blob: cd938e57718dc08d505201faea94ab041cf59283 [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;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000745#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000746 if (ia32) {
747 switch (new) {
748 case 2: break; /* x86 SYS_fork */
749 case SYS_clone: new = 120; break;
750 default:
751 fprintf(stderr, "%s: unexpected syscall %d\n",
752 __FUNCTION__, new);
753 return -1;
754 }
755 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
756 return -1;
757 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000758 return -1;
759 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000760#elif defined(HPPA)
761 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
762 return -1;
763 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000764#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000765 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000766 return -1;
767 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000768#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000769 /* Top half of reg encodes the no. of args n as 0x1n.
770 Assume 0 args as kernel never actually checks... */
771 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
772 0x100000 | new) < 0)
773 return -1;
774 return 0;
Roland McGrathf691bd22006-04-25 07:34:41 +0000775#elif defined(ARM)
776 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
777# ifndef PTRACE_SET_SYSCALL
778# define PTRACE_SET_SYSCALL 23
779# endif
780
781 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
782 return -1;
783
784 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000785#else
786#warning Do not know how to handle change_syscall for this architecture
787#endif /* architecture */
788#endif /* LINUX */
789 return -1;
790}
791
Roland McGratha4d48532005-06-08 20:45:28 +0000792#if 0
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000793int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000794setarg(tcp, argnum)
795 struct tcb *tcp;
796 int argnum;
797{
798#if defined (IA64)
799 {
800 unsigned long *bsp, *ap;
801
802 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
803 return -1;
804
805 ap = ia64_rse_skip_regs(bsp, argnum);
806 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000807 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000808 if (errno)
809 return -1;
810
811 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000812#elif defined(I386)
813 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000814 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000815 if (errno)
816 return -1;
817 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000818#elif defined(X86_64)
819 {
820 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
821 if (errno)
822 return -1;
823 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000824#elif defined(POWERPC)
825#ifndef PT_ORIG_R3
826#define PT_ORIG_R3 34
827#endif
828 {
829 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000830 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000831 tcp->u_arg[argnum]);
832 if (errno)
833 return -1;
834 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000835#elif defined(MIPS)
836 {
837 errno = 0;
838 if (argnum < 4)
839 ptrace(PTRACE_POKEUSER, tcp->pid,
840 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
841 else {
842 unsigned long *sp;
843
844 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
845 return -1;
846
847 ptrace(PTRACE_POKEDATA, tcp->pid,
848 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
849 }
850 if (errno)
851 return -1;
852 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000853#elif defined(S390) || defined(S390X)
854 {
855 if(argnum <= 5)
856 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000857 (char *) (argnum==0 ? PT_ORIGGPR2 :
858 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000859 tcp->u_arg[argnum]);
860 else
861 return -E2BIG;
862 if (errno)
863 return -1;
864 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000865#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000866# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000867#endif
868 return 0;
869}
Roland McGratha4d48532005-06-08 20:45:28 +0000870#endif
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000871
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000872#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000873int
874internal_clone(tcp)
875struct tcb *tcp;
876{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000877 struct tcb *tcpchild;
878 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000879 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000880 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000881 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000882 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000883 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000884 if (setbpt(tcp) < 0)
885 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000886 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000887 int bpt = tcp->flags & TCB_BPTSET;
888
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000889 if (!(tcp->flags & TCB_FOLLOWFORK))
890 return 0;
891
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000892 if (syserror(tcp)) {
893 if (bpt)
894 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000895 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000896 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000897
898 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000899
900#ifdef CLONE_PTRACE /* See new setbpt code. */
901 tcpchild = pid2tcb(pid);
902 if (tcpchild != NULL) {
903 /* The child already reported its startup trap
904 before the parent reported its syscall return. */
905 if ((tcpchild->flags
906 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
907 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
908 fprintf(stderr, "\
909[preattached child %d of %d in weird state!]\n",
910 pid, tcp->pid);
911 }
912 else
913#endif
Dmitry V. Levin76860f62006-10-11 22:55:25 +0000914 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000915 if (bpt)
916 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000917 kill(pid, SIGKILL); /* XXX */
918 return 0;
919 }
920
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000921#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000922 /* Attach to the new child */
923 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000924 if (bpt)
925 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000926 perror("PTRACE_ATTACH");
927 fprintf(stderr, "Too late?\n");
928 droptcb(tcpchild);
929 return 0;
930 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000931#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000932
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000933 if (bpt)
934 clearbpt(tcp);
935
Ulrich Drepper90512f01999-12-24 07:22:25 +0000936 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000937 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000938 if (bpt) {
939 tcpchild->flags |= TCB_BPTSET;
940 tcpchild->baddr = tcp->baddr;
941 memcpy(tcpchild->inst, tcp->inst,
942 sizeof tcpchild->inst);
943 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000944 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000945 tcp->nchildren++;
946 if (tcpchild->flags & TCB_SUSPENDED) {
947 /* The child was born suspended, due to our having
948 forced CLONE_PTRACE. */
949 if (bpt)
950 clearbpt(tcpchild);
951
952 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
953 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
954 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
955 return -1;
956 }
957
958 if (!qflag)
959 fprintf(stderr, "\
960Process %u resumed (parent %d ready)\n",
961 pid, tcp->pid);
962 }
963 else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000964 if (!qflag)
965 fprintf(stderr, "Process %d attached\n", pid);
966 }
967
968#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000969 {
970 /*
971 * Save the flags used in this call,
972 * in case we point TCP to our parent below.
973 */
974 int call_flags = tcp->u_arg[ARG_FLAGS];
975 if ((tcp->flags & TCB_CLONE_THREAD) &&
976 tcp->parent != NULL) {
977 /* The parent in this clone is itself a
978 thread belonging to another process.
979 There is no meaning to the parentage
980 relationship of the new child with the
981 thread, only with the process. We
982 associate the new thread with our
983 parent. Since this is done for every
984 new thread, there will never be a
985 TCB_CLONE_THREAD process that has
986 children. */
987 --tcp->nchildren;
988 tcp = tcp->parent;
989 tcpchild->parent = tcp;
990 ++tcp->nchildren;
991 }
992 if (call_flags & CLONE_THREAD) {
993 tcpchild->flags |= TCB_CLONE_THREAD;
994 ++tcp->nclone_threads;
995 }
996 if (call_flags & CLONE_DETACHED) {
997 tcpchild->flags |= TCB_CLONE_DETACHED;
998 ++tcp->nclone_detached;
999 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001000 }
1001#endif
1002
1003 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001004 return 0;
1005}
1006#endif
1007
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001008int
1009internal_fork(tcp)
1010struct tcb *tcp;
1011{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001012#ifdef LINUX
1013 /* We do special magic with clone for any clone or fork. */
1014 return internal_clone(tcp);
1015#else
1016
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001017 struct tcb *tcpchild;
1018 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001019 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001020
1021#ifdef SYS_vfork
Roland McGratha4f9f2d2005-06-07 23:21:20 +00001022 if (known_scno(tcp) == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001023 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath41c48222008-07-18 00:25:10 +00001024 if (change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +00001025 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +00001026 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001027#endif
1028 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +00001029 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001030 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +00001031 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001032 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001033 if (setbpt(tcp) < 0)
1034 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +00001035 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001036 else {
1037 int bpt = tcp->flags & TCB_BPTSET;
1038
1039 if (!(tcp->flags & TCB_FOLLOWFORK))
1040 return 0;
1041 if (bpt)
1042 clearbpt(tcp);
1043
1044 if (syserror(tcp))
1045 return 0;
1046
1047 pid = tcp->u_rval;
Dmitry V. Levin76860f62006-10-11 22:55:25 +00001048 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001049 kill(pid, SIGKILL); /* XXX */
1050 return 0;
1051 }
1052#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001053#ifdef HPPA
1054 /* The child must have run before it can be attached. */
1055 /* This must be a bug in the parisc kernel, but I havn't
1056 * identified it yet. Seems to be an issue associated
1057 * with attaching to a process (which sends it a signal)
1058 * before that process has ever been scheduled. When
1059 * debugging, I started seeing crashes in
1060 * arch/parisc/kernel/signal.c:do_signal(), apparently
1061 * caused by r8 getting corrupt over the dequeue_signal()
1062 * call. Didn't make much sense though...
1063 */
1064 {
1065 struct timeval tv;
1066 tv.tv_sec = 0;
1067 tv.tv_usec = 10000;
1068 select(0, NULL, NULL, NULL, &tv);
1069 }
1070#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001071 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1072 perror("PTRACE_ATTACH");
1073 fprintf(stderr, "Too late?\n");
1074 droptcb(tcpchild);
1075 return 0;
1076 }
1077#endif /* LINUX */
1078#ifdef SUNOS4
1079#ifdef oldway
1080 /* The child must have run before it can be attached. */
1081 {
1082 struct timeval tv;
1083 tv.tv_sec = 0;
1084 tv.tv_usec = 10000;
1085 select(0, NULL, NULL, NULL, &tv);
1086 }
1087 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1088 perror("PTRACE_ATTACH");
1089 fprintf(stderr, "Too late?\n");
1090 droptcb(tcpchild);
1091 return 0;
1092 }
1093#else /* !oldway */
1094 /* Try to catch the new process as soon as possible. */
1095 {
1096 int i;
1097 for (i = 0; i < 1024; i++)
1098 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1099 break;
1100 if (i == 1024) {
1101 perror("PTRACE_ATTACH");
1102 fprintf(stderr, "Too late?\n");
1103 droptcb(tcpchild);
1104 return 0;
1105 }
1106 }
1107#endif /* !oldway */
1108#endif /* SUNOS4 */
1109 tcpchild->flags |= TCB_ATTACHED;
1110 /* Child has BPT too, must be removed on first occasion */
1111 if (bpt) {
1112 tcpchild->flags |= TCB_BPTSET;
1113 tcpchild->baddr = tcp->baddr;
1114 memcpy(tcpchild->inst, tcp->inst,
1115 sizeof tcpchild->inst);
1116 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001117 tcpchild->parent = tcp;
1118 tcp->nchildren++;
1119 if (!qflag)
1120 fprintf(stderr, "Process %d attached\n", pid);
1121 }
1122 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001123#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001124}
1125
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001126#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001127
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001128#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001129
1130int
1131sys_vfork(tcp)
1132struct tcb *tcp;
1133{
1134 if (exiting(tcp))
1135 return RVAL_UDECIMAL;
1136 return 0;
1137}
1138
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001139#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001140
1141#ifndef LINUX
1142
1143static char idstr[16];
1144
1145int
1146sys_getpid(tcp)
1147struct tcb *tcp;
1148{
1149 if (exiting(tcp)) {
1150 sprintf(idstr, "ppid %lu", getrval2(tcp));
1151 tcp->auxstr = idstr;
1152 return RVAL_STR;
1153 }
1154 return 0;
1155}
1156
1157int
1158sys_getuid(tcp)
1159struct tcb *tcp;
1160{
1161 if (exiting(tcp)) {
1162 sprintf(idstr, "euid %lu", getrval2(tcp));
1163 tcp->auxstr = idstr;
1164 return RVAL_STR;
1165 }
1166 return 0;
1167}
1168
1169int
1170sys_getgid(tcp)
1171struct tcb *tcp;
1172{
1173 if (exiting(tcp)) {
1174 sprintf(idstr, "egid %lu", getrval2(tcp));
1175 tcp->auxstr = idstr;
1176 return RVAL_STR;
1177 }
1178 return 0;
1179}
1180
1181#endif /* !LINUX */
1182
1183#ifdef LINUX
1184
1185int
1186sys_setuid(tcp)
1187struct tcb *tcp;
1188{
1189 if (entering(tcp)) {
1190 tprintf("%u", (uid_t) tcp->u_arg[0]);
1191 }
1192 return 0;
1193}
1194
1195int
1196sys_setgid(tcp)
1197struct tcb *tcp;
1198{
1199 if (entering(tcp)) {
1200 tprintf("%u", (gid_t) tcp->u_arg[0]);
1201 }
1202 return 0;
1203}
1204
1205int
1206sys_getresuid(tcp)
1207 struct tcb *tcp;
1208{
1209 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001210 __kernel_uid_t uid;
1211 if (syserror(tcp))
1212 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1213 tcp->u_arg[1], tcp->u_arg[2]);
1214 else {
1215 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1216 tprintf("%#lx, ", tcp->u_arg[0]);
1217 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001218 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001219 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1220 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001221 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[2], &uid) < 0)
1224 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001225 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001226 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001227 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001228 }
1229 return 0;
1230}
1231
1232int
1233sys_getresgid(tcp)
1234struct tcb *tcp;
1235{
1236 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001237 __kernel_gid_t gid;
1238 if (syserror(tcp))
1239 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1240 tcp->u_arg[1], tcp->u_arg[2]);
1241 else {
1242 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1243 tprintf("%#lx, ", tcp->u_arg[0]);
1244 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001245 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001246 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1247 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001248 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[2], &gid) < 0)
1251 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001252 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001253 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001254 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001255 }
1256 return 0;
1257}
1258
1259#endif /* LINUX */
1260
1261int
1262sys_setreuid(tcp)
1263struct tcb *tcp;
1264{
1265 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001266 printuid("", tcp->u_arg[0]);
1267 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001268 }
1269 return 0;
1270}
1271
1272int
1273sys_setregid(tcp)
1274struct tcb *tcp;
1275{
1276 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001277 printuid("", tcp->u_arg[0]);
1278 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001279 }
1280 return 0;
1281}
1282
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001283#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001284int
1285sys_setresuid(tcp)
1286 struct tcb *tcp;
1287{
1288 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001289 printuid("", tcp->u_arg[0]);
1290 printuid(", ", tcp->u_arg[1]);
1291 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001292 }
1293 return 0;
1294}
1295int
1296sys_setresgid(tcp)
1297 struct tcb *tcp;
1298{
1299 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001300 printuid("", tcp->u_arg[0]);
1301 printuid(", ", tcp->u_arg[1]);
1302 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001303 }
1304 return 0;
1305}
1306
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001307#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001308
1309int
1310sys_setgroups(tcp)
1311struct tcb *tcp;
1312{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001313 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001314 unsigned long len, size, start, cur, end, abbrev_end;
1315 GETGROUPS_T gid;
1316 int failed = 0;
1317
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001318 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001319 tprintf("%lu, ", len);
1320 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001321 tprintf("[]");
1322 return 0;
1323 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001324 start = tcp->u_arg[1];
1325 if (start == 0) {
1326 tprintf("NULL");
1327 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001328 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001329 size = len * sizeof(gid);
1330 end = start + size;
1331 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1332 tprintf("%#lx", start);
1333 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001334 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001335 if (abbrev(tcp)) {
1336 abbrev_end = start + max_strlen * sizeof(gid);
1337 if (abbrev_end < start)
1338 abbrev_end = end;
1339 } else {
1340 abbrev_end = end;
1341 }
1342 tprintf("[");
1343 for (cur = start; cur < end; cur += sizeof(gid)) {
1344 if (cur > start)
1345 tprintf(", ");
1346 if (cur >= abbrev_end) {
1347 tprintf("...");
1348 break;
1349 }
1350 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1351 tprintf("?");
1352 failed = 1;
1353 break;
1354 }
1355 tprintf("%lu", (unsigned long) gid);
1356 }
1357 tprintf("]");
1358 if (failed)
1359 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001360 }
1361 return 0;
1362}
1363
1364int
1365sys_getgroups(tcp)
1366struct tcb *tcp;
1367{
Roland McGrathaa524c82005-06-01 19:22:06 +00001368 unsigned long len;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001369
1370 if (entering(tcp)) {
1371 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001372 tprintf("%lu, ", len);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001373 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001374 unsigned long size, start, cur, end, abbrev_end;
1375 GETGROUPS_T gid;
1376 int failed = 0;
1377
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001378 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001379 if (len == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001380 tprintf("[]");
1381 return 0;
1382 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001383 start = tcp->u_arg[1];
1384 if (start == 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001385 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001386 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001387 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001388 if (tcp->u_arg[0] == 0) {
1389 tprintf("%#lx", start);
1390 return 0;
1391 }
1392 size = len * sizeof(gid);
1393 end = start + size;
1394 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1395 size / sizeof(gid) != len || end < start) {
1396 tprintf("%#lx", start);
1397 return 0;
1398 }
1399 if (abbrev(tcp)) {
1400 abbrev_end = start + max_strlen * sizeof(gid);
1401 if (abbrev_end < start)
1402 abbrev_end = end;
1403 } else {
1404 abbrev_end = end;
1405 }
1406 tprintf("[");
1407 for (cur = start; cur < end; cur += sizeof(gid)) {
1408 if (cur > start)
1409 tprintf(", ");
1410 if (cur >= abbrev_end) {
1411 tprintf("...");
1412 break;
1413 }
1414 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1415 tprintf("?");
1416 failed = 1;
1417 break;
1418 }
1419 tprintf("%lu", (unsigned long) gid);
1420 }
1421 tprintf("]");
1422 if (failed)
1423 tprintf(" %#lx", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001424 }
1425 return 0;
1426}
1427
Roland McGrath83bd47a2003-11-13 22:32:26 +00001428#ifdef LINUX
1429int
1430sys_setgroups32(tcp)
1431struct tcb *tcp;
1432{
Roland McGrath83bd47a2003-11-13 22:32:26 +00001433 if (entering(tcp)) {
Roland McGrathaa524c82005-06-01 19:22:06 +00001434 unsigned long len, size, start, cur, end, abbrev_end;
1435 GETGROUPS32_T gid;
1436 int failed = 0;
1437
Roland McGrath83bd47a2003-11-13 22:32:26 +00001438 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001439 tprintf("%lu, ", len);
1440 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001441 tprintf("[]");
1442 return 0;
1443 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001444 start = tcp->u_arg[1];
1445 if (start == 0) {
1446 tprintf("NULL");
1447 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001448 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001449 size = len * sizeof(gid);
1450 end = start + size;
1451 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1452 tprintf("%#lx", start);
1453 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001454 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001455 if (abbrev(tcp)) {
1456 abbrev_end = start + max_strlen * sizeof(gid);
1457 if (abbrev_end < start)
1458 abbrev_end = end;
1459 } else {
1460 abbrev_end = end;
1461 }
1462 tprintf("[");
1463 for (cur = start; cur < end; cur += sizeof(gid)) {
1464 if (cur > start)
1465 tprintf(", ");
1466 if (cur >= abbrev_end) {
1467 tprintf("...");
1468 break;
1469 }
1470 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1471 tprintf("?");
1472 failed = 1;
1473 break;
1474 }
1475 tprintf("%lu", (unsigned long) gid);
1476 }
1477 tprintf("]");
1478 if (failed)
1479 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001480 }
1481 return 0;
1482}
1483
1484int
1485sys_getgroups32(tcp)
1486struct tcb *tcp;
1487{
Roland McGrathaa524c82005-06-01 19:22:06 +00001488 unsigned long len;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001489
1490 if (entering(tcp)) {
1491 len = tcp->u_arg[0];
Roland McGrathaa524c82005-06-01 19:22:06 +00001492 tprintf("%lu, ", len);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001493 } else {
Roland McGrathaa524c82005-06-01 19:22:06 +00001494 unsigned long size, start, cur, end, abbrev_end;
1495 GETGROUPS32_T gid;
1496 int failed = 0;
1497
Roland McGrath83bd47a2003-11-13 22:32:26 +00001498 len = tcp->u_rval;
Roland McGrathaa524c82005-06-01 19:22:06 +00001499 if (len == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001500 tprintf("[]");
1501 return 0;
1502 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001503 start = tcp->u_arg[1];
1504 if (start == 0) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001505 tprintf("NULL");
Roland McGrathaa524c82005-06-01 19:22:06 +00001506 return 0;
Roland McGrath83bd47a2003-11-13 22:32:26 +00001507 }
Roland McGrathaa524c82005-06-01 19:22:06 +00001508 size = len * sizeof(gid);
1509 end = start + size;
1510 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1511 size / sizeof(gid) != len || end < start) {
1512 tprintf("%#lx", start);
1513 return 0;
1514 }
1515 if (abbrev(tcp)) {
1516 abbrev_end = start + max_strlen * sizeof(gid);
1517 if (abbrev_end < start)
1518 abbrev_end = end;
1519 } else {
1520 abbrev_end = end;
1521 }
1522 tprintf("[");
1523 for (cur = start; cur < end; cur += sizeof(gid)) {
1524 if (cur > start)
1525 tprintf(", ");
1526 if (cur >= abbrev_end) {
1527 tprintf("...");
1528 break;
1529 }
1530 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1531 tprintf("?");
1532 failed = 1;
1533 break;
1534 }
1535 tprintf("%lu", (unsigned long) gid);
1536 }
1537 tprintf("]");
1538 if (failed)
1539 tprintf(" %#lx", tcp->u_arg[1]);
Roland McGrath83bd47a2003-11-13 22:32:26 +00001540 }
1541 return 0;
1542}
1543#endif /* LINUX */
1544
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001545#if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001546int
1547sys_setpgrp(tcp)
1548struct tcb *tcp;
1549{
1550 if (entering(tcp)) {
1551#ifndef SVR4
1552 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1553#endif /* !SVR4 */
1554 }
1555 return 0;
1556}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001557#endif /* ALPHA || SUNOS4 || SVR4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001558
1559int
1560sys_getpgrp(tcp)
1561struct tcb *tcp;
1562{
1563 if (entering(tcp)) {
1564#ifndef SVR4
1565 tprintf("%lu", tcp->u_arg[0]);
1566#endif /* !SVR4 */
1567 }
1568 return 0;
1569}
1570
1571int
1572sys_getsid(tcp)
1573struct tcb *tcp;
1574{
1575 if (entering(tcp)) {
1576 tprintf("%lu", tcp->u_arg[0]);
1577 }
1578 return 0;
1579}
1580
1581int
1582sys_setsid(tcp)
1583struct tcb *tcp;
1584{
1585 return 0;
1586}
1587
1588int
1589sys_getpgid(tcp)
1590struct tcb *tcp;
1591{
1592 if (entering(tcp)) {
1593 tprintf("%lu", tcp->u_arg[0]);
1594 }
1595 return 0;
1596}
1597
1598int
1599sys_setpgid(tcp)
1600struct tcb *tcp;
1601{
1602 if (entering(tcp)) {
1603 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1604 }
1605 return 0;
1606}
1607
John Hughesc61eb3d2002-05-17 11:37:50 +00001608#if UNIXWARE >= 2
1609
1610#include <sys/privilege.h>
1611
1612
Roland McGrathd9f816f2004-09-04 03:39:20 +00001613static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001614 { SETPRV, "SETPRV" },
1615 { CLRPRV, "CLRPRV" },
1616 { PUTPRV, "PUTPRV" },
1617 { GETPRV, "GETPRV" },
1618 { CNTPRV, "CNTPRV" },
1619 { 0, NULL },
1620};
1621
1622
Roland McGrathd9f816f2004-09-04 03:39:20 +00001623static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001624 { P_OWNER, "P_OWNER" },
1625 { P_AUDIT, "P_AUDIT" },
1626 { P_COMPAT, "P_COMPAT" },
1627 { P_DACREAD, "P_DACREAD" },
1628 { P_DACWRITE, "P_DACWRITE" },
1629 { P_DEV, "P_DEV" },
1630 { P_FILESYS, "P_FILESYS" },
1631 { P_MACREAD, "P_MACREAD" },
1632 { P_MACWRITE, "P_MACWRITE" },
1633 { P_MOUNT, "P_MOUNT" },
1634 { P_MULTIDIR, "P_MULTIDIR" },
1635 { P_SETPLEVEL, "P_SETPLEVEL" },
1636 { P_SETSPRIV, "P_SETSPRIV" },
1637 { P_SETUID, "P_SETUID" },
1638 { P_SYSOPS, "P_SYSOPS" },
1639 { P_SETUPRIV, "P_SETUPRIV" },
1640 { P_DRIVER, "P_DRIVER" },
1641 { P_RTIME, "P_RTIME" },
1642 { P_MACUPGRADE, "P_MACUPGRADE" },
1643 { P_FSYSRANGE, "P_FSYSRANGE" },
1644 { P_SETFLEVEL, "P_SETFLEVEL" },
1645 { P_AUDITWR, "P_AUDITWR" },
1646 { P_TSHAR, "P_TSHAR" },
1647 { P_PLOCK, "P_PLOCK" },
1648 { P_CORE, "P_CORE" },
1649 { P_LOADMOD, "P_LOADMOD" },
1650 { P_BIND, "P_BIND" },
1651 { P_ALLPRIVS, "P_ALLPRIVS" },
1652 { 0, NULL },
1653};
1654
1655
Roland McGrathd9f816f2004-09-04 03:39:20 +00001656static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001657 { PS_FIX, "PS_FIX" },
1658 { PS_INH, "PS_INH" },
1659 { PS_MAX, "PS_MAX" },
1660 { PS_WKG, "PS_WKG" },
1661 { 0, NULL },
1662};
1663
1664
1665static void
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001666printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
John Hughesc61eb3d2002-05-17 11:37:50 +00001667{
1668 priv_t buf [128];
1669 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1670 int dots = len > max;
1671 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001672
John Hughesc61eb3d2002-05-17 11:37:50 +00001673 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001674
John Hughesc61eb3d2002-05-17 11:37:50 +00001675 if (len <= 0 ||
1676 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1677 {
1678 tprintf ("%#lx", addr);
1679 return;
1680 }
1681
1682 tprintf ("[");
1683
1684 for (i = 0; i < len; ++i) {
Dmitry V. Levinab9008b2007-01-11 22:05:04 +00001685 const char *t, *p;
John Hughesc61eb3d2002-05-17 11:37:50 +00001686
1687 if (i) tprintf (", ");
1688
1689 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1690 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1691 {
1692 tprintf ("%s|%s", t, p);
1693 }
1694 else {
1695 tprintf ("%#lx", buf [i]);
1696 }
1697 }
1698
1699 if (dots) tprintf (" ...");
1700
1701 tprintf ("]");
1702}
1703
1704
1705int
1706sys_procpriv(tcp)
1707struct tcb *tcp;
1708{
1709 if (entering(tcp)) {
1710 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1711 switch (tcp->u_arg[0]) {
1712 case CNTPRV:
1713 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1714 break;
1715
1716 case GETPRV:
1717 break;
1718
1719 default:
1720 tprintf (", ");
1721 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1722 tprintf (", %ld", tcp->u_arg[2]);
1723 }
1724 }
1725 else if (tcp->u_arg[0] == GETPRV) {
1726 if (syserror (tcp)) {
1727 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1728 }
1729 else {
1730 tprintf (", ");
1731 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1732 tprintf (", %ld", tcp->u_arg[2]);
1733 }
1734 }
Roland McGrath5a223472002-12-15 23:58:26 +00001735
John Hughesc61eb3d2002-05-17 11:37:50 +00001736 return 0;
1737}
1738
1739#endif
1740
1741
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001742static void
1743printargv(tcp, addr)
1744struct tcb *tcp;
1745long addr;
1746{
Roland McGrath85a3bc42007-08-02 02:13:05 +00001747 union {
1748 int p32;
1749 long p64;
1750 char data[sizeof(long)];
1751 } cp;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001752 char *sep;
Roland McGrath85a3bc42007-08-02 02:13:05 +00001753 int n = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001754
Roland McGrath85a3bc42007-08-02 02:13:05 +00001755 cp.p64 = 1;
1756 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1757 if (umoven(tcp, addr, personality_wordsize[current_personality],
1758 cp.data) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001759 tprintf("%#lx", addr);
1760 return;
1761 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001762 if (personality_wordsize[current_personality] == 4)
1763 cp.p64 = cp.p32;
1764 if (cp.p64 == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001765 break;
1766 tprintf(sep);
Roland McGrath85a3bc42007-08-02 02:13:05 +00001767 printstr(tcp, cp.p64, -1);
1768 addr += personality_wordsize[current_personality];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001769 }
Roland McGrath85a3bc42007-08-02 02:13:05 +00001770 if (cp.p64)
1771 tprintf("%s...", sep);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772}
1773
1774static void
1775printargc(fmt, tcp, addr)
1776char *fmt;
1777struct tcb *tcp;
1778long addr;
1779{
1780 int count;
1781 char *cp;
1782
1783 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1784 addr += sizeof(char *);
1785 }
1786 tprintf(fmt, count, count == 1 ? "" : "s");
1787}
1788
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001789#if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001790int
1791sys_execv(tcp)
1792struct tcb *tcp;
1793{
1794 if (entering(tcp)) {
1795 printpath(tcp, tcp->u_arg[0]);
1796 if (!verbose(tcp))
1797 tprintf(", %#lx", tcp->u_arg[1]);
1798#if 0
1799 else if (abbrev(tcp))
1800 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1801#endif
1802 else {
1803 tprintf(", [");
1804 printargv(tcp, tcp->u_arg[1]);
1805 tprintf("]");
1806 }
1807 }
1808 return 0;
1809}
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +00001810#endif /* SPARC || SPARC64 || SUNOS4 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001811
1812int
1813sys_execve(tcp)
1814struct tcb *tcp;
1815{
1816 if (entering(tcp)) {
1817 printpath(tcp, tcp->u_arg[0]);
1818 if (!verbose(tcp))
1819 tprintf(", %#lx", tcp->u_arg[1]);
1820#if 0
1821 else if (abbrev(tcp))
1822 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1823#endif
1824 else {
1825 tprintf(", [");
1826 printargv(tcp, tcp->u_arg[1]);
1827 tprintf("]");
1828 }
1829 if (!verbose(tcp))
1830 tprintf(", %#lx", tcp->u_arg[2]);
1831 else if (abbrev(tcp))
1832 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1833 else {
1834 tprintf(", [");
1835 printargv(tcp, tcp->u_arg[2]);
1836 tprintf("]");
1837 }
1838 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001839 return 0;
1840}
1841
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001842#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001843
1844int sys_rexecve(tcp)
1845struct tcb *tcp;
1846{
1847 if (entering (tcp)) {
1848 sys_execve (tcp);
1849 tprintf (", %ld", tcp->u_arg[3]);
1850 }
1851 return 0;
1852}
1853
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001854#endif
John Hughes4e36a812001-04-18 15:11:51 +00001855
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001856int
1857internal_exec(tcp)
1858struct tcb *tcp;
1859{
1860#ifdef SUNOS4
1861 if (exiting(tcp) && !syserror(tcp) && followfork)
1862 fixvfork(tcp);
1863#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001864#if defined LINUX && defined TCB_WAITEXECVE
1865 if (exiting(tcp) && syserror(tcp))
1866 tcp->flags &= ~TCB_WAITEXECVE;
1867 else
1868 tcp->flags |= TCB_WAITEXECVE;
1869#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001870 return 0;
1871}
1872
1873#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001874#ifndef __WNOTHREAD
1875#define __WNOTHREAD 0x20000000
1876#endif
1877#ifndef __WALL
1878#define __WALL 0x40000000
1879#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001880#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001881#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001882#endif
1883#endif /* LINUX */
1884
Roland McGrathd9f816f2004-09-04 03:39:20 +00001885static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001886 { WNOHANG, "WNOHANG" },
1887#ifndef WSTOPPED
1888 { WUNTRACED, "WUNTRACED" },
1889#endif
1890#ifdef WEXITED
1891 { WEXITED, "WEXITED" },
1892#endif
1893#ifdef WTRAPPED
1894 { WTRAPPED, "WTRAPPED" },
1895#endif
1896#ifdef WSTOPPED
1897 { WSTOPPED, "WSTOPPED" },
1898#endif
1899#ifdef WCONTINUED
1900 { WCONTINUED, "WCONTINUED" },
1901#endif
1902#ifdef WNOWAIT
1903 { WNOWAIT, "WNOWAIT" },
1904#endif
1905#ifdef __WCLONE
1906 { __WCLONE, "__WCLONE" },
1907#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001908#ifdef __WALL
1909 { __WALL, "__WALL" },
1910#endif
1911#ifdef __WNOTHREAD
1912 { __WNOTHREAD, "__WNOTHREAD" },
1913#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001914 { 0, NULL },
1915};
1916
Roland McGrath5e02a572004-10-19 23:33:47 +00001917#if !defined WCOREFLAG && defined WCOREFLG
1918# define WCOREFLAG WCOREFLG
1919#endif
1920#ifndef WCOREFLAG
1921#define WCOREFLAG 0x80
1922#endif
1923
1924#ifndef W_STOPCODE
1925#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1926#endif
1927#ifndef W_EXITCODE
1928#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1929#endif
1930
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001931static int
1932printstatus(status)
1933int status;
1934{
1935 int exited = 0;
1936
1937 /*
1938 * Here is a tricky presentation problem. This solution
1939 * is still not entirely satisfactory but since there
1940 * are no wait status constructors it will have to do.
1941 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001942 if (WIFSTOPPED(status)) {
1943 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001944 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001945 status &= ~W_STOPCODE(WSTOPSIG(status));
1946 }
1947 else if (WIFSIGNALED(status)) {
1948 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001949 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001950 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001951 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1952 }
1953 else if (WIFEXITED(status)) {
1954 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001955 WEXITSTATUS(status));
1956 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001957 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001958 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001959 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001960 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001961 return 0;
1962 }
1963
1964 if (status == 0)
1965 tprintf("]");
1966 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001967 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001968
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001969 return exited;
1970}
1971
1972static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001973printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001974struct tcb *tcp;
1975int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001976int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001977{
1978 int status;
1979 int exited = 0;
1980
1981 if (entering(tcp)) {
Roland McGrath5b63d962008-07-18 02:16:47 +00001982 /*
1983 * Sign-extend a 32-bit value when that's what it is.
1984 */
1985 long pid = tcp->u_arg[0];
1986 if (personality_wordsize[current_personality] < sizeof pid)
1987 pid = (long) (int) pid;
1988 tprintf("%ld, ", pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001989 } else {
1990 /* status */
1991 if (!tcp->u_arg[1])
1992 tprintf("NULL");
1993 else if (syserror(tcp) || tcp->u_rval == 0)
1994 tprintf("%#lx", tcp->u_arg[1]);
1995 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1996 tprintf("[?]");
1997 else
1998 exited = printstatus(status);
1999 /* options */
2000 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002001 printflags(wait4_options, tcp->u_arg[2], "W???");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 if (n == 4) {
2003 tprintf(", ");
2004 /* usage */
2005 if (!tcp->u_arg[3])
2006 tprintf("NULL");
2007#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002008 else if (tcp->u_rval > 0) {
2009#ifdef LINUX_64BIT
2010 if (bitness)
2011 printrusage32(tcp, tcp->u_arg[3]);
2012 else
2013#endif
2014 printrusage(tcp, tcp->u_arg[3]);
2015 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002016#endif /* LINUX */
2017#ifdef SUNOS4
2018 else if (tcp->u_rval > 0 && exited)
2019 printrusage(tcp, tcp->u_arg[3]);
2020#endif /* SUNOS4 */
2021 else
2022 tprintf("%#lx", tcp->u_arg[3]);
2023 }
2024 }
2025 return 0;
2026}
2027
2028int
Roland McGrathc74c0b72004-09-01 19:39:46 +00002029internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002030struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00002031int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002032{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002033 int got_kids;
2034
2035#ifdef TCB_CLONE_THREAD
2036 if (tcp->flags & TCB_CLONE_THREAD)
2037 /* The children we wait for are our parent's children. */
2038 got_kids = (tcp->parent->nchildren
2039 > tcp->parent->nclone_detached);
2040 else
2041 got_kids = (tcp->nchildren > tcp->nclone_detached);
2042#else
2043 got_kids = tcp->nchildren > 0;
2044#endif
2045
2046 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002047 /* There are children that this parent should block for.
2048 But ptrace made us the parent of the traced children
2049 and the real parent will get ECHILD from the wait call.
2050
2051 XXX If we attached with strace -f -p PID, then there
2052 may be untraced dead children the parent could be reaping
2053 now, but we make him block. */
2054
2055 /* ??? WTA: fix bug with hanging children */
2056
Roland McGrathc74c0b72004-09-01 19:39:46 +00002057 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00002058 /*
2059 * There are traced children. We'll make the parent
2060 * block to avoid a false ECHILD error due to our
2061 * ptrace having stolen the children. However,
2062 * we shouldn't block if there are zombies to reap.
2063 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2064 */
Roland McGrathfccfb942003-10-01 21:59:44 +00002065 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00002066 if (tcp->nzombies > 0 &&
2067 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00002068 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00002069 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00002070 if (tcp->u_arg[0] > 0) {
2071 /*
2072 * If the parent waits for a specified child
2073 * PID, then it must get ECHILD right away
2074 * if that PID is not one of its children.
2075 * Make sure that the requested PID matches
2076 * one of the parent's children that we are
2077 * tracing, and don't suspend it otherwise.
2078 */
2079 if (child == NULL)
2080 child = pid2tcb(tcp->u_arg[0]);
2081 if (child == NULL || child->parent != (
2082#ifdef TCB_CLONE_THREAD
2083 (tcp->flags & TCB_CLONE_THREAD)
2084 ? tcp->parent :
2085#endif
Roland McGrathd56a6562005-08-03 11:23:43 +00002086 tcp) ||
2087 (child->flags & TCB_EXITING))
Roland McGrathfccfb942003-10-01 21:59:44 +00002088 return 0;
2089 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002090 tcp->flags |= TCB_SUSPENDED;
2091 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002092#ifdef TCB_CLONE_THREAD
2093 if (tcp->flags & TCB_CLONE_THREAD)
2094 tcp->parent->nclone_waiting++;
2095#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002096 }
2097 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00002098 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00002099 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00002100 /* We must force a fake result of 0 instead of
2101 the ECHILD error. */
2102 extern int force_result();
2103 return force_result(tcp, 0, 0);
2104 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00002105 }
Roland McGrath09623452003-05-23 02:27:13 +00002106 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2107 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2108 /*
2109 * We just reaped a child we don't know about,
2110 * presumably a zombie we already droptcb'd.
2111 */
2112 tcp->nzombies--;
2113 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002114 return 0;
2115}
2116
2117#ifdef SVR4
2118
2119int
2120sys_wait(tcp)
2121struct tcb *tcp;
2122{
2123 if (exiting(tcp)) {
2124 /* The library wrapper stuffs this into the user variable. */
2125 if (!syserror(tcp))
2126 printstatus(getrval2(tcp));
2127 }
2128 return 0;
2129}
2130
2131#endif /* SVR4 */
2132
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002133#ifdef FREEBSD
2134int
2135sys_wait(tcp)
2136struct tcb *tcp;
2137{
2138 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00002139
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002140 if (exiting(tcp)) {
2141 if (!syserror(tcp)) {
2142 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2143 tprintf("%#lx", tcp->u_arg[0]);
2144 else
2145 printstatus(status);
2146 }
2147 }
2148 return 0;
2149}
2150#endif
2151
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002152int
2153sys_waitpid(tcp)
2154struct tcb *tcp;
2155{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002156 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002157}
2158
2159int
2160sys_wait4(tcp)
2161struct tcb *tcp;
2162{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002163 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002164}
2165
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002166#ifdef ALPHA
2167int
2168sys_osf_wait4(tcp)
2169struct tcb *tcp;
2170{
2171 return printwaitn(tcp, 4, 1);
2172}
2173#endif
2174
Roland McGrathc74c0b72004-09-01 19:39:46 +00002175#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002176
Roland McGrathd9f816f2004-09-04 03:39:20 +00002177static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002178 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002179#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002180 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002181#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002182 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002183#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002184 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002185#endif
2186#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002187 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002188#endif
2189#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002190 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002191#endif
2192#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002193 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002194#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002195 { P_ALL, "P_ALL" },
2196#ifdef P_LWPID
2197 { P_LWPID, "P_LWPID" },
2198#endif
2199 { 0, NULL },
2200};
2201
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002202int
2203sys_waitid(tcp)
2204struct tcb *tcp;
2205{
2206 siginfo_t si;
2207 int exited;
2208
2209 if (entering(tcp)) {
2210 printxval(waitid_types, tcp->u_arg[0], "P_???");
2211 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002212 }
2213 else {
2214 /* siginfo */
2215 exited = 0;
2216 if (!tcp->u_arg[2])
2217 tprintf("NULL");
2218 else if (syserror(tcp))
2219 tprintf("%#lx", tcp->u_arg[2]);
2220 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2221 tprintf("{???}");
2222 else
John Hughes58265892001-10-18 15:13:53 +00002223 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002224 /* options */
2225 tprintf(", ");
Roland McGrathb2dee132005-06-01 19:02:36 +00002226 printflags(wait4_options, tcp->u_arg[3], "W???");
Roland McGrath39426a32004-10-06 22:02:59 +00002227 if (tcp->u_nargs > 4) {
2228 /* usage */
2229 tprintf(", ");
2230 if (!tcp->u_arg[4])
2231 tprintf("NULL");
2232 else if (tcp->u_error)
2233 tprintf("%#lx", tcp->u_arg[4]);
2234 else
2235 printrusage(tcp, tcp->u_arg[4]);
2236 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002237 }
2238 return 0;
2239}
2240
Roland McGrathc74c0b72004-09-01 19:39:46 +00002241#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002242
2243int
2244sys_alarm(tcp)
2245struct tcb *tcp;
2246{
2247 if (entering(tcp))
2248 tprintf("%lu", tcp->u_arg[0]);
2249 return 0;
2250}
2251
2252int
2253sys_uname(tcp)
2254struct tcb *tcp;
2255{
2256 struct utsname uname;
2257
2258 if (exiting(tcp)) {
2259 if (syserror(tcp) || !verbose(tcp))
2260 tprintf("%#lx", tcp->u_arg[0]);
2261 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2262 tprintf("{...}");
2263 else if (!abbrev(tcp)) {
2264
2265 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2266 uname.sysname, uname.nodename);
2267 tprintf("release=\"%s\", version=\"%s\", ",
2268 uname.release, uname.version);
2269 tprintf("machine=\"%s\"", uname.machine);
2270#ifdef LINUX
2271#ifndef __GLIBC__
2272 tprintf(", domainname=\"%s\"", uname.domainname);
2273#endif /* __GLIBC__ */
2274#endif /* LINUX */
2275 tprintf("}");
2276 }
2277 else
2278 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2279 uname.sysname, uname.nodename);
2280 }
2281 return 0;
2282}
2283
2284#ifndef SVR4
2285
Roland McGrathd9f816f2004-09-04 03:39:20 +00002286static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002287#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002288 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2289 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2290 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2291 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2292 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2293 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2294 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2295 { PTRACE_CONT, "PTRACE_CONT" },
2296 { PTRACE_KILL, "PTRACE_KILL" },
2297 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2298 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2299 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002300#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002301 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002302#endif
2303#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002304 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002305#endif
2306#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002307 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002308#endif
2309#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002310 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002311#endif
2312#ifdef PTRACE_GETFPXREGS
2313 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2314#endif
2315#ifdef PTRACE_SETFPXREGS
2316 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2317#endif
Roland McGrathf04bb482005-05-09 07:45:33 +00002318#ifdef PTRACE_GETVRREGS
2319 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2320#endif
2321#ifdef PTRACE_SETVRREGS
2322 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2323#endif
Roland McGrathbf621d42003-01-14 09:46:21 +00002324#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002325 { PTRACE_READDATA, "PTRACE_READDATA" },
2326 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2327 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2328 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2329 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2330 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2331#ifdef SPARC
2332 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2333 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2334#else /* !SPARC */
2335 { PTRACE_22, "PTRACE_PTRACE_22" },
2336 { PTRACE_23, "PTRACE_PTRACE_23" },
2337#endif /* !SPARC */
2338#endif /* SUNOS4 */
2339 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2340#ifdef SUNOS4
2341 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2342#ifdef I386
2343 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2344 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2345 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2346#else /* !I386 */
2347 { PTRACE_26, "PTRACE_26" },
2348 { PTRACE_27, "PTRACE_27" },
2349 { PTRACE_28, "PTRACE_28" },
2350#endif /* !I386 */
2351 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2352#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002353#else /* FREEBSD */
2354 { PT_TRACE_ME, "PT_TRACE_ME" },
2355 { PT_READ_I, "PT_READ_I" },
2356 { PT_READ_D, "PT_READ_D" },
2357 { PT_WRITE_I, "PT_WRITE_I" },
2358 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002359#ifdef PT_READ_U
2360 { PT_READ_U, "PT_READ_U" },
2361#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002362 { PT_CONTINUE, "PT_CONTINUE" },
2363 { PT_KILL, "PT_KILL" },
2364 { PT_STEP, "PT_STEP" },
2365 { PT_ATTACH, "PT_ATTACH" },
2366 { PT_DETACH, "PT_DETACH" },
2367 { PT_GETREGS, "PT_GETREGS" },
2368 { PT_SETREGS, "PT_SETREGS" },
2369 { PT_GETFPREGS, "PT_GETFPREGS" },
2370 { PT_SETFPREGS, "PT_SETFPREGS" },
2371 { PT_GETDBREGS, "PT_GETDBREGS" },
2372 { PT_SETDBREGS, "PT_SETDBREGS" },
2373#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002374 { 0, NULL },
2375};
2376
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002377#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002378#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2379static
2380#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002381const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002382#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002383#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002384 { PT_PSWMASK, "psw_mask" },
2385 { PT_PSWADDR, "psw_addr" },
2386 { PT_GPR0, "gpr0" },
2387 { PT_GPR1, "gpr1" },
2388 { PT_GPR2, "gpr2" },
2389 { PT_GPR3, "gpr3" },
2390 { PT_GPR4, "gpr4" },
2391 { PT_GPR5, "gpr5" },
2392 { PT_GPR6, "gpr6" },
2393 { PT_GPR7, "gpr7" },
2394 { PT_GPR8, "gpr8" },
2395 { PT_GPR9, "gpr9" },
2396 { PT_GPR10, "gpr10" },
2397 { PT_GPR11, "gpr11" },
2398 { PT_GPR12, "gpr12" },
2399 { PT_GPR13, "gpr13" },
2400 { PT_GPR14, "gpr14" },
2401 { PT_GPR15, "gpr15" },
2402 { PT_ACR0, "acr0" },
2403 { PT_ACR1, "acr1" },
2404 { PT_ACR2, "acr2" },
2405 { PT_ACR3, "acr3" },
2406 { PT_ACR4, "acr4" },
2407 { PT_ACR5, "acr5" },
2408 { PT_ACR6, "acr6" },
2409 { PT_ACR7, "acr7" },
2410 { PT_ACR8, "acr8" },
2411 { PT_ACR9, "acr9" },
2412 { PT_ACR10, "acr10" },
2413 { PT_ACR11, "acr11" },
2414 { PT_ACR12, "acr12" },
2415 { PT_ACR13, "acr13" },
2416 { PT_ACR14, "acr14" },
2417 { PT_ACR15, "acr15" },
2418 { PT_ORIGGPR2, "orig_gpr2" },
2419 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002420#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002421 { PT_FPR0_HI, "fpr0.hi" },
2422 { PT_FPR0_LO, "fpr0.lo" },
2423 { PT_FPR1_HI, "fpr1.hi" },
2424 { PT_FPR1_LO, "fpr1.lo" },
2425 { PT_FPR2_HI, "fpr2.hi" },
2426 { PT_FPR2_LO, "fpr2.lo" },
2427 { PT_FPR3_HI, "fpr3.hi" },
2428 { PT_FPR3_LO, "fpr3.lo" },
2429 { PT_FPR4_HI, "fpr4.hi" },
2430 { PT_FPR4_LO, "fpr4.lo" },
2431 { PT_FPR5_HI, "fpr5.hi" },
2432 { PT_FPR5_LO, "fpr5.lo" },
2433 { PT_FPR6_HI, "fpr6.hi" },
2434 { PT_FPR6_LO, "fpr6.lo" },
2435 { PT_FPR7_HI, "fpr7.hi" },
2436 { PT_FPR7_LO, "fpr7.lo" },
2437 { PT_FPR8_HI, "fpr8.hi" },
2438 { PT_FPR8_LO, "fpr8.lo" },
2439 { PT_FPR9_HI, "fpr9.hi" },
2440 { PT_FPR9_LO, "fpr9.lo" },
2441 { PT_FPR10_HI, "fpr10.hi" },
2442 { PT_FPR10_LO, "fpr10.lo" },
2443 { PT_FPR11_HI, "fpr11.hi" },
2444 { PT_FPR11_LO, "fpr11.lo" },
2445 { PT_FPR12_HI, "fpr12.hi" },
2446 { PT_FPR12_LO, "fpr12.lo" },
2447 { PT_FPR13_HI, "fpr13.hi" },
2448 { PT_FPR13_LO, "fpr13.lo" },
2449 { PT_FPR14_HI, "fpr14.hi" },
2450 { PT_FPR14_LO, "fpr14.lo" },
2451 { PT_FPR15_HI, "fpr15.hi" },
2452 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002453#endif
2454#if defined(S390X)
2455 { PT_FPR0, "fpr0" },
2456 { PT_FPR1, "fpr1" },
2457 { PT_FPR2, "fpr2" },
2458 { PT_FPR3, "fpr3" },
2459 { PT_FPR4, "fpr4" },
2460 { PT_FPR5, "fpr5" },
2461 { PT_FPR6, "fpr6" },
2462 { PT_FPR7, "fpr7" },
2463 { PT_FPR8, "fpr8" },
2464 { PT_FPR9, "fpr9" },
2465 { PT_FPR10, "fpr10" },
2466 { PT_FPR11, "fpr11" },
2467 { PT_FPR12, "fpr12" },
2468 { PT_FPR13, "fpr13" },
2469 { PT_FPR14, "fpr14" },
2470 { PT_FPR15, "fpr15" },
2471#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002472 { PT_CR_9, "cr9" },
2473 { PT_CR_10, "cr10" },
2474 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002475 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002476#endif
2477#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002478 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002479#elif defined(HPPA)
2480 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002481#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002482#ifndef PT_ORIG_R3
2483#define PT_ORIG_R3 34
2484#endif
Roland McGratheb285352003-01-14 09:59:00 +00002485#define REGSIZE (sizeof(unsigned long))
2486 { REGSIZE*PT_R0, "r0" },
2487 { REGSIZE*PT_R1, "r1" },
2488 { REGSIZE*PT_R2, "r2" },
2489 { REGSIZE*PT_R3, "r3" },
2490 { REGSIZE*PT_R4, "r4" },
2491 { REGSIZE*PT_R5, "r5" },
2492 { REGSIZE*PT_R6, "r6" },
2493 { REGSIZE*PT_R7, "r7" },
2494 { REGSIZE*PT_R8, "r8" },
2495 { REGSIZE*PT_R9, "r9" },
2496 { REGSIZE*PT_R10, "r10" },
2497 { REGSIZE*PT_R11, "r11" },
2498 { REGSIZE*PT_R12, "r12" },
2499 { REGSIZE*PT_R13, "r13" },
2500 { REGSIZE*PT_R14, "r14" },
2501 { REGSIZE*PT_R15, "r15" },
2502 { REGSIZE*PT_R16, "r16" },
2503 { REGSIZE*PT_R17, "r17" },
2504 { REGSIZE*PT_R18, "r18" },
2505 { REGSIZE*PT_R19, "r19" },
2506 { REGSIZE*PT_R20, "r20" },
2507 { REGSIZE*PT_R21, "r21" },
2508 { REGSIZE*PT_R22, "r22" },
2509 { REGSIZE*PT_R23, "r23" },
2510 { REGSIZE*PT_R24, "r24" },
2511 { REGSIZE*PT_R25, "r25" },
2512 { REGSIZE*PT_R26, "r26" },
2513 { REGSIZE*PT_R27, "r27" },
2514 { REGSIZE*PT_R28, "r28" },
2515 { REGSIZE*PT_R29, "r29" },
2516 { REGSIZE*PT_R30, "r30" },
2517 { REGSIZE*PT_R31, "r31" },
2518 { REGSIZE*PT_NIP, "NIP" },
2519 { REGSIZE*PT_MSR, "MSR" },
2520 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2521 { REGSIZE*PT_CTR, "CTR" },
2522 { REGSIZE*PT_LNK, "LNK" },
2523 { REGSIZE*PT_XER, "XER" },
2524 { REGSIZE*PT_CCR, "CCR" },
2525 { REGSIZE*PT_FPR0, "FPR0" },
2526#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002527#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002528#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002529 { 0, "r0" },
2530 { 1, "r1" },
2531 { 2, "r2" },
2532 { 3, "r3" },
2533 { 4, "r4" },
2534 { 5, "r5" },
2535 { 6, "r6" },
2536 { 7, "r7" },
2537 { 8, "r8" },
2538 { 9, "r9" },
2539 { 10, "r10" },
2540 { 11, "r11" },
2541 { 12, "r12" },
2542 { 13, "r13" },
2543 { 14, "r14" },
2544 { 15, "r15" },
2545 { 16, "r16" },
2546 { 17, "r17" },
2547 { 18, "r18" },
2548 { 19, "r19" },
2549 { 20, "r20" },
2550 { 21, "r21" },
2551 { 22, "r22" },
2552 { 23, "r23" },
2553 { 24, "r24" },
2554 { 25, "r25" },
2555 { 26, "r26" },
2556 { 27, "r27" },
2557 { 28, "r28" },
2558 { 29, "gp" },
2559 { 30, "fp" },
2560 { 31, "zero" },
2561 { 32, "fp0" },
2562 { 33, "fp" },
2563 { 34, "fp2" },
2564 { 35, "fp3" },
2565 { 36, "fp4" },
2566 { 37, "fp5" },
2567 { 38, "fp6" },
2568 { 39, "fp7" },
2569 { 40, "fp8" },
2570 { 41, "fp9" },
2571 { 42, "fp10" },
2572 { 43, "fp11" },
2573 { 44, "fp12" },
2574 { 45, "fp13" },
2575 { 46, "fp14" },
2576 { 47, "fp15" },
2577 { 48, "fp16" },
2578 { 49, "fp17" },
2579 { 50, "fp18" },
2580 { 51, "fp19" },
2581 { 52, "fp20" },
2582 { 53, "fp21" },
2583 { 54, "fp22" },
2584 { 55, "fp23" },
2585 { 56, "fp24" },
2586 { 57, "fp25" },
2587 { 58, "fp26" },
2588 { 59, "fp27" },
2589 { 60, "fp28" },
2590 { 61, "fp29" },
2591 { 62, "fp30" },
2592 { 63, "fp31" },
2593 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002594#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002595#ifdef IA64
2596 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2597 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2598 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2599 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2600 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2601 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2602 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2603 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2604 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2605 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2606 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2607 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2608 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2609 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2610 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2611 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2612 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2613 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2614 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2615 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2616 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2617 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2618 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2619 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2620 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2621 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2622 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2623 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2624 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2625 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2626 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2627 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2628 /* switch stack: */
2629 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2630 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2631 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2632 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2633 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2634 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2635 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2636 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2637 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2638 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002639 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2640 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002641 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002642 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002643 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2644 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002645 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2646 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2647 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2648 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2649 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2650 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2651 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2652 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2653 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2654 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2655 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2656 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2657 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2658 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2659 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002660# ifdef PT_AR_CSD
2661 { PT_AR_CSD, "ar.csd" },
2662# endif
2663# ifdef PT_AR_SSD
2664 { PT_AR_SSD, "ar.ssd" },
2665# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002666 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002667#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002668#ifdef I386
2669 { 4*EBX, "4*EBX" },
2670 { 4*ECX, "4*ECX" },
2671 { 4*EDX, "4*EDX" },
2672 { 4*ESI, "4*ESI" },
2673 { 4*EDI, "4*EDI" },
2674 { 4*EBP, "4*EBP" },
2675 { 4*EAX, "4*EAX" },
2676 { 4*DS, "4*DS" },
2677 { 4*ES, "4*ES" },
2678 { 4*FS, "4*FS" },
2679 { 4*GS, "4*GS" },
2680 { 4*ORIG_EAX, "4*ORIG_EAX" },
2681 { 4*EIP, "4*EIP" },
2682 { 4*CS, "4*CS" },
2683 { 4*EFL, "4*EFL" },
2684 { 4*UESP, "4*UESP" },
2685 { 4*SS, "4*SS" },
2686#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002687#ifdef X86_64
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002688 { 8*R15, "8*R15" },
2689 { 8*R14, "8*R14" },
2690 { 8*R13, "8*R13" },
2691 { 8*R12, "8*R12" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002692 { 8*RBP, "8*RBP" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002693 { 8*RBX, "8*RBX" },
2694 { 8*R11, "8*R11" },
2695 { 8*R10, "8*R10" },
2696 { 8*R9, "8*R9" },
2697 { 8*R8, "8*R8" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002698 { 8*RAX, "8*RAX" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002699 { 8*RCX, "8*RCX" },
2700 { 8*RDX, "8*RDX" },
2701 { 8*RSI, "8*RSI" },
2702 { 8*RDI, "8*RDI" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002703#if 0
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002704 { DS, "DS" },
2705 { ES, "ES" },
2706 { FS, "FS" },
2707 { GS, "GS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002708#endif
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002709 { 8*ORIG_RAX, "8*ORIG_RAX" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002710 { 8*RIP, "8*RIP" },
2711 { 8*CS, "8*CS" },
2712 { 8*EFLAGS, "8*EFL" },
Roland McGratha4f9f2d2005-06-07 23:21:20 +00002713 { 8*RSP, "8*RSP" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002714 { 8*SS, "8*SS" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002715#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002716#ifdef M68K
2717 { 4*PT_D1, "4*PT_D1" },
2718 { 4*PT_D2, "4*PT_D2" },
2719 { 4*PT_D3, "4*PT_D3" },
2720 { 4*PT_D4, "4*PT_D4" },
2721 { 4*PT_D5, "4*PT_D5" },
2722 { 4*PT_D6, "4*PT_D6" },
2723 { 4*PT_D7, "4*PT_D7" },
2724 { 4*PT_A0, "4*PT_A0" },
2725 { 4*PT_A1, "4*PT_A1" },
2726 { 4*PT_A2, "4*PT_A2" },
2727 { 4*PT_A3, "4*PT_A3" },
2728 { 4*PT_A4, "4*PT_A4" },
2729 { 4*PT_A5, "4*PT_A5" },
2730 { 4*PT_A6, "4*PT_A6" },
2731 { 4*PT_D0, "4*PT_D0" },
2732 { 4*PT_USP, "4*PT_USP" },
2733 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2734 { 4*PT_SR, "4*PT_SR" },
2735 { 4*PT_PC, "4*PT_PC" },
2736#endif /* M68K */
2737#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002738#ifdef SH
2739 { 4*REG_REG0, "4*REG_REG0" },
2740 { 4*(REG_REG0+1), "4*REG_REG1" },
2741 { 4*(REG_REG0+2), "4*REG_REG2" },
2742 { 4*(REG_REG0+3), "4*REG_REG3" },
2743 { 4*(REG_REG0+4), "4*REG_REG4" },
2744 { 4*(REG_REG0+5), "4*REG_REG5" },
2745 { 4*(REG_REG0+6), "4*REG_REG6" },
2746 { 4*(REG_REG0+7), "4*REG_REG7" },
2747 { 4*(REG_REG0+8), "4*REG_REG8" },
2748 { 4*(REG_REG0+9), "4*REG_REG9" },
2749 { 4*(REG_REG0+10), "4*REG_REG10" },
2750 { 4*(REG_REG0+11), "4*REG_REG11" },
2751 { 4*(REG_REG0+12), "4*REG_REG12" },
2752 { 4*(REG_REG0+13), "4*REG_REG13" },
2753 { 4*(REG_REG0+14), "4*REG_REG14" },
2754 { 4*REG_REG15, "4*REG_REG15" },
2755 { 4*REG_PC, "4*REG_PC" },
2756 { 4*REG_PR, "4*REG_PR" },
2757 { 4*REG_SR, "4*REG_SR" },
2758 { 4*REG_GBR, "4*REG_GBR" },
2759 { 4*REG_MACH, "4*REG_MACH" },
2760 { 4*REG_MACL, "4*REG_MACL" },
2761 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2762 { 4*REG_FPUL, "4*REG_FPUL" },
2763 { 4*REG_FPREG0, "4*REG_FPREG0" },
2764 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2765 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2766 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2767 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2768 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2769 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2770 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2771 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2772 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2773 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2774 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2775 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2776 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2777 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2778 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002779#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002780 { 4*REG_XDREG0, "4*REG_XDREG0" },
2781 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2782 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2783 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2784 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2785 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2786 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2787 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002788#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002789 { 4*REG_FPSCR, "4*REG_FPSCR" },
2790#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002791#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002792 { 0, "PC(L)" },
2793 { 4, "PC(U)" },
2794 { 8, "SR(L)" },
2795 { 12, "SR(U)" },
2796 { 16, "syscall no.(L)" },
2797 { 20, "syscall_no.(U)" },
2798 { 24, "R0(L)" },
2799 { 28, "R0(U)" },
2800 { 32, "R1(L)" },
2801 { 36, "R1(U)" },
2802 { 40, "R2(L)" },
2803 { 44, "R2(U)" },
2804 { 48, "R3(L)" },
2805 { 52, "R3(U)" },
2806 { 56, "R4(L)" },
2807 { 60, "R4(U)" },
2808 { 64, "R5(L)" },
2809 { 68, "R5(U)" },
2810 { 72, "R6(L)" },
2811 { 76, "R6(U)" },
2812 { 80, "R7(L)" },
2813 { 84, "R7(U)" },
2814 { 88, "R8(L)" },
2815 { 92, "R8(U)" },
2816 { 96, "R9(L)" },
2817 { 100, "R9(U)" },
2818 { 104, "R10(L)" },
2819 { 108, "R10(U)" },
2820 { 112, "R11(L)" },
2821 { 116, "R11(U)" },
2822 { 120, "R12(L)" },
2823 { 124, "R12(U)" },
2824 { 128, "R13(L)" },
2825 { 132, "R13(U)" },
2826 { 136, "R14(L)" },
2827 { 140, "R14(U)" },
2828 { 144, "R15(L)" },
2829 { 148, "R15(U)" },
2830 { 152, "R16(L)" },
2831 { 156, "R16(U)" },
2832 { 160, "R17(L)" },
2833 { 164, "R17(U)" },
2834 { 168, "R18(L)" },
2835 { 172, "R18(U)" },
2836 { 176, "R19(L)" },
2837 { 180, "R19(U)" },
2838 { 184, "R20(L)" },
2839 { 188, "R20(U)" },
2840 { 192, "R21(L)" },
2841 { 196, "R21(U)" },
2842 { 200, "R22(L)" },
2843 { 204, "R22(U)" },
2844 { 208, "R23(L)" },
2845 { 212, "R23(U)" },
2846 { 216, "R24(L)" },
2847 { 220, "R24(U)" },
2848 { 224, "R25(L)" },
2849 { 228, "R25(U)" },
2850 { 232, "R26(L)" },
2851 { 236, "R26(U)" },
2852 { 240, "R27(L)" },
2853 { 244, "R27(U)" },
2854 { 248, "R28(L)" },
2855 { 252, "R28(U)" },
2856 { 256, "R29(L)" },
2857 { 260, "R29(U)" },
2858 { 264, "R30(L)" },
2859 { 268, "R30(U)" },
2860 { 272, "R31(L)" },
2861 { 276, "R31(U)" },
2862 { 280, "R32(L)" },
2863 { 284, "R32(U)" },
2864 { 288, "R33(L)" },
2865 { 292, "R33(U)" },
2866 { 296, "R34(L)" },
2867 { 300, "R34(U)" },
2868 { 304, "R35(L)" },
2869 { 308, "R35(U)" },
2870 { 312, "R36(L)" },
2871 { 316, "R36(U)" },
2872 { 320, "R37(L)" },
2873 { 324, "R37(U)" },
2874 { 328, "R38(L)" },
2875 { 332, "R38(U)" },
2876 { 336, "R39(L)" },
2877 { 340, "R39(U)" },
2878 { 344, "R40(L)" },
2879 { 348, "R40(U)" },
2880 { 352, "R41(L)" },
2881 { 356, "R41(U)" },
2882 { 360, "R42(L)" },
2883 { 364, "R42(U)" },
2884 { 368, "R43(L)" },
2885 { 372, "R43(U)" },
2886 { 376, "R44(L)" },
2887 { 380, "R44(U)" },
2888 { 384, "R45(L)" },
2889 { 388, "R45(U)" },
2890 { 392, "R46(L)" },
2891 { 396, "R46(U)" },
2892 { 400, "R47(L)" },
2893 { 404, "R47(U)" },
2894 { 408, "R48(L)" },
2895 { 412, "R48(U)" },
2896 { 416, "R49(L)" },
2897 { 420, "R49(U)" },
2898 { 424, "R50(L)" },
2899 { 428, "R50(U)" },
2900 { 432, "R51(L)" },
2901 { 436, "R51(U)" },
2902 { 440, "R52(L)" },
2903 { 444, "R52(U)" },
2904 { 448, "R53(L)" },
2905 { 452, "R53(U)" },
2906 { 456, "R54(L)" },
2907 { 460, "R54(U)" },
2908 { 464, "R55(L)" },
2909 { 468, "R55(U)" },
2910 { 472, "R56(L)" },
2911 { 476, "R56(U)" },
2912 { 480, "R57(L)" },
2913 { 484, "R57(U)" },
2914 { 488, "R58(L)" },
2915 { 492, "R58(U)" },
2916 { 496, "R59(L)" },
2917 { 500, "R59(U)" },
2918 { 504, "R60(L)" },
2919 { 508, "R60(U)" },
2920 { 512, "R61(L)" },
2921 { 516, "R61(U)" },
2922 { 520, "R62(L)" },
2923 { 524, "R62(U)" },
2924 { 528, "TR0(L)" },
2925 { 532, "TR0(U)" },
2926 { 536, "TR1(L)" },
2927 { 540, "TR1(U)" },
2928 { 544, "TR2(L)" },
2929 { 548, "TR2(U)" },
2930 { 552, "TR3(L)" },
2931 { 556, "TR3(U)" },
2932 { 560, "TR4(L)" },
2933 { 564, "TR4(U)" },
2934 { 568, "TR5(L)" },
2935 { 572, "TR5(U)" },
2936 { 576, "TR6(L)" },
2937 { 580, "TR6(U)" },
2938 { 584, "TR7(L)" },
2939 { 588, "TR7(U)" },
2940 /* This entry is in case pt_regs contains dregs (depends on
2941 the kernel build options). */
2942 { uoff(regs), "offsetof(struct user, regs)" },
2943 { uoff(fpu), "offsetof(struct user, fpu)" },
2944#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002945#ifdef ARM
2946 { uoff(regs.ARM_r0), "r0" },
2947 { uoff(regs.ARM_r1), "r1" },
2948 { uoff(regs.ARM_r2), "r2" },
2949 { uoff(regs.ARM_r3), "r3" },
2950 { uoff(regs.ARM_r4), "r4" },
2951 { uoff(regs.ARM_r5), "r5" },
2952 { uoff(regs.ARM_r6), "r6" },
2953 { uoff(regs.ARM_r7), "r7" },
2954 { uoff(regs.ARM_r8), "r8" },
2955 { uoff(regs.ARM_r9), "r9" },
2956 { uoff(regs.ARM_r10), "r10" },
2957 { uoff(regs.ARM_fp), "fp" },
2958 { uoff(regs.ARM_ip), "ip" },
2959 { uoff(regs.ARM_sp), "sp" },
2960 { uoff(regs.ARM_lr), "lr" },
2961 { uoff(regs.ARM_pc), "pc" },
2962 { uoff(regs.ARM_cpsr), "cpsr" },
2963#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002964
Roland McGrath542c2c62008-05-20 01:11:56 +00002965#ifdef MIPS
2966 { 0, "r0" },
2967 { 1, "r1" },
2968 { 2, "r2" },
2969 { 3, "r3" },
2970 { 4, "r4" },
2971 { 5, "r5" },
2972 { 6, "r6" },
2973 { 7, "r7" },
2974 { 8, "r8" },
2975 { 9, "r9" },
2976 { 10, "r10" },
2977 { 11, "r11" },
2978 { 12, "r12" },
2979 { 13, "r13" },
2980 { 14, "r14" },
2981 { 15, "r15" },
2982 { 16, "r16" },
2983 { 17, "r17" },
2984 { 18, "r18" },
2985 { 19, "r19" },
2986 { 20, "r20" },
2987 { 21, "r21" },
2988 { 22, "r22" },
2989 { 23, "r23" },
2990 { 24, "r24" },
2991 { 25, "r25" },
2992 { 26, "r26" },
2993 { 27, "r27" },
2994 { 28, "r28" },
2995 { 29, "r29" },
2996 { 30, "r30" },
2997 { 31, "r31" },
2998 { 32, "f0" },
2999 { 33, "f1" },
3000 { 34, "f2" },
3001 { 35, "f3" },
3002 { 36, "f4" },
3003 { 37, "f5" },
3004 { 38, "f6" },
3005 { 39, "f7" },
3006 { 40, "f8" },
3007 { 41, "f9" },
3008 { 42, "f10" },
3009 { 43, "f11" },
3010 { 44, "f12" },
3011 { 45, "f13" },
3012 { 46, "f14" },
3013 { 47, "f15" },
3014 { 48, "f16" },
3015 { 49, "f17" },
3016 { 50, "f18" },
3017 { 51, "f19" },
3018 { 52, "f20" },
3019 { 53, "f21" },
3020 { 54, "f22" },
3021 { 55, "f23" },
3022 { 56, "f24" },
3023 { 57, "f25" },
3024 { 58, "f26" },
3025 { 59, "f27" },
3026 { 60, "f28" },
3027 { 61, "f29" },
3028 { 62, "f30" },
3029 { 63, "f31" },
3030 { 64, "pc" },
3031 { 65, "cause" },
3032 { 66, "badvaddr" },
3033 { 67, "mmhi" },
3034 { 68, "mmlo" },
3035 { 69, "fpcsr" },
3036 { 70, "fpeir" },
3037#endif
3038
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003039#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003040 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003041#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00003042#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003043 { uoff(i387), "offsetof(struct user, i387)" },
3044#else /* !I386 */
3045#ifdef M68K
3046 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3047#endif /* M68K */
3048#endif /* !I386 */
3049 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3050 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3051 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003052#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003053 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003054#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00003055#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00003056 { uoff(start_data), "offsetof(struct user, start_data)" },
3057#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003058#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003059 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003060#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003061 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003062#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003063 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00003064#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003065#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003066 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00003067#endif
3068#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003069 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3070#endif
3071 { uoff(magic), "offsetof(struct user, magic)" },
3072 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00003073#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003074 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3075#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00003076#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003077#endif /* !ALPHA */
3078#endif /* !POWERPC/!SPARC */
3079#endif /* LINUX */
3080#ifdef SUNOS4
3081 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3082 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3083 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3084 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3085 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3086 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3087 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3088 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3089 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3090 { uoff(u_error), "offsetof(struct user, u_error)" },
3091 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3092 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3093 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3094 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3095 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3096 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3097 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3098 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3099 { uoff(u_code), "offsetof(struct user, u_code)" },
3100 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3101 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3102 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3103 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3104 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3105 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3106 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3107 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3108 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3109 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3110 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3111 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3112 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3113 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3114 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3115 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3116 { uoff(u_start), "offsetof(struct user, u_start)" },
3117 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3118 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3119 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3120 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3121 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3122 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3123 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3124 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3125 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3126#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003127#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003128 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00003129#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003130 { 0, NULL },
3131};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003132#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003133
3134int
3135sys_ptrace(tcp)
3136struct tcb *tcp;
3137{
Roland McGrathd9f816f2004-09-04 03:39:20 +00003138 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003139 long addr;
3140
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003141 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00003142 printxval(ptrace_cmds, tcp->u_arg[0],
3143#ifndef FREEBSD
3144 "PTRACE_???"
3145#else
3146 "PT_???"
3147#endif
3148 );
3149 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003150 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003151#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003152 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3153 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3154 for (x = struct_user_offsets; x->str; x++) {
3155 if (x->val >= addr)
3156 break;
3157 }
3158 if (!x->str)
3159 tprintf("%#lx, ", addr);
3160 else if (x->val > addr && x != struct_user_offsets) {
3161 x--;
3162 tprintf("%s + %ld, ", x->str, addr - x->val);
3163 }
3164 else
3165 tprintf("%s, ", x->str);
3166 }
3167 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003168#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003169 tprintf("%#lx, ", tcp->u_arg[2]);
3170#ifdef LINUX
3171 switch (tcp->u_arg[0]) {
Roland McGrath1e868062007-11-19 22:11:45 +00003172#ifndef IA64
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003173 case PTRACE_PEEKDATA:
3174 case PTRACE_PEEKTEXT:
3175 case PTRACE_PEEKUSER:
3176 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003177#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003178 case PTRACE_CONT:
3179 case PTRACE_SINGLESTEP:
3180 case PTRACE_SYSCALL:
3181 case PTRACE_DETACH:
3182 printsignal(tcp->u_arg[3]);
3183 break;
3184 default:
3185 tprintf("%#lx", tcp->u_arg[3]);
3186 break;
3187 }
3188 } else {
3189 switch (tcp->u_arg[0]) {
3190 case PTRACE_PEEKDATA:
3191 case PTRACE_PEEKTEXT:
3192 case PTRACE_PEEKUSER:
Roland McGrath1e868062007-11-19 22:11:45 +00003193#ifdef IA64
3194 return RVAL_HEX;
3195#else
Roland McGratheb285352003-01-14 09:59:00 +00003196 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003197 break;
Roland McGrath1e868062007-11-19 22:11:45 +00003198#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003199 }
3200 }
3201#endif /* LINUX */
3202#ifdef SUNOS4
3203 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3204 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3205 tprintf("%lu, ", tcp->u_arg[3]);
3206 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3207 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3208 tcp->u_arg[0] != PTRACE_READTEXT) {
3209 tprintf("%#lx", tcp->u_arg[3]);
3210 }
3211 } else {
3212 if (tcp->u_arg[0] == PTRACE_READDATA ||
3213 tcp->u_arg[0] == PTRACE_READTEXT) {
3214 tprintf("%lu, ", tcp->u_arg[3]);
3215 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3216 }
3217 }
3218#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00003219#ifdef FREEBSD
3220 tprintf("%lu", tcp->u_arg[3]);
3221 }
3222#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00003223 return 0;
3224}
3225
3226#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00003227
3228#ifdef LINUX
Roland McGrath51942a92007-07-05 18:59:11 +00003229# ifndef FUTEX_CMP_REQUEUE
3230# define FUTEX_CMP_REQUEUE 4
3231# endif
3232# ifndef FUTEX_WAKE_OP
3233# define FUTEX_WAKE_OP 5
3234# endif
3235# ifndef FUTEX_LOCK_PI
3236# define FUTEX_LOCK_PI 6
3237# define FUTEX_UNLOCK_PI 7
3238# define FUTEX_TRYLOCK_PI 8
3239# endif
Roland McGrath1aeaf742008-07-18 01:27:39 +00003240# ifndef FUTEX_WAIT_BITSET
3241# define FUTEX_WAIT_BITSET 9
3242# endif
3243# ifndef FUTEX_WAKE_BITSET
3244# define FUTEX_WAKE_BITSET 10
Roland McGrath51942a92007-07-05 18:59:11 +00003245# endif
3246# ifndef FUTEX_PRIVATE_FLAG
3247# define FUTEX_PRIVATE_FLAG 128
3248# endif
Roland McGrathd9f816f2004-09-04 03:39:20 +00003249static const struct xlat futexops[] = {
Roland McGrath51942a92007-07-05 18:59:11 +00003250 { FUTEX_WAIT, "FUTEX_WAIT" },
3251 { FUTEX_WAKE, "FUTEX_WAKE" },
3252 { FUTEX_FD, "FUTEX_FD" },
3253 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3254 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3255 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3256 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3257 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3258 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003259 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3260 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
Roland McGrath51942a92007-07-05 18:59:11 +00003261 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3262 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3263 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3264 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3265 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3266 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3267 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3268 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3269 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
Roland McGrath1aeaf742008-07-18 01:27:39 +00003270 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3271 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
Roland McGrath51942a92007-07-05 18:59:11 +00003272 { 0, NULL }
3273};
3274#ifndef FUTEX_OP_SET
3275# define FUTEX_OP_SET 0
3276# define FUTEX_OP_ADD 1
3277# define FUTEX_OP_OR 2
3278# define FUTEX_OP_ANDN 3
3279# define FUTEX_OP_XOR 4
3280# define FUTEX_OP_CMP_EQ 0
3281# define FUTEX_OP_CMP_NE 1
3282# define FUTEX_OP_CMP_LT 2
3283# define FUTEX_OP_CMP_LE 3
3284# define FUTEX_OP_CMP_GT 4
3285# define FUTEX_OP_CMP_GE 5
3286#endif
3287static const struct xlat futexwakeops[] = {
3288 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3289 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3290 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3291 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3292 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3293 { 0, NULL }
3294};
3295static const struct xlat futexwakecmps[] = {
3296 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3297 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3298 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3299 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3300 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3301 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3302 { 0, NULL }
Roland McGrath5a223472002-12-15 23:58:26 +00003303};
3304
3305int
3306sys_futex(tcp)
3307struct tcb *tcp;
3308{
3309 if (entering(tcp)) {
Roland McGrath1aeaf742008-07-18 01:27:39 +00003310 long int cmd = tcp->u_arg[1] & 127;
Roland McGrath5a223472002-12-15 23:58:26 +00003311 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003312 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003313 tprintf(", %ld", tcp->u_arg[2]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003314 if (cmd == FUTEX_WAKE_BITSET)
3315 tprintf(", %lx", tcp->u_arg[5]);
3316 else if (cmd == FUTEX_WAIT) {
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003317 tprintf(", ");
3318 printtv(tcp, tcp->u_arg[3]);
Roland McGrath1aeaf742008-07-18 01:27:39 +00003319 } else if (cmd == FUTEX_WAIT_BITSET) {
3320 tprintf(", ");
3321 printtv(tcp, tcp->u_arg[3]);
3322 tprintf(", %lx", tcp->u_arg[5]);
Roland McGrath51942a92007-07-05 18:59:11 +00003323 } else if (cmd == FUTEX_REQUEUE)
Roland McGrath88812d62003-06-26 22:27:23 +00003324 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath51942a92007-07-05 18:59:11 +00003325 else if (cmd == FUTEX_CMP_REQUEUE)
3326 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3327 else if (cmd == FUTEX_WAKE_OP) {
3328 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3329 if ((tcp->u_arg[5] >> 28) & 8)
3330 tprintf("FUTEX_OP_OPARG_SHIFT|");
3331 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3332 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3333 if ((tcp->u_arg[5] >> 24) & 8)
3334 tprintf("FUTEX_OP_OPARG_SHIFT|");
3335 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3336 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3337 }
Roland McGrath5a223472002-12-15 23:58:26 +00003338 }
3339 return 0;
3340}
3341
3342static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003343print_affinitylist(tcp, list, len)
3344struct tcb *tcp;
3345long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003346unsigned int len;
3347{
3348 int first = 1;
3349 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003350 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003351 unsigned long w;
3352 umove(tcp, list, &w);
3353 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003354 first = 0;
3355 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003356 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003357 }
3358 tprintf(" }");
3359}
3360
3361int
3362sys_sched_setaffinity(tcp)
3363struct tcb *tcp;
3364{
3365 if (entering(tcp)) {
3366 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003367 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003368 }
3369 return 0;
3370}
3371
3372int
3373sys_sched_getaffinity(tcp)
3374struct tcb *tcp;
3375{
3376 if (entering(tcp)) {
3377 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3378 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003379 if (tcp->u_rval == -1)
3380 tprintf("%#lx", tcp->u_arg[2]);
3381 else
3382 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003383 }
3384 return 0;
3385}
Roland McGrath279d3782004-03-01 20:27:37 +00003386
Roland McGrathd9f816f2004-09-04 03:39:20 +00003387static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003388 { SCHED_OTHER, "SCHED_OTHER" },
3389 { SCHED_RR, "SCHED_RR" },
3390 { SCHED_FIFO, "SCHED_FIFO" },
3391 { 0, NULL }
3392};
3393
3394int
3395sys_sched_getscheduler(tcp)
3396struct tcb *tcp;
3397{
3398 if (entering(tcp)) {
3399 tprintf("%d", (int) tcp->u_arg[0]);
3400 } else if (! syserror(tcp)) {
3401 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3402 if (tcp->auxstr != NULL)
3403 return RVAL_STR;
3404 }
3405 return 0;
3406}
3407
3408int
3409sys_sched_setscheduler(tcp)
3410struct tcb *tcp;
3411{
3412 if (entering(tcp)) {
3413 struct sched_param p;
3414 tprintf("%d, ", (int) tcp->u_arg[0]);
3415 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3416 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003417 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003418 else
3419 tprintf(", { %d }", p.__sched_priority);
3420 }
3421 return 0;
3422}
3423
3424int
3425sys_sched_getparam(tcp)
3426struct tcb *tcp;
3427{
3428 if (entering(tcp)) {
3429 tprintf("%d, ", (int) tcp->u_arg[0]);
3430 } else {
3431 struct sched_param p;
3432 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003433 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003434 else
3435 tprintf("{ %d }", p.__sched_priority);
3436 }
3437 return 0;
3438}
3439
3440int
3441sys_sched_setparam(tcp)
3442struct tcb *tcp;
3443{
3444 if (entering(tcp)) {
3445 struct sched_param p;
3446 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003447 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003448 else
3449 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3450 }
3451 return 0;
3452}
3453
3454int
3455sys_sched_get_priority_min(tcp)
3456struct tcb *tcp;
3457{
3458 if (entering(tcp)) {
3459 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3460 }
3461 return 0;
3462}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003463
3464#ifdef X86_64
3465#include <asm/prctl.h>
3466
3467static const struct xlat archvals[] = {
3468 { ARCH_SET_GS, "ARCH_SET_GS" },
3469 { ARCH_SET_FS, "ARCH_SET_FS" },
3470 { ARCH_GET_FS, "ARCH_GET_FS" },
3471 { ARCH_GET_GS, "ARCH_GET_GS" },
3472 { 0, NULL },
3473};
3474
3475int
3476sys_arch_prctl(tcp)
3477struct tcb *tcp;
3478{
3479 if (entering(tcp)) {
3480 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3481 if (tcp->u_arg[0] == ARCH_SET_GS
3482 || tcp->u_arg[0] == ARCH_SET_FS)
3483 tprintf(", %#lx", tcp->u_arg[1]);
3484 } else {
3485 if (tcp->u_arg[0] == ARCH_GET_GS
3486 || tcp->u_arg[0] == ARCH_GET_FS) {
3487 long int v;
3488 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3489 tprintf(", [%#lx]", v);
3490 else
3491 tprintf(", %#lx", tcp->u_arg[1]);
3492 }
3493 }
3494 return 0;
3495}
3496#endif
3497
Roland McGrathdb8319f2007-08-02 01:37:55 +00003498
3499int
3500sys_getcpu(tcp)
3501struct tcb *tcp;
3502{
3503 if (exiting(tcp)) {
3504 unsigned u;
3505 if (tcp->u_arg[0] == 0)
3506 tprintf("NULL, ");
3507 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3508 tprintf("%#lx, ", tcp->u_arg[0]);
3509 else
3510 tprintf("[%u], ", u);
3511 if (tcp->u_arg[1] == 0)
3512 tprintf("NULL, ");
3513 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3514 tprintf("%#lx, ", tcp->u_arg[1]);
3515 else
3516 tprintf("[%u], ", u);
3517 tprintf("%#lx", tcp->u_arg[2]);
3518 }
3519 return 0;
3520}
3521
Roland McGrath5a223472002-12-15 23:58:26 +00003522#endif