blob: 0a7f4868aff74eda155e4a77dd04cb07617785b2 [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
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000207#ifdef PR_GET_UNALIGN
208 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
209#endif
210#ifdef PR_SET_UNALIGN
211 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
212#endif
213#ifdef PR_GET_KEEPCAPS
214 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
215#endif
216#ifdef PR_SET_KEEPCAPS
217 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
218#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000219 { 0, NULL },
220};
221
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000222
223const char *
224unalignctl_string (unsigned int ctl)
225{
226 static char buf[16];
227
228 switch (ctl) {
229#ifdef PR_UNALIGN_NOPRINT
230 case PR_UNALIGN_NOPRINT:
231 return "NOPRINT";
232#endif
233#ifdef PR_UNALIGN_SIGBUS
234 case PR_UNALIGN_SIGBUS:
235 return "SIGBUS";
236#endif
237 default:
238 break;
239 }
240 sprintf(buf, "%x", ctl);
241 return buf;
242}
243
244
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000245int
246sys_prctl(tcp)
247struct tcb *tcp;
248{
249 int i;
250
251 if (entering(tcp)) {
252 printxval(prctl_options, tcp->u_arg[0], "PR_???");
253 switch (tcp->u_arg[0]) {
254#ifdef PR_GETNSHARE
255 case PR_GETNSHARE:
256 break;
257#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000258#ifdef PR_SET_DEATHSIG
259 case PR_GET_PDEATHSIG:
260 break;
261#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000262#ifdef PR_SET_UNALIGN
263 case PR_SET_UNALIGN:
264 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
265 break;
266#endif
267#ifdef PR_GET_UNALIGN
268 case PR_GET_UNALIGN:
269 tprintf(", %#lx", tcp->u_arg[1]);
270 break;
271#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000272 default:
273 for (i = 1; i < tcp->u_nargs; i++)
274 tprintf(", %#lx", tcp->u_arg[i]);
275 break;
276 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000277 } else {
278 switch (tcp->u_arg[0]) {
279#ifdef PR_GET_PDEATHSIG
280 case PR_GET_PDEATHSIG:
281 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000282 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000283 break;
284#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000285#ifdef PR_SET_UNALIGN
286 case PR_SET_UNALIGN:
287 break;
288#endif
289#ifdef PR_GET_UNALIGN
290 case PR_GET_UNALIGN:
291 {
292 int ctl;
293
294 umove(tcp, tcp->u_arg[1], &ctl);
295 tcp->auxstr = unalignctl_string(ctl);
296 return RVAL_STR;
297 }
298#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000299 default:
300 break;
301 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000302 }
303 return 0;
304}
305
306#endif /* HAVE_PRCTL */
307
308int
309sys_gethostid(tcp)
310struct tcb *tcp;
311{
312 if (exiting(tcp))
313 return RVAL_HEX;
314 return 0;
315}
316
317int
318sys_sethostname(tcp)
319struct tcb *tcp;
320{
321 if (entering(tcp)) {
322 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
323 tprintf(", %lu", tcp->u_arg[1]);
324 }
325 return 0;
326}
327
328int
329sys_gethostname(tcp)
330struct tcb *tcp;
331{
332 if (exiting(tcp)) {
333 if (syserror(tcp))
334 tprintf("%#lx", tcp->u_arg[0]);
335 else
336 printpath(tcp, tcp->u_arg[0]);
337 tprintf(", %lu", tcp->u_arg[1]);
338 }
339 return 0;
340}
341
342int
343sys_setdomainname(tcp)
344struct tcb *tcp;
345{
346 if (entering(tcp)) {
347 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
348 tprintf(", %lu", tcp->u_arg[1]);
349 }
350 return 0;
351}
352
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000353#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000354
355int
356sys_getdomainname(tcp)
357struct tcb *tcp;
358{
359 if (exiting(tcp)) {
360 if (syserror(tcp))
361 tprintf("%#lx", tcp->u_arg[0]);
362 else
363 printpath(tcp, tcp->u_arg[0]);
364 tprintf(", %lu", tcp->u_arg[1]);
365 }
366 return 0;
367}
368#endif /* !LINUX */
369
370int
371sys_exit(tcp)
372struct tcb *tcp;
373{
374 if (exiting(tcp)) {
375 fprintf(stderr, "_exit returned!\n");
376 return -1;
377 }
378 /* special case: we stop tracing this process, finish line now */
379 tprintf("%ld) ", tcp->u_arg[0]);
380 tabto(acolumn);
381 tprintf("= ?");
382 printtrailer(tcp);
383 return 0;
384}
385
386int
387internal_exit(tcp)
388struct tcb *tcp;
389{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000390 if (entering(tcp)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000391 tcp->flags |= TCB_EXITING;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000392#ifdef __NR_exit_group
Roland McGrath08267b82004-02-20 22:56:43 +0000393# ifdef IA64
394 if (ia32) {
395 if (tcp->scno == 252)
396 tcp->flags |= TCB_GROUP_EXITING;
397 } else
398# endif
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000399 if (tcp->scno == __NR_exit_group)
400 tcp->flags |= TCB_GROUP_EXITING;
401#endif
402 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000403 return 0;
404}
405
Roland McGrathee9d4352002-12-18 04:16:10 +0000406/* TCP is creating a child we want to follow.
407 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
408 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
409static int
410fork_tcb(struct tcb *tcp)
411{
412 if (nprocs == tcbtabsize) {
Roland McGrath7b54a7a2004-06-04 01:50:45 +0000413 if (expand_tcbtab()) {
Roland McGrathee9d4352002-12-18 04:16:10 +0000414 tcp->flags &= ~TCB_FOLLOWFORK;
415 fprintf(stderr, "sys_fork: tcb table full\n");
Roland McGrathee9d4352002-12-18 04:16:10 +0000416 }
Roland McGrathee9d4352002-12-18 04:16:10 +0000417 }
418
419 tcp->flags |= TCB_FOLLOWFORK;
420 return 0;
421}
422
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000423#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000424
425int
426sys_fork(tcp)
427struct tcb *tcp;
428{
429 if (exiting(tcp)) {
430 if (getrval2(tcp)) {
431 tcp->auxstr = "child process";
432 return RVAL_UDECIMAL | RVAL_STR;
433 }
434 }
435 return 0;
436}
437
John Hughes4e36a812001-04-18 15:11:51 +0000438#if UNIXWARE > 2
439
440int
441sys_rfork(tcp)
442struct tcb *tcp;
443{
444 if (entering(tcp)) {
445 tprintf ("%ld", tcp->u_arg[0]);
446 }
447 else {
448 if (getrval2(tcp)) {
449 tcp->auxstr = "child process";
450 return RVAL_UDECIMAL | RVAL_STR;
451 }
452 }
453 return 0;
454}
455
456#endif
457
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000458int
459internal_fork(tcp)
460struct tcb *tcp;
461{
462 struct tcb *tcpchild;
463
464 if (exiting(tcp)) {
Roland McGrathf3a0e1b2003-02-20 02:45:22 +0000465#ifdef SYS_rfork
466 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
467 return 0;
468#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000469 if (getrval2(tcp))
470 return 0;
471 if (!followfork)
472 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000473 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000474 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000475 if (syserror(tcp))
476 return 0;
477 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
478 fprintf(stderr, "sys_fork: tcb table full\n");
479 return 0;
480 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000481 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000482 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000483 }
484 return 0;
485}
486
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000487#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000488
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000489#ifdef LINUX
490
491/* defines copied from linux/sched.h since we can't include that
492 * ourselves (it conflicts with *lots* of libc includes)
493 */
494#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
495#define CLONE_VM 0x00000100 /* set if VM shared between processes */
496#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
497#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
498#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000499#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000500#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
501#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
502#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000503#define CLONE_THREAD 0x00010000 /* Same thread group? */
504#define CLONE_NEWNS 0x00020000 /* New namespace group? */
505#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
506#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
507#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
508#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
509#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
510#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
511#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000512
Roland McGrathd9f816f2004-09-04 03:39:20 +0000513static const struct xlat clone_flags[] = {
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000514 { CLONE_VM, "CLONE_VM" },
515 { CLONE_FS, "CLONE_FS" },
516 { CLONE_FILES, "CLONE_FILES" },
517 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000518 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000519 { CLONE_PTRACE, "CLONE_PTRACE" },
520 { CLONE_VFORK, "CLONE_VFORK" },
521 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000522 { CLONE_THREAD, "CLONE_THREAD" },
523 { CLONE_NEWNS, "CLONE_NEWNS" },
524 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
525 { CLONE_SETTLS, "CLONE_SETTLS" },
526 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
527 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
528 { CLONE_DETACHED, "CLONE_DETACHED" },
529 { CLONE_UNTRACED, "CLONE_UNTRACED" },
530 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000531 { 0, NULL },
532};
533
Roland McGrath909875b2002-12-22 03:34:36 +0000534# ifdef I386
535# include <asm/ldt.h>
Roland McGrath7decfb22004-03-01 22:10:52 +0000536# ifdef HAVE_STRUCT_USER_DESC
537# define modify_ldt_ldt_s user_desc
538# endif
Roland McGrath909875b2002-12-22 03:34:36 +0000539extern void print_ldt_entry();
540# endif
541
Roland McGrath9677b3a2003-03-12 09:54:36 +0000542# if defined IA64
543# define ARG_FLAGS 0
544# define ARG_STACK 1
545# define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
Roland McGrathc03981d2003-03-14 10:32:36 +0000546# define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
547# define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
548# define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000549# elif defined S390 || defined S390X
Roland McGrath9677b3a2003-03-12 09:54:36 +0000550# define ARG_STACK 0
551# define ARG_FLAGS 1
552# define ARG_PTID 2
Roland McGrathfe5fdb22003-05-23 00:29:05 +0000553# define ARG_CTID 3
554# define ARG_TLS 4
Roland McGrath9c555e72003-07-09 09:47:59 +0000555# elif defined X86_64 || defined ALPHA
Roland McGrath361aac52003-03-18 07:43:42 +0000556# define ARG_FLAGS 0
557# define ARG_STACK 1
558# define ARG_PTID 2
559# define ARG_CTID 3
560# define ARG_TLS 4
Roland McGrath9677b3a2003-03-12 09:54:36 +0000561# else
562# define ARG_FLAGS 0
563# define ARG_STACK 1
564# define ARG_PTID 2
565# define ARG_TLS 3
566# define ARG_CTID 4
567# endif
568
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000569int
570sys_clone(tcp)
571struct tcb *tcp;
572{
573 if (exiting(tcp)) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000574 unsigned long flags = tcp->u_arg[ARG_FLAGS];
575 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
576# ifdef ARG_STACKSIZE
577 if (ARG_STACKSIZE != -1)
578 tprintf("stack_size=%#lx, ",
579 tcp->u_arg[ARG_STACKSIZE]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000580# endif
Roland McGrath9677b3a2003-03-12 09:54:36 +0000581 tprintf("flags=");
Roland McGrath984154d2003-05-23 01:08:42 +0000582 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000583 tprintf("0");
Roland McGrath984154d2003-05-23 01:08:42 +0000584 if ((flags & CSIGNAL) != 0)
585 tprintf("|%s", signame(flags & CSIGNAL));
Roland McGrathb4968be2003-01-20 09:04:33 +0000586 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
Roland McGrath9677b3a2003-03-12 09:54:36 +0000587 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
Roland McGrath909875b2002-12-22 03:34:36 +0000588 return 0;
Roland McGrath6f67a982003-03-21 07:33:15 +0000589 if (flags & CLONE_PARENT_SETTID)
590 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
Roland McGrathb4968be2003-01-20 09:04:33 +0000591 if (flags & CLONE_SETTLS) {
Roland McGrath9677b3a2003-03-12 09:54:36 +0000592# ifdef I386
Roland McGrath909875b2002-12-22 03:34:36 +0000593 struct modify_ldt_ldt_s copy;
Roland McGrath9677b3a2003-03-12 09:54:36 +0000594 if (umove(tcp, tcp->u_arg[ARG_TLS], &copy) != -1) {
Roland McGrath909875b2002-12-22 03:34:36 +0000595 tprintf(", {entry_number:%d, ",
596 copy.entry_number);
597 if (!verbose(tcp))
598 tprintf("...}");
599 else
600 print_ldt_entry(&copy);
601 }
602 else
Roland McGrath9677b3a2003-03-12 09:54:36 +0000603# endif
Roland McGrath43f2c842003-03-12 09:58:14 +0000604 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
Roland McGrath909875b2002-12-22 03:34:36 +0000605 }
Roland McGrath9677b3a2003-03-12 09:54:36 +0000606 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
607 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000608 }
609 return 0;
610}
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000611#endif
612
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000613int
614sys_fork(tcp)
615struct tcb *tcp;
616{
617 if (exiting(tcp))
618 return RVAL_UDECIMAL;
619 return 0;
620}
621
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000622int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000623change_syscall(tcp, new)
624struct tcb *tcp;
625int new;
626{
627#if defined(LINUX)
628#if defined(I386)
629 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000630 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000631 return -1;
632 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000633#elif defined(X86_64)
634 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000635 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000636 return -1;
637 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000638#elif defined(POWERPC)
Roland McGratheb285352003-01-14 09:59:00 +0000639 if (ptrace(PTRACE_POKEUSER, tcp->pid,
640 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000641 return -1;
Roland McGrath43b286f2003-01-10 11:14:41 +0000642 return 0;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000643#elif defined(S390) || defined(S390X)
644 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
645 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
646 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000647 return 0;
648#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000649 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000650 return -1;
651 return 0;
Roland McGrath6d1a65c2004-07-12 07:44:08 +0000652#elif defined(SPARC) || defined(SPARC64)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000653 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000654 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
655 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000656 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000657 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
658 return -1;
659 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000660#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000661 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000662 return -1;
663 return 0;
664#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000665 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000666 return -1;
667 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000668#elif defined(IA64)
Roland McGrath08267b82004-02-20 22:56:43 +0000669 if (ia32) {
670 switch (new) {
671 case 2: break; /* x86 SYS_fork */
672 case SYS_clone: new = 120; break;
673 default:
674 fprintf(stderr, "%s: unexpected syscall %d\n",
675 __FUNCTION__, new);
676 return -1;
677 }
678 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
679 return -1;
680 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000681 return -1;
682 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000683#elif defined(HPPA)
684 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
685 return -1;
686 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000687#elif defined(SH)
Roland McGrathac971c22003-03-31 01:03:33 +0000688 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
Wichert Akkermanccef6372002-05-01 16:39:22 +0000689 return -1;
690 return 0;
Roland McGrathf5a47772003-06-26 22:40:42 +0000691#elif defined(SH64)
Roland McGrathe1e584b2003-06-02 19:18:58 +0000692 /* Top half of reg encodes the no. of args n as 0x1n.
693 Assume 0 args as kernel never actually checks... */
694 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
695 0x100000 | new) < 0)
696 return -1;
697 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000698#else
699#warning Do not know how to handle change_syscall for this architecture
700#endif /* architecture */
701#endif /* LINUX */
702 return -1;
703}
704
705int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000706setarg(tcp, argnum)
707 struct tcb *tcp;
708 int argnum;
709{
710#if defined (IA64)
711 {
712 unsigned long *bsp, *ap;
713
714 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
715 return -1;
716
717 ap = ia64_rse_skip_regs(bsp, argnum);
718 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000719 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000720 if (errno)
721 return -1;
722
723 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000724#elif defined(I386)
725 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000726 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000727 if (errno)
728 return -1;
729 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000730#elif defined(X86_64)
731 {
732 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
733 if (errno)
734 return -1;
735 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000736#elif defined(POWERPC)
737#ifndef PT_ORIG_R3
738#define PT_ORIG_R3 34
739#endif
740 {
741 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGratheb285352003-01-14 09:59:00 +0000742 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000743 tcp->u_arg[argnum]);
744 if (errno)
745 return -1;
746 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000747#elif defined(MIPS)
748 {
749 errno = 0;
750 if (argnum < 4)
751 ptrace(PTRACE_POKEUSER, tcp->pid,
752 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
753 else {
754 unsigned long *sp;
755
756 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
757 return -1;
758
759 ptrace(PTRACE_POKEDATA, tcp->pid,
760 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
761 }
762 if (errno)
763 return -1;
764 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000765#elif defined(S390) || defined(S390X)
766 {
767 if(argnum <= 5)
768 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000769 (char *) (argnum==0 ? PT_ORIGGPR2 :
770 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000771 tcp->u_arg[argnum]);
772 else
773 return -E2BIG;
774 if (errno)
775 return -1;
776 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000777#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000778# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000779#endif
780 return 0;
781}
782
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000783#if defined SYS_clone || defined SYS_clone2
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000784int
785internal_clone(tcp)
786struct tcb *tcp;
787{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000788 struct tcb *tcpchild;
789 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000790 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000791 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000792 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000793 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000794 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000795 if (setbpt(tcp) < 0)
796 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000797 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000798 int bpt = tcp->flags & TCB_BPTSET;
799
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000800 if (!(tcp->flags & TCB_FOLLOWFORK))
801 return 0;
802
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000803 if (syserror(tcp)) {
804 if (bpt)
805 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000806 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000807 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000808
809 pid = tcp->u_rval;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000810
811#ifdef CLONE_PTRACE /* See new setbpt code. */
812 tcpchild = pid2tcb(pid);
813 if (tcpchild != NULL) {
814 /* The child already reported its startup trap
815 before the parent reported its syscall return. */
816 if ((tcpchild->flags
817 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
818 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
819 fprintf(stderr, "\
820[preattached child %d of %d in weird state!]\n",
821 pid, tcp->pid);
822 }
823 else
824#endif
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000825 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000826 if (bpt)
827 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000828 fprintf(stderr, " [tcb table full]\n");
829 kill(pid, SIGKILL); /* XXX */
830 return 0;
831 }
832
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000833#ifndef CLONE_PTRACE
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000834 /* Attach to the new child */
835 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000836 if (bpt)
837 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000838 perror("PTRACE_ATTACH");
839 fprintf(stderr, "Too late?\n");
840 droptcb(tcpchild);
841 return 0;
842 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000843#endif
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000844
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000845 if (bpt)
846 clearbpt(tcp);
847
Ulrich Drepper90512f01999-12-24 07:22:25 +0000848 tcpchild->flags |= TCB_ATTACHED;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000849 /* Child has BPT too, must be removed on first occasion. */
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000850 if (bpt) {
851 tcpchild->flags |= TCB_BPTSET;
852 tcpchild->baddr = tcp->baddr;
853 memcpy(tcpchild->inst, tcp->inst,
854 sizeof tcpchild->inst);
855 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000856 tcpchild->parent = tcp;
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000857 tcp->nchildren++;
858 if (tcpchild->flags & TCB_SUSPENDED) {
859 /* The child was born suspended, due to our having
860 forced CLONE_PTRACE. */
861 if (bpt)
862 clearbpt(tcpchild);
863
864 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
865 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
866 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
867 return -1;
868 }
869
870 if (!qflag)
871 fprintf(stderr, "\
872Process %u resumed (parent %d ready)\n",
873 pid, tcp->pid);
874 }
875 else {
876 newoutf(tcpchild);
877 if (!qflag)
878 fprintf(stderr, "Process %d attached\n", pid);
879 }
880
881#ifdef TCB_CLONE_THREAD
Roland McGrath984154d2003-05-23 01:08:42 +0000882 {
883 /*
884 * Save the flags used in this call,
885 * in case we point TCP to our parent below.
886 */
887 int call_flags = tcp->u_arg[ARG_FLAGS];
888 if ((tcp->flags & TCB_CLONE_THREAD) &&
889 tcp->parent != NULL) {
890 /* The parent in this clone is itself a
891 thread belonging to another process.
892 There is no meaning to the parentage
893 relationship of the new child with the
894 thread, only with the process. We
895 associate the new thread with our
896 parent. Since this is done for every
897 new thread, there will never be a
898 TCB_CLONE_THREAD process that has
899 children. */
900 --tcp->nchildren;
901 tcp = tcp->parent;
902 tcpchild->parent = tcp;
903 ++tcp->nchildren;
904 }
905 if (call_flags & CLONE_THREAD) {
906 tcpchild->flags |= TCB_CLONE_THREAD;
907 ++tcp->nclone_threads;
908 }
909 if (call_flags & CLONE_DETACHED) {
910 tcpchild->flags |= TCB_CLONE_DETACHED;
911 ++tcp->nclone_detached;
912 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000913 }
914#endif
915
916 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000917 return 0;
918}
919#endif
920
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000921int
922internal_fork(tcp)
923struct tcb *tcp;
924{
Roland McGrathe85bbfe2003-01-09 06:53:31 +0000925#ifdef LINUX
926 /* We do special magic with clone for any clone or fork. */
927 return internal_clone(tcp);
928#else
929
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000930 struct tcb *tcpchild;
931 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000932 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000933
934#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000935 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000936 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000937 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000938 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000939 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000940 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000941#endif
942 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000943 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000944 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000945 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000946 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000947 if (setbpt(tcp) < 0)
948 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000949 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000950 else {
951 int bpt = tcp->flags & TCB_BPTSET;
952
953 if (!(tcp->flags & TCB_FOLLOWFORK))
954 return 0;
955 if (bpt)
956 clearbpt(tcp);
957
958 if (syserror(tcp))
959 return 0;
960
961 pid = tcp->u_rval;
962 if ((tcpchild = alloctcb(pid)) == NULL) {
963 fprintf(stderr, " [tcb table full]\n");
964 kill(pid, SIGKILL); /* XXX */
965 return 0;
966 }
967#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000968#ifdef HPPA
969 /* The child must have run before it can be attached. */
970 /* This must be a bug in the parisc kernel, but I havn't
971 * identified it yet. Seems to be an issue associated
972 * with attaching to a process (which sends it a signal)
973 * before that process has ever been scheduled. When
974 * debugging, I started seeing crashes in
975 * arch/parisc/kernel/signal.c:do_signal(), apparently
976 * caused by r8 getting corrupt over the dequeue_signal()
977 * call. Didn't make much sense though...
978 */
979 {
980 struct timeval tv;
981 tv.tv_sec = 0;
982 tv.tv_usec = 10000;
983 select(0, NULL, NULL, NULL, &tv);
984 }
985#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000986 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
987 perror("PTRACE_ATTACH");
988 fprintf(stderr, "Too late?\n");
989 droptcb(tcpchild);
990 return 0;
991 }
992#endif /* LINUX */
993#ifdef SUNOS4
994#ifdef oldway
995 /* The child must have run before it can be attached. */
996 {
997 struct timeval tv;
998 tv.tv_sec = 0;
999 tv.tv_usec = 10000;
1000 select(0, NULL, NULL, NULL, &tv);
1001 }
1002 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1003 perror("PTRACE_ATTACH");
1004 fprintf(stderr, "Too late?\n");
1005 droptcb(tcpchild);
1006 return 0;
1007 }
1008#else /* !oldway */
1009 /* Try to catch the new process as soon as possible. */
1010 {
1011 int i;
1012 for (i = 0; i < 1024; i++)
1013 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1014 break;
1015 if (i == 1024) {
1016 perror("PTRACE_ATTACH");
1017 fprintf(stderr, "Too late?\n");
1018 droptcb(tcpchild);
1019 return 0;
1020 }
1021 }
1022#endif /* !oldway */
1023#endif /* SUNOS4 */
1024 tcpchild->flags |= TCB_ATTACHED;
1025 /* Child has BPT too, must be removed on first occasion */
1026 if (bpt) {
1027 tcpchild->flags |= TCB_BPTSET;
1028 tcpchild->baddr = tcp->baddr;
1029 memcpy(tcpchild->inst, tcp->inst,
1030 sizeof tcpchild->inst);
1031 }
1032 newoutf(tcpchild);
1033 tcpchild->parent = tcp;
1034 tcp->nchildren++;
1035 if (!qflag)
1036 fprintf(stderr, "Process %d attached\n", pid);
1037 }
1038 return 0;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001039#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001040}
1041
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001042#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001043
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001044#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001045
1046int
1047sys_vfork(tcp)
1048struct tcb *tcp;
1049{
1050 if (exiting(tcp))
1051 return RVAL_UDECIMAL;
1052 return 0;
1053}
1054
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001055#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001056
1057#ifndef LINUX
1058
1059static char idstr[16];
1060
1061int
1062sys_getpid(tcp)
1063struct tcb *tcp;
1064{
1065 if (exiting(tcp)) {
1066 sprintf(idstr, "ppid %lu", getrval2(tcp));
1067 tcp->auxstr = idstr;
1068 return RVAL_STR;
1069 }
1070 return 0;
1071}
1072
1073int
1074sys_getuid(tcp)
1075struct tcb *tcp;
1076{
1077 if (exiting(tcp)) {
1078 sprintf(idstr, "euid %lu", getrval2(tcp));
1079 tcp->auxstr = idstr;
1080 return RVAL_STR;
1081 }
1082 return 0;
1083}
1084
1085int
1086sys_getgid(tcp)
1087struct tcb *tcp;
1088{
1089 if (exiting(tcp)) {
1090 sprintf(idstr, "egid %lu", getrval2(tcp));
1091 tcp->auxstr = idstr;
1092 return RVAL_STR;
1093 }
1094 return 0;
1095}
1096
1097#endif /* !LINUX */
1098
1099#ifdef LINUX
1100
1101int
1102sys_setuid(tcp)
1103struct tcb *tcp;
1104{
1105 if (entering(tcp)) {
1106 tprintf("%u", (uid_t) tcp->u_arg[0]);
1107 }
1108 return 0;
1109}
1110
1111int
1112sys_setgid(tcp)
1113struct tcb *tcp;
1114{
1115 if (entering(tcp)) {
1116 tprintf("%u", (gid_t) tcp->u_arg[0]);
1117 }
1118 return 0;
1119}
1120
1121int
1122sys_getresuid(tcp)
1123 struct tcb *tcp;
1124{
1125 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001126 __kernel_uid_t uid;
1127 if (syserror(tcp))
1128 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1129 tcp->u_arg[1], tcp->u_arg[2]);
1130 else {
1131 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1132 tprintf("%#lx, ", tcp->u_arg[0]);
1133 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001134 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001135 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1136 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001137 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001138 tprintf("[%lu], ", (unsigned long) uid);
Roland McGrath9bd6b422003-02-24 07:13:51 +00001139 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1140 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001141 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001142 tprintf("[%lu]", (unsigned long) uid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001143 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001144 }
1145 return 0;
1146}
1147
1148int
1149sys_getresgid(tcp)
1150struct tcb *tcp;
1151{
1152 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001153 __kernel_gid_t gid;
1154 if (syserror(tcp))
1155 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1156 tcp->u_arg[1], tcp->u_arg[2]);
1157 else {
1158 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1159 tprintf("%#lx, ", tcp->u_arg[0]);
1160 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001161 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001162 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1163 tprintf("%#lx, ", tcp->u_arg[1]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001164 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001165 tprintf("[%lu], ", (unsigned long) gid);
Roland McGrathd2450922003-02-24 10:18:07 +00001166 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1167 tprintf("%#lx", tcp->u_arg[2]);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001168 else
Roland McGrath83bd47a2003-11-13 22:32:26 +00001169 tprintf("[%lu]", (unsigned long) gid);
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001170 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001171 }
1172 return 0;
1173}
1174
1175#endif /* LINUX */
1176
1177int
1178sys_setreuid(tcp)
1179struct tcb *tcp;
1180{
1181 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001182 printuid("", tcp->u_arg[0]);
1183 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001184 }
1185 return 0;
1186}
1187
1188int
1189sys_setregid(tcp)
1190struct tcb *tcp;
1191{
1192 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001193 printuid("", tcp->u_arg[0]);
1194 printuid(", ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001195 }
1196 return 0;
1197}
1198
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001199#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001200int
1201sys_setresuid(tcp)
1202 struct tcb *tcp;
1203{
1204 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001205 printuid("", tcp->u_arg[0]);
1206 printuid(", ", tcp->u_arg[1]);
1207 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001208 }
1209 return 0;
1210}
1211int
1212sys_setresgid(tcp)
1213 struct tcb *tcp;
1214{
1215 if (entering(tcp)) {
Roland McGrath83bd47a2003-11-13 22:32:26 +00001216 printuid("", tcp->u_arg[0]);
1217 printuid(", ", tcp->u_arg[1]);
1218 printuid(", ", tcp->u_arg[2]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001219 }
1220 return 0;
1221}
1222
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001223#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001224
1225int
1226sys_setgroups(tcp)
1227struct tcb *tcp;
1228{
1229 int i, len;
1230 GETGROUPS_T *gidset;
1231
1232 if (entering(tcp)) {
1233 len = tcp->u_arg[0];
1234 tprintf("%u, ", len);
1235 if (len <= 0) {
1236 tprintf("[]");
1237 return 0;
1238 }
1239 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1240 if (gidset == NULL) {
1241 fprintf(stderr, "sys_setgroups: out of memory\n");
1242 return -1;
1243 }
1244 if (!verbose(tcp))
1245 tprintf("%#lx", tcp->u_arg[1]);
1246 else if (umoven(tcp, tcp->u_arg[1],
1247 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1248 tprintf("[?]");
1249 else {
1250 tprintf("[");
1251 for (i = 0; i < len; i++)
1252 tprintf("%s%lu", i ? ", " : "",
1253 (unsigned long) gidset[i]);
1254 tprintf("]");
1255 }
1256 free((char *) gidset);
1257 }
1258 return 0;
1259}
1260
1261int
1262sys_getgroups(tcp)
1263struct tcb *tcp;
1264{
1265 int i, len;
1266 GETGROUPS_T *gidset;
1267
1268 if (entering(tcp)) {
1269 len = tcp->u_arg[0];
1270 tprintf("%u, ", len);
1271 } else {
1272 len = tcp->u_rval;
1273 if (len <= 0) {
1274 tprintf("[]");
1275 return 0;
1276 }
1277 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1278 if (gidset == NULL) {
1279 fprintf(stderr, "sys_getgroups: out of memory\n");
1280 return -1;
1281 }
1282 if (!tcp->u_arg[1])
1283 tprintf("NULL");
1284 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1285 tprintf("%#lx", tcp->u_arg[1]);
1286 else if (umoven(tcp, tcp->u_arg[1],
1287 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1288 tprintf("[?]");
1289 else {
1290 tprintf("[");
1291 for (i = 0; i < len; i++)
1292 tprintf("%s%lu", i ? ", " : "",
1293 (unsigned long) gidset[i]);
1294 tprintf("]");
1295 }
1296 free((char *)gidset);
1297 }
1298 return 0;
1299}
1300
Roland McGrath83bd47a2003-11-13 22:32:26 +00001301#ifdef LINUX
1302int
1303sys_setgroups32(tcp)
1304struct tcb *tcp;
1305{
1306 int i, len;
1307 GETGROUPS32_T *gidset;
1308
1309 if (entering(tcp)) {
1310 len = tcp->u_arg[0];
1311 tprintf("%u, ", len);
1312 if (len <= 0) {
1313 tprintf("[]");
1314 return 0;
1315 }
1316 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1317 if (gidset == NULL) {
1318 fprintf(stderr, "sys_setgroups32: out of memory\n");
1319 return -1;
1320 }
1321 if (!verbose(tcp))
1322 tprintf("%#lx", tcp->u_arg[1]);
1323 else if (umoven(tcp, tcp->u_arg[1],
1324 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1325 tprintf("[?]");
1326 else {
1327 tprintf("[");
1328 for (i = 0; i < len; i++)
1329 tprintf("%s%lu", i ? ", " : "",
1330 (unsigned long) gidset[i]);
1331 tprintf("]");
1332 }
1333 free((char *) gidset);
1334 }
1335 return 0;
1336}
1337
1338int
1339sys_getgroups32(tcp)
1340struct tcb *tcp;
1341{
1342 int i, len;
1343 GETGROUPS32_T *gidset;
1344
1345 if (entering(tcp)) {
1346 len = tcp->u_arg[0];
1347 tprintf("%u, ", len);
1348 } else {
1349 len = tcp->u_rval;
1350 if (len <= 0) {
1351 tprintf("[]");
1352 return 0;
1353 }
1354 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1355 if (gidset == NULL) {
1356 fprintf(stderr, "sys_getgroups32: out of memory\n");
1357 return -1;
1358 }
1359 if (!tcp->u_arg[1])
1360 tprintf("NULL");
1361 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1362 tprintf("%#lx", tcp->u_arg[1]);
1363 else if (umoven(tcp, tcp->u_arg[1],
1364 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1365 tprintf("[?]");
1366 else {
1367 tprintf("[");
1368 for (i = 0; i < len; i++)
1369 tprintf("%s%lu", i ? ", " : "",
1370 (unsigned long) gidset[i]);
1371 tprintf("]");
1372 }
1373 free((char *)gidset);
1374 }
1375 return 0;
1376}
1377#endif /* LINUX */
1378
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001379int
1380sys_setpgrp(tcp)
1381struct tcb *tcp;
1382{
1383 if (entering(tcp)) {
1384#ifndef SVR4
1385 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1386#endif /* !SVR4 */
1387 }
1388 return 0;
1389}
1390
1391int
1392sys_getpgrp(tcp)
1393struct tcb *tcp;
1394{
1395 if (entering(tcp)) {
1396#ifndef SVR4
1397 tprintf("%lu", tcp->u_arg[0]);
1398#endif /* !SVR4 */
1399 }
1400 return 0;
1401}
1402
1403int
1404sys_getsid(tcp)
1405struct tcb *tcp;
1406{
1407 if (entering(tcp)) {
1408 tprintf("%lu", tcp->u_arg[0]);
1409 }
1410 return 0;
1411}
1412
1413int
1414sys_setsid(tcp)
1415struct tcb *tcp;
1416{
1417 return 0;
1418}
1419
1420int
1421sys_getpgid(tcp)
1422struct tcb *tcp;
1423{
1424 if (entering(tcp)) {
1425 tprintf("%lu", tcp->u_arg[0]);
1426 }
1427 return 0;
1428}
1429
1430int
1431sys_setpgid(tcp)
1432struct tcb *tcp;
1433{
1434 if (entering(tcp)) {
1435 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1436 }
1437 return 0;
1438}
1439
John Hughesc61eb3d2002-05-17 11:37:50 +00001440#if UNIXWARE >= 2
1441
1442#include <sys/privilege.h>
1443
1444
Roland McGrathd9f816f2004-09-04 03:39:20 +00001445static const struct xlat procpriv_cmds [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001446 { SETPRV, "SETPRV" },
1447 { CLRPRV, "CLRPRV" },
1448 { PUTPRV, "PUTPRV" },
1449 { GETPRV, "GETPRV" },
1450 { CNTPRV, "CNTPRV" },
1451 { 0, NULL },
1452};
1453
1454
Roland McGrathd9f816f2004-09-04 03:39:20 +00001455static const struct xlat procpriv_priv [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001456 { P_OWNER, "P_OWNER" },
1457 { P_AUDIT, "P_AUDIT" },
1458 { P_COMPAT, "P_COMPAT" },
1459 { P_DACREAD, "P_DACREAD" },
1460 { P_DACWRITE, "P_DACWRITE" },
1461 { P_DEV, "P_DEV" },
1462 { P_FILESYS, "P_FILESYS" },
1463 { P_MACREAD, "P_MACREAD" },
1464 { P_MACWRITE, "P_MACWRITE" },
1465 { P_MOUNT, "P_MOUNT" },
1466 { P_MULTIDIR, "P_MULTIDIR" },
1467 { P_SETPLEVEL, "P_SETPLEVEL" },
1468 { P_SETSPRIV, "P_SETSPRIV" },
1469 { P_SETUID, "P_SETUID" },
1470 { P_SYSOPS, "P_SYSOPS" },
1471 { P_SETUPRIV, "P_SETUPRIV" },
1472 { P_DRIVER, "P_DRIVER" },
1473 { P_RTIME, "P_RTIME" },
1474 { P_MACUPGRADE, "P_MACUPGRADE" },
1475 { P_FSYSRANGE, "P_FSYSRANGE" },
1476 { P_SETFLEVEL, "P_SETFLEVEL" },
1477 { P_AUDITWR, "P_AUDITWR" },
1478 { P_TSHAR, "P_TSHAR" },
1479 { P_PLOCK, "P_PLOCK" },
1480 { P_CORE, "P_CORE" },
1481 { P_LOADMOD, "P_LOADMOD" },
1482 { P_BIND, "P_BIND" },
1483 { P_ALLPRIVS, "P_ALLPRIVS" },
1484 { 0, NULL },
1485};
1486
1487
Roland McGrathd9f816f2004-09-04 03:39:20 +00001488static const struct xlat procpriv_type [] = {
John Hughesc61eb3d2002-05-17 11:37:50 +00001489 { PS_FIX, "PS_FIX" },
1490 { PS_INH, "PS_INH" },
1491 { PS_MAX, "PS_MAX" },
1492 { PS_WKG, "PS_WKG" },
1493 { 0, NULL },
1494};
1495
1496
1497static void
1498printpriv(tcp, addr, len, opt)
1499struct tcb *tcp;
1500long addr;
1501int len;
Roland McGrathd9f816f2004-09-04 03:39:20 +00001502const struct xlat *opt;
John Hughesc61eb3d2002-05-17 11:37:50 +00001503{
1504 priv_t buf [128];
1505 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1506 int dots = len > max;
1507 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001508
John Hughesc61eb3d2002-05-17 11:37:50 +00001509 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001510
John Hughesc61eb3d2002-05-17 11:37:50 +00001511 if (len <= 0 ||
1512 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1513 {
1514 tprintf ("%#lx", addr);
1515 return;
1516 }
1517
1518 tprintf ("[");
1519
1520 for (i = 0; i < len; ++i) {
1521 char *t, *p;
1522
1523 if (i) tprintf (", ");
1524
1525 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1526 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1527 {
1528 tprintf ("%s|%s", t, p);
1529 }
1530 else {
1531 tprintf ("%#lx", buf [i]);
1532 }
1533 }
1534
1535 if (dots) tprintf (" ...");
1536
1537 tprintf ("]");
1538}
1539
1540
1541int
1542sys_procpriv(tcp)
1543struct tcb *tcp;
1544{
1545 if (entering(tcp)) {
1546 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1547 switch (tcp->u_arg[0]) {
1548 case CNTPRV:
1549 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1550 break;
1551
1552 case GETPRV:
1553 break;
1554
1555 default:
1556 tprintf (", ");
1557 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1558 tprintf (", %ld", tcp->u_arg[2]);
1559 }
1560 }
1561 else if (tcp->u_arg[0] == GETPRV) {
1562 if (syserror (tcp)) {
1563 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1564 }
1565 else {
1566 tprintf (", ");
1567 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1568 tprintf (", %ld", tcp->u_arg[2]);
1569 }
1570 }
Roland McGrath5a223472002-12-15 23:58:26 +00001571
John Hughesc61eb3d2002-05-17 11:37:50 +00001572 return 0;
1573}
1574
1575#endif
1576
1577
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001578void
1579fake_execve(tcp, program, argv, envp)
1580struct tcb *tcp;
1581char *program;
1582char *argv[];
1583char *envp[];
1584{
1585 int i;
1586
1587#ifdef ARM
1588 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1589 return;
1590#else
1591 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1592 return;
1593#endif /* !ARM */
1594 printleader(tcp);
1595 tprintf("execve(");
1596 string_quote(program);
1597 tprintf(", [");
1598 for (i = 0; argv[i] != NULL; i++) {
1599 if (i != 0)
1600 tprintf(", ");
1601 string_quote(argv[i]);
1602 }
1603 for (i = 0; envp[i] != NULL; i++)
1604 ;
1605 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1606 tabto(acolumn);
1607 tprintf("= 0");
1608 printtrailer(tcp);
1609}
1610
1611static void
1612printargv(tcp, addr)
1613struct tcb *tcp;
1614long addr;
1615{
1616 char *cp;
1617 char *sep;
1618 int max = max_strlen / 2;
1619
1620 for (sep = ""; --max >= 0; sep = ", ") {
1621 if (!abbrev(tcp))
1622 max++;
1623 if (umove(tcp, addr, &cp) < 0) {
1624 tprintf("%#lx", addr);
1625 return;
1626 }
1627 if (cp == 0)
1628 break;
1629 tprintf(sep);
1630 printstr(tcp, (long) cp, -1);
1631 addr += sizeof(char *);
1632 }
1633 if (cp)
1634 tprintf(", ...");
1635}
1636
1637static void
1638printargc(fmt, tcp, addr)
1639char *fmt;
1640struct tcb *tcp;
1641long addr;
1642{
1643 int count;
1644 char *cp;
1645
1646 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1647 addr += sizeof(char *);
1648 }
1649 tprintf(fmt, count, count == 1 ? "" : "s");
1650}
1651
1652int
1653sys_execv(tcp)
1654struct tcb *tcp;
1655{
1656 if (entering(tcp)) {
1657 printpath(tcp, tcp->u_arg[0]);
1658 if (!verbose(tcp))
1659 tprintf(", %#lx", tcp->u_arg[1]);
1660#if 0
1661 else if (abbrev(tcp))
1662 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1663#endif
1664 else {
1665 tprintf(", [");
1666 printargv(tcp, tcp->u_arg[1]);
1667 tprintf("]");
1668 }
1669 }
1670 return 0;
1671}
1672
1673int
1674sys_execve(tcp)
1675struct tcb *tcp;
1676{
1677 if (entering(tcp)) {
1678 printpath(tcp, tcp->u_arg[0]);
1679 if (!verbose(tcp))
1680 tprintf(", %#lx", tcp->u_arg[1]);
1681#if 0
1682 else if (abbrev(tcp))
1683 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1684#endif
1685 else {
1686 tprintf(", [");
1687 printargv(tcp, tcp->u_arg[1]);
1688 tprintf("]");
1689 }
1690 if (!verbose(tcp))
1691 tprintf(", %#lx", tcp->u_arg[2]);
1692 else if (abbrev(tcp))
1693 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1694 else {
1695 tprintf(", [");
1696 printargv(tcp, tcp->u_arg[2]);
1697 tprintf("]");
1698 }
1699 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001700 return 0;
1701}
1702
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001703#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001704
1705int sys_rexecve(tcp)
1706struct tcb *tcp;
1707{
1708 if (entering (tcp)) {
1709 sys_execve (tcp);
1710 tprintf (", %ld", tcp->u_arg[3]);
1711 }
1712 return 0;
1713}
1714
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001715#endif
John Hughes4e36a812001-04-18 15:11:51 +00001716
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001717int
1718internal_exec(tcp)
1719struct tcb *tcp;
1720{
1721#ifdef SUNOS4
1722 if (exiting(tcp) && !syserror(tcp) && followfork)
1723 fixvfork(tcp);
1724#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001725#if defined LINUX && defined TCB_WAITEXECVE
1726 if (exiting(tcp) && syserror(tcp))
1727 tcp->flags &= ~TCB_WAITEXECVE;
1728 else
1729 tcp->flags |= TCB_WAITEXECVE;
1730#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001731 return 0;
1732}
1733
1734#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001735#ifndef __WNOTHREAD
1736#define __WNOTHREAD 0x20000000
1737#endif
1738#ifndef __WALL
1739#define __WALL 0x40000000
1740#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001741#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001742#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743#endif
1744#endif /* LINUX */
1745
Roland McGrathd9f816f2004-09-04 03:39:20 +00001746static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001747 { WNOHANG, "WNOHANG" },
1748#ifndef WSTOPPED
1749 { WUNTRACED, "WUNTRACED" },
1750#endif
1751#ifdef WEXITED
1752 { WEXITED, "WEXITED" },
1753#endif
1754#ifdef WTRAPPED
1755 { WTRAPPED, "WTRAPPED" },
1756#endif
1757#ifdef WSTOPPED
1758 { WSTOPPED, "WSTOPPED" },
1759#endif
1760#ifdef WCONTINUED
1761 { WCONTINUED, "WCONTINUED" },
1762#endif
1763#ifdef WNOWAIT
1764 { WNOWAIT, "WNOWAIT" },
1765#endif
1766#ifdef __WCLONE
1767 { __WCLONE, "__WCLONE" },
1768#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001769#ifdef __WALL
1770 { __WALL, "__WALL" },
1771#endif
1772#ifdef __WNOTHREAD
1773 { __WNOTHREAD, "__WNOTHREAD" },
1774#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001775 { 0, NULL },
1776};
1777
Roland McGrath5e02a572004-10-19 23:33:47 +00001778#if !defined WCOREFLAG && defined WCOREFLG
1779# define WCOREFLAG WCOREFLG
1780#endif
1781#ifndef WCOREFLAG
1782#define WCOREFLAG 0x80
1783#endif
1784
1785#ifndef W_STOPCODE
1786#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1787#endif
1788#ifndef W_EXITCODE
1789#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1790#endif
1791
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001792static int
1793printstatus(status)
1794int status;
1795{
1796 int exited = 0;
1797
1798 /*
1799 * Here is a tricky presentation problem. This solution
1800 * is still not entirely satisfactory but since there
1801 * are no wait status constructors it will have to do.
1802 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001803 if (WIFSTOPPED(status)) {
1804 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001805 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001806 status &= ~W_STOPCODE(WSTOPSIG(status));
1807 }
1808 else if (WIFSIGNALED(status)) {
1809 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001810 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001811 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001812 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1813 }
1814 else if (WIFEXITED(status)) {
1815 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001816 WEXITSTATUS(status));
1817 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001818 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001819 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001820 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001821 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001822 return 0;
1823 }
1824
1825 if (status == 0)
1826 tprintf("]");
1827 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001828 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001829
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001830 return exited;
1831}
1832
1833static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001834printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001835struct tcb *tcp;
1836int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001837int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001838{
1839 int status;
1840 int exited = 0;
1841
1842 if (entering(tcp)) {
1843 tprintf("%ld, ", tcp->u_arg[0]);
1844 } else {
1845 /* status */
1846 if (!tcp->u_arg[1])
1847 tprintf("NULL");
1848 else if (syserror(tcp) || tcp->u_rval == 0)
1849 tprintf("%#lx", tcp->u_arg[1]);
1850 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1851 tprintf("[?]");
1852 else
1853 exited = printstatus(status);
1854 /* options */
1855 tprintf(", ");
1856 if (!printflags(wait4_options, tcp->u_arg[2]))
1857 tprintf("0");
1858 if (n == 4) {
1859 tprintf(", ");
1860 /* usage */
1861 if (!tcp->u_arg[3])
1862 tprintf("NULL");
1863#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001864 else if (tcp->u_rval > 0) {
1865#ifdef LINUX_64BIT
1866 if (bitness)
1867 printrusage32(tcp, tcp->u_arg[3]);
1868 else
1869#endif
1870 printrusage(tcp, tcp->u_arg[3]);
1871 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001872#endif /* LINUX */
1873#ifdef SUNOS4
1874 else if (tcp->u_rval > 0 && exited)
1875 printrusage(tcp, tcp->u_arg[3]);
1876#endif /* SUNOS4 */
1877 else
1878 tprintf("%#lx", tcp->u_arg[3]);
1879 }
1880 }
1881 return 0;
1882}
1883
1884int
Roland McGrathc74c0b72004-09-01 19:39:46 +00001885internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001886struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00001887int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001888{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001889 int got_kids;
1890
1891#ifdef TCB_CLONE_THREAD
1892 if (tcp->flags & TCB_CLONE_THREAD)
1893 /* The children we wait for are our parent's children. */
1894 got_kids = (tcp->parent->nchildren
1895 > tcp->parent->nclone_detached);
1896 else
1897 got_kids = (tcp->nchildren > tcp->nclone_detached);
1898#else
1899 got_kids = tcp->nchildren > 0;
1900#endif
1901
1902 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001903 /* There are children that this parent should block for.
1904 But ptrace made us the parent of the traced children
1905 and the real parent will get ECHILD from the wait call.
1906
1907 XXX If we attached with strace -f -p PID, then there
1908 may be untraced dead children the parent could be reaping
1909 now, but we make him block. */
1910
1911 /* ??? WTA: fix bug with hanging children */
1912
Roland McGrathc74c0b72004-09-01 19:39:46 +00001913 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001914 /*
1915 * There are traced children. We'll make the parent
1916 * block to avoid a false ECHILD error due to our
1917 * ptrace having stolen the children. However,
1918 * we shouldn't block if there are zombies to reap.
1919 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1920 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001921 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001922 if (tcp->nzombies > 0 &&
1923 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001924 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001925 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001926 if (tcp->u_arg[0] > 0) {
1927 /*
1928 * If the parent waits for a specified child
1929 * PID, then it must get ECHILD right away
1930 * if that PID is not one of its children.
1931 * Make sure that the requested PID matches
1932 * one of the parent's children that we are
1933 * tracing, and don't suspend it otherwise.
1934 */
1935 if (child == NULL)
1936 child = pid2tcb(tcp->u_arg[0]);
1937 if (child == NULL || child->parent != (
1938#ifdef TCB_CLONE_THREAD
1939 (tcp->flags & TCB_CLONE_THREAD)
1940 ? tcp->parent :
1941#endif
1942 tcp))
1943 return 0;
1944 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001945 tcp->flags |= TCB_SUSPENDED;
1946 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001947#ifdef TCB_CLONE_THREAD
1948 if (tcp->flags & TCB_CLONE_THREAD)
1949 tcp->parent->nclone_waiting++;
1950#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001951 }
1952 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001953 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00001954 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001955 /* We must force a fake result of 0 instead of
1956 the ECHILD error. */
1957 extern int force_result();
1958 return force_result(tcp, 0, 0);
1959 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001960 }
Roland McGrath09623452003-05-23 02:27:13 +00001961 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1962 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1963 /*
1964 * We just reaped a child we don't know about,
1965 * presumably a zombie we already droptcb'd.
1966 */
1967 tcp->nzombies--;
1968 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001969 return 0;
1970}
1971
1972#ifdef SVR4
1973
1974int
1975sys_wait(tcp)
1976struct tcb *tcp;
1977{
1978 if (exiting(tcp)) {
1979 /* The library wrapper stuffs this into the user variable. */
1980 if (!syserror(tcp))
1981 printstatus(getrval2(tcp));
1982 }
1983 return 0;
1984}
1985
1986#endif /* SVR4 */
1987
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001988#ifdef FREEBSD
1989int
1990sys_wait(tcp)
1991struct tcb *tcp;
1992{
1993 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001994
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001995 if (exiting(tcp)) {
1996 if (!syserror(tcp)) {
1997 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1998 tprintf("%#lx", tcp->u_arg[0]);
1999 else
2000 printstatus(status);
2001 }
2002 }
2003 return 0;
2004}
2005#endif
2006
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002007int
2008sys_waitpid(tcp)
2009struct tcb *tcp;
2010{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002011 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002012}
2013
2014int
2015sys_wait4(tcp)
2016struct tcb *tcp;
2017{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002018 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002019}
2020
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00002021#ifdef ALPHA
2022int
2023sys_osf_wait4(tcp)
2024struct tcb *tcp;
2025{
2026 return printwaitn(tcp, 4, 1);
2027}
2028#endif
2029
Roland McGrathc74c0b72004-09-01 19:39:46 +00002030#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002031
Roland McGrathd9f816f2004-09-04 03:39:20 +00002032static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002033 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002034#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002035 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002036#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002037 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002038#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002039 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002040#endif
2041#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002042 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002043#endif
2044#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002045 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002046#endif
2047#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002048 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002049#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002050 { P_ALL, "P_ALL" },
2051#ifdef P_LWPID
2052 { P_LWPID, "P_LWPID" },
2053#endif
2054 { 0, NULL },
2055};
2056
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002057int
2058sys_waitid(tcp)
2059struct tcb *tcp;
2060{
2061 siginfo_t si;
2062 int exited;
2063
2064 if (entering(tcp)) {
2065 printxval(waitid_types, tcp->u_arg[0], "P_???");
2066 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002067 }
2068 else {
2069 /* siginfo */
2070 exited = 0;
2071 if (!tcp->u_arg[2])
2072 tprintf("NULL");
2073 else if (syserror(tcp))
2074 tprintf("%#lx", tcp->u_arg[2]);
2075 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2076 tprintf("{???}");
2077 else
John Hughes58265892001-10-18 15:13:53 +00002078 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002079 /* options */
2080 tprintf(", ");
2081 if (!printflags(wait4_options, tcp->u_arg[3]))
2082 tprintf("0");
Roland McGrath39426a32004-10-06 22:02:59 +00002083 if (tcp->u_nargs > 4) {
2084 /* usage */
2085 tprintf(", ");
2086 if (!tcp->u_arg[4])
2087 tprintf("NULL");
2088 else if (tcp->u_error)
2089 tprintf("%#lx", tcp->u_arg[4]);
2090 else
2091 printrusage(tcp, tcp->u_arg[4]);
2092 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002093 }
2094 return 0;
2095}
2096
Roland McGrathc74c0b72004-09-01 19:39:46 +00002097#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002098
2099int
2100sys_alarm(tcp)
2101struct tcb *tcp;
2102{
2103 if (entering(tcp))
2104 tprintf("%lu", tcp->u_arg[0]);
2105 return 0;
2106}
2107
2108int
2109sys_uname(tcp)
2110struct tcb *tcp;
2111{
2112 struct utsname uname;
2113
2114 if (exiting(tcp)) {
2115 if (syserror(tcp) || !verbose(tcp))
2116 tprintf("%#lx", tcp->u_arg[0]);
2117 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2118 tprintf("{...}");
2119 else if (!abbrev(tcp)) {
2120
2121 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2122 uname.sysname, uname.nodename);
2123 tprintf("release=\"%s\", version=\"%s\", ",
2124 uname.release, uname.version);
2125 tprintf("machine=\"%s\"", uname.machine);
2126#ifdef LINUX
2127#ifndef __GLIBC__
2128 tprintf(", domainname=\"%s\"", uname.domainname);
2129#endif /* __GLIBC__ */
2130#endif /* LINUX */
2131 tprintf("}");
2132 }
2133 else
2134 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2135 uname.sysname, uname.nodename);
2136 }
2137 return 0;
2138}
2139
2140#ifndef SVR4
2141
Roland McGrathd9f816f2004-09-04 03:39:20 +00002142static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002143#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002144 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2145 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2146 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2147 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2148 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2149 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2150 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2151 { PTRACE_CONT, "PTRACE_CONT" },
2152 { PTRACE_KILL, "PTRACE_KILL" },
2153 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2154 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2155 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002156#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002157 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002158#endif
2159#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002160 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002161#endif
2162#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002163 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002164#endif
2165#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002166 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002167#endif
2168#ifdef PTRACE_GETFPXREGS
2169 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2170#endif
2171#ifdef PTRACE_SETFPXREGS
2172 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2173#endif
2174#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002175 { PTRACE_READDATA, "PTRACE_READDATA" },
2176 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2177 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2178 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2179 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2180 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2181#ifdef SPARC
2182 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2183 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2184#else /* !SPARC */
2185 { PTRACE_22, "PTRACE_PTRACE_22" },
2186 { PTRACE_23, "PTRACE_PTRACE_23" },
2187#endif /* !SPARC */
2188#endif /* SUNOS4 */
2189 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2190#ifdef SUNOS4
2191 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2192#ifdef I386
2193 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2194 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2195 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2196#else /* !I386 */
2197 { PTRACE_26, "PTRACE_26" },
2198 { PTRACE_27, "PTRACE_27" },
2199 { PTRACE_28, "PTRACE_28" },
2200#endif /* !I386 */
2201 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2202#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002203#else /* FREEBSD */
2204 { PT_TRACE_ME, "PT_TRACE_ME" },
2205 { PT_READ_I, "PT_READ_I" },
2206 { PT_READ_D, "PT_READ_D" },
2207 { PT_WRITE_I, "PT_WRITE_I" },
2208 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002209#ifdef PT_READ_U
2210 { PT_READ_U, "PT_READ_U" },
2211#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002212 { PT_CONTINUE, "PT_CONTINUE" },
2213 { PT_KILL, "PT_KILL" },
2214 { PT_STEP, "PT_STEP" },
2215 { PT_ATTACH, "PT_ATTACH" },
2216 { PT_DETACH, "PT_DETACH" },
2217 { PT_GETREGS, "PT_GETREGS" },
2218 { PT_SETREGS, "PT_SETREGS" },
2219 { PT_GETFPREGS, "PT_GETFPREGS" },
2220 { PT_SETFPREGS, "PT_SETFPREGS" },
2221 { PT_GETDBREGS, "PT_GETDBREGS" },
2222 { PT_SETDBREGS, "PT_SETDBREGS" },
2223#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002224 { 0, NULL },
2225};
2226
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002227#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002228#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2229static
2230#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002231const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002232#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002233#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002234 { PT_PSWMASK, "psw_mask" },
2235 { PT_PSWADDR, "psw_addr" },
2236 { PT_GPR0, "gpr0" },
2237 { PT_GPR1, "gpr1" },
2238 { PT_GPR2, "gpr2" },
2239 { PT_GPR3, "gpr3" },
2240 { PT_GPR4, "gpr4" },
2241 { PT_GPR5, "gpr5" },
2242 { PT_GPR6, "gpr6" },
2243 { PT_GPR7, "gpr7" },
2244 { PT_GPR8, "gpr8" },
2245 { PT_GPR9, "gpr9" },
2246 { PT_GPR10, "gpr10" },
2247 { PT_GPR11, "gpr11" },
2248 { PT_GPR12, "gpr12" },
2249 { PT_GPR13, "gpr13" },
2250 { PT_GPR14, "gpr14" },
2251 { PT_GPR15, "gpr15" },
2252 { PT_ACR0, "acr0" },
2253 { PT_ACR1, "acr1" },
2254 { PT_ACR2, "acr2" },
2255 { PT_ACR3, "acr3" },
2256 { PT_ACR4, "acr4" },
2257 { PT_ACR5, "acr5" },
2258 { PT_ACR6, "acr6" },
2259 { PT_ACR7, "acr7" },
2260 { PT_ACR8, "acr8" },
2261 { PT_ACR9, "acr9" },
2262 { PT_ACR10, "acr10" },
2263 { PT_ACR11, "acr11" },
2264 { PT_ACR12, "acr12" },
2265 { PT_ACR13, "acr13" },
2266 { PT_ACR14, "acr14" },
2267 { PT_ACR15, "acr15" },
2268 { PT_ORIGGPR2, "orig_gpr2" },
2269 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002270#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002271 { PT_FPR0_HI, "fpr0.hi" },
2272 { PT_FPR0_LO, "fpr0.lo" },
2273 { PT_FPR1_HI, "fpr1.hi" },
2274 { PT_FPR1_LO, "fpr1.lo" },
2275 { PT_FPR2_HI, "fpr2.hi" },
2276 { PT_FPR2_LO, "fpr2.lo" },
2277 { PT_FPR3_HI, "fpr3.hi" },
2278 { PT_FPR3_LO, "fpr3.lo" },
2279 { PT_FPR4_HI, "fpr4.hi" },
2280 { PT_FPR4_LO, "fpr4.lo" },
2281 { PT_FPR5_HI, "fpr5.hi" },
2282 { PT_FPR5_LO, "fpr5.lo" },
2283 { PT_FPR6_HI, "fpr6.hi" },
2284 { PT_FPR6_LO, "fpr6.lo" },
2285 { PT_FPR7_HI, "fpr7.hi" },
2286 { PT_FPR7_LO, "fpr7.lo" },
2287 { PT_FPR8_HI, "fpr8.hi" },
2288 { PT_FPR8_LO, "fpr8.lo" },
2289 { PT_FPR9_HI, "fpr9.hi" },
2290 { PT_FPR9_LO, "fpr9.lo" },
2291 { PT_FPR10_HI, "fpr10.hi" },
2292 { PT_FPR10_LO, "fpr10.lo" },
2293 { PT_FPR11_HI, "fpr11.hi" },
2294 { PT_FPR11_LO, "fpr11.lo" },
2295 { PT_FPR12_HI, "fpr12.hi" },
2296 { PT_FPR12_LO, "fpr12.lo" },
2297 { PT_FPR13_HI, "fpr13.hi" },
2298 { PT_FPR13_LO, "fpr13.lo" },
2299 { PT_FPR14_HI, "fpr14.hi" },
2300 { PT_FPR14_LO, "fpr14.lo" },
2301 { PT_FPR15_HI, "fpr15.hi" },
2302 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002303#endif
2304#if defined(S390X)
2305 { PT_FPR0, "fpr0" },
2306 { PT_FPR1, "fpr1" },
2307 { PT_FPR2, "fpr2" },
2308 { PT_FPR3, "fpr3" },
2309 { PT_FPR4, "fpr4" },
2310 { PT_FPR5, "fpr5" },
2311 { PT_FPR6, "fpr6" },
2312 { PT_FPR7, "fpr7" },
2313 { PT_FPR8, "fpr8" },
2314 { PT_FPR9, "fpr9" },
2315 { PT_FPR10, "fpr10" },
2316 { PT_FPR11, "fpr11" },
2317 { PT_FPR12, "fpr12" },
2318 { PT_FPR13, "fpr13" },
2319 { PT_FPR14, "fpr14" },
2320 { PT_FPR15, "fpr15" },
2321#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002322 { PT_CR_9, "cr9" },
2323 { PT_CR_10, "cr10" },
2324 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002325 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002326#endif
2327#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002328 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002329#elif defined(HPPA)
2330 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002331#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002332#ifndef PT_ORIG_R3
2333#define PT_ORIG_R3 34
2334#endif
Roland McGratheb285352003-01-14 09:59:00 +00002335#define REGSIZE (sizeof(unsigned long))
2336 { REGSIZE*PT_R0, "r0" },
2337 { REGSIZE*PT_R1, "r1" },
2338 { REGSIZE*PT_R2, "r2" },
2339 { REGSIZE*PT_R3, "r3" },
2340 { REGSIZE*PT_R4, "r4" },
2341 { REGSIZE*PT_R5, "r5" },
2342 { REGSIZE*PT_R6, "r6" },
2343 { REGSIZE*PT_R7, "r7" },
2344 { REGSIZE*PT_R8, "r8" },
2345 { REGSIZE*PT_R9, "r9" },
2346 { REGSIZE*PT_R10, "r10" },
2347 { REGSIZE*PT_R11, "r11" },
2348 { REGSIZE*PT_R12, "r12" },
2349 { REGSIZE*PT_R13, "r13" },
2350 { REGSIZE*PT_R14, "r14" },
2351 { REGSIZE*PT_R15, "r15" },
2352 { REGSIZE*PT_R16, "r16" },
2353 { REGSIZE*PT_R17, "r17" },
2354 { REGSIZE*PT_R18, "r18" },
2355 { REGSIZE*PT_R19, "r19" },
2356 { REGSIZE*PT_R20, "r20" },
2357 { REGSIZE*PT_R21, "r21" },
2358 { REGSIZE*PT_R22, "r22" },
2359 { REGSIZE*PT_R23, "r23" },
2360 { REGSIZE*PT_R24, "r24" },
2361 { REGSIZE*PT_R25, "r25" },
2362 { REGSIZE*PT_R26, "r26" },
2363 { REGSIZE*PT_R27, "r27" },
2364 { REGSIZE*PT_R28, "r28" },
2365 { REGSIZE*PT_R29, "r29" },
2366 { REGSIZE*PT_R30, "r30" },
2367 { REGSIZE*PT_R31, "r31" },
2368 { REGSIZE*PT_NIP, "NIP" },
2369 { REGSIZE*PT_MSR, "MSR" },
2370 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2371 { REGSIZE*PT_CTR, "CTR" },
2372 { REGSIZE*PT_LNK, "LNK" },
2373 { REGSIZE*PT_XER, "XER" },
2374 { REGSIZE*PT_CCR, "CCR" },
2375 { REGSIZE*PT_FPR0, "FPR0" },
2376#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002377#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002378#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002379 { 0, "r0" },
2380 { 1, "r1" },
2381 { 2, "r2" },
2382 { 3, "r3" },
2383 { 4, "r4" },
2384 { 5, "r5" },
2385 { 6, "r6" },
2386 { 7, "r7" },
2387 { 8, "r8" },
2388 { 9, "r9" },
2389 { 10, "r10" },
2390 { 11, "r11" },
2391 { 12, "r12" },
2392 { 13, "r13" },
2393 { 14, "r14" },
2394 { 15, "r15" },
2395 { 16, "r16" },
2396 { 17, "r17" },
2397 { 18, "r18" },
2398 { 19, "r19" },
2399 { 20, "r20" },
2400 { 21, "r21" },
2401 { 22, "r22" },
2402 { 23, "r23" },
2403 { 24, "r24" },
2404 { 25, "r25" },
2405 { 26, "r26" },
2406 { 27, "r27" },
2407 { 28, "r28" },
2408 { 29, "gp" },
2409 { 30, "fp" },
2410 { 31, "zero" },
2411 { 32, "fp0" },
2412 { 33, "fp" },
2413 { 34, "fp2" },
2414 { 35, "fp3" },
2415 { 36, "fp4" },
2416 { 37, "fp5" },
2417 { 38, "fp6" },
2418 { 39, "fp7" },
2419 { 40, "fp8" },
2420 { 41, "fp9" },
2421 { 42, "fp10" },
2422 { 43, "fp11" },
2423 { 44, "fp12" },
2424 { 45, "fp13" },
2425 { 46, "fp14" },
2426 { 47, "fp15" },
2427 { 48, "fp16" },
2428 { 49, "fp17" },
2429 { 50, "fp18" },
2430 { 51, "fp19" },
2431 { 52, "fp20" },
2432 { 53, "fp21" },
2433 { 54, "fp22" },
2434 { 55, "fp23" },
2435 { 56, "fp24" },
2436 { 57, "fp25" },
2437 { 58, "fp26" },
2438 { 59, "fp27" },
2439 { 60, "fp28" },
2440 { 61, "fp29" },
2441 { 62, "fp30" },
2442 { 63, "fp31" },
2443 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002444#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002445#ifdef IA64
2446 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2447 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2448 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2449 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2450 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2451 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2452 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2453 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2454 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2455 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2456 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2457 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2458 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2459 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2460 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2461 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2462 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2463 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2464 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2465 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2466 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2467 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2468 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2469 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2470 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2471 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2472 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2473 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2474 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2475 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2476 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2477 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2478 /* switch stack: */
2479 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2480 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2481 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2482 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2483 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2484 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2485 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2486 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2487 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2488 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002489 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2490 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002491 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002492 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002493 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2494 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002495 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2496 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2497 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2498 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2499 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2500 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2501 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2502 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2503 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2504 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2505 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2506 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2507 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2508 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2509 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002510# ifdef PT_AR_CSD
2511 { PT_AR_CSD, "ar.csd" },
2512# endif
2513# ifdef PT_AR_SSD
2514 { PT_AR_SSD, "ar.ssd" },
2515# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002516 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002517#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002518#ifdef I386
2519 { 4*EBX, "4*EBX" },
2520 { 4*ECX, "4*ECX" },
2521 { 4*EDX, "4*EDX" },
2522 { 4*ESI, "4*ESI" },
2523 { 4*EDI, "4*EDI" },
2524 { 4*EBP, "4*EBP" },
2525 { 4*EAX, "4*EAX" },
2526 { 4*DS, "4*DS" },
2527 { 4*ES, "4*ES" },
2528 { 4*FS, "4*FS" },
2529 { 4*GS, "4*GS" },
2530 { 4*ORIG_EAX, "4*ORIG_EAX" },
2531 { 4*EIP, "4*EIP" },
2532 { 4*CS, "4*CS" },
2533 { 4*EFL, "4*EFL" },
2534 { 4*UESP, "4*UESP" },
2535 { 4*SS, "4*SS" },
2536#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002537#ifdef X86_64
2538 { 8*RDI, "8*RDI" },
2539 { 8*RSI, "8*RSI" },
2540 { 8*RDX, "8*RDX" },
2541 { 8*R10, "8*R10" },
2542 { 8*R8, "8*R8" },
2543 { 8*R9, "8*R9" },
2544 { 8*RBX, "8*RBX" },
2545 { 8*RCX, "8*RCX" },
2546 { 8*RBP, "8*RBP" },
2547 { 8*RAX, "8*RAX" },
2548#if 0
2549 { 8*DS, "8*DS" },
2550 { 8*ES, "8*ES" },
2551 { 8*FS, "8*FS" },
2552 { 8*GS, "8*GS" },
2553#endif
2554 { 8*ORIG_RAX, "8*ORIG_EAX" },
2555 { 8*RIP, "8*RIP" },
2556 { 8*CS, "8*CS" },
2557 { 8*EFLAGS, "8*EFL" },
2558 { 8*RSP, "8*RSP" },
2559 { 8*SS, "8*SS" },
2560 { 8*R11, "8*R11" },
2561 { 8*R12, "8*R12" },
2562 { 8*R13, "8*R13" },
2563 { 8*R14, "8*R14" },
2564 { 8*R15, "8*R15" },
2565#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002566#ifdef M68K
2567 { 4*PT_D1, "4*PT_D1" },
2568 { 4*PT_D2, "4*PT_D2" },
2569 { 4*PT_D3, "4*PT_D3" },
2570 { 4*PT_D4, "4*PT_D4" },
2571 { 4*PT_D5, "4*PT_D5" },
2572 { 4*PT_D6, "4*PT_D6" },
2573 { 4*PT_D7, "4*PT_D7" },
2574 { 4*PT_A0, "4*PT_A0" },
2575 { 4*PT_A1, "4*PT_A1" },
2576 { 4*PT_A2, "4*PT_A2" },
2577 { 4*PT_A3, "4*PT_A3" },
2578 { 4*PT_A4, "4*PT_A4" },
2579 { 4*PT_A5, "4*PT_A5" },
2580 { 4*PT_A6, "4*PT_A6" },
2581 { 4*PT_D0, "4*PT_D0" },
2582 { 4*PT_USP, "4*PT_USP" },
2583 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2584 { 4*PT_SR, "4*PT_SR" },
2585 { 4*PT_PC, "4*PT_PC" },
2586#endif /* M68K */
2587#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002588#ifdef SH
2589 { 4*REG_REG0, "4*REG_REG0" },
2590 { 4*(REG_REG0+1), "4*REG_REG1" },
2591 { 4*(REG_REG0+2), "4*REG_REG2" },
2592 { 4*(REG_REG0+3), "4*REG_REG3" },
2593 { 4*(REG_REG0+4), "4*REG_REG4" },
2594 { 4*(REG_REG0+5), "4*REG_REG5" },
2595 { 4*(REG_REG0+6), "4*REG_REG6" },
2596 { 4*(REG_REG0+7), "4*REG_REG7" },
2597 { 4*(REG_REG0+8), "4*REG_REG8" },
2598 { 4*(REG_REG0+9), "4*REG_REG9" },
2599 { 4*(REG_REG0+10), "4*REG_REG10" },
2600 { 4*(REG_REG0+11), "4*REG_REG11" },
2601 { 4*(REG_REG0+12), "4*REG_REG12" },
2602 { 4*(REG_REG0+13), "4*REG_REG13" },
2603 { 4*(REG_REG0+14), "4*REG_REG14" },
2604 { 4*REG_REG15, "4*REG_REG15" },
2605 { 4*REG_PC, "4*REG_PC" },
2606 { 4*REG_PR, "4*REG_PR" },
2607 { 4*REG_SR, "4*REG_SR" },
2608 { 4*REG_GBR, "4*REG_GBR" },
2609 { 4*REG_MACH, "4*REG_MACH" },
2610 { 4*REG_MACL, "4*REG_MACL" },
2611 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2612 { 4*REG_FPUL, "4*REG_FPUL" },
2613 { 4*REG_FPREG0, "4*REG_FPREG0" },
2614 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2615 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2616 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2617 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2618 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2619 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2620 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2621 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2622 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2623 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2624 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2625 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2626 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2627 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2628 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002629#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002630 { 4*REG_XDREG0, "4*REG_XDREG0" },
2631 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2632 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2633 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2634 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2635 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2636 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2637 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002638#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002639 { 4*REG_FPSCR, "4*REG_FPSCR" },
2640#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002641#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002642 { 0, "PC(L)" },
2643 { 4, "PC(U)" },
2644 { 8, "SR(L)" },
2645 { 12, "SR(U)" },
2646 { 16, "syscall no.(L)" },
2647 { 20, "syscall_no.(U)" },
2648 { 24, "R0(L)" },
2649 { 28, "R0(U)" },
2650 { 32, "R1(L)" },
2651 { 36, "R1(U)" },
2652 { 40, "R2(L)" },
2653 { 44, "R2(U)" },
2654 { 48, "R3(L)" },
2655 { 52, "R3(U)" },
2656 { 56, "R4(L)" },
2657 { 60, "R4(U)" },
2658 { 64, "R5(L)" },
2659 { 68, "R5(U)" },
2660 { 72, "R6(L)" },
2661 { 76, "R6(U)" },
2662 { 80, "R7(L)" },
2663 { 84, "R7(U)" },
2664 { 88, "R8(L)" },
2665 { 92, "R8(U)" },
2666 { 96, "R9(L)" },
2667 { 100, "R9(U)" },
2668 { 104, "R10(L)" },
2669 { 108, "R10(U)" },
2670 { 112, "R11(L)" },
2671 { 116, "R11(U)" },
2672 { 120, "R12(L)" },
2673 { 124, "R12(U)" },
2674 { 128, "R13(L)" },
2675 { 132, "R13(U)" },
2676 { 136, "R14(L)" },
2677 { 140, "R14(U)" },
2678 { 144, "R15(L)" },
2679 { 148, "R15(U)" },
2680 { 152, "R16(L)" },
2681 { 156, "R16(U)" },
2682 { 160, "R17(L)" },
2683 { 164, "R17(U)" },
2684 { 168, "R18(L)" },
2685 { 172, "R18(U)" },
2686 { 176, "R19(L)" },
2687 { 180, "R19(U)" },
2688 { 184, "R20(L)" },
2689 { 188, "R20(U)" },
2690 { 192, "R21(L)" },
2691 { 196, "R21(U)" },
2692 { 200, "R22(L)" },
2693 { 204, "R22(U)" },
2694 { 208, "R23(L)" },
2695 { 212, "R23(U)" },
2696 { 216, "R24(L)" },
2697 { 220, "R24(U)" },
2698 { 224, "R25(L)" },
2699 { 228, "R25(U)" },
2700 { 232, "R26(L)" },
2701 { 236, "R26(U)" },
2702 { 240, "R27(L)" },
2703 { 244, "R27(U)" },
2704 { 248, "R28(L)" },
2705 { 252, "R28(U)" },
2706 { 256, "R29(L)" },
2707 { 260, "R29(U)" },
2708 { 264, "R30(L)" },
2709 { 268, "R30(U)" },
2710 { 272, "R31(L)" },
2711 { 276, "R31(U)" },
2712 { 280, "R32(L)" },
2713 { 284, "R32(U)" },
2714 { 288, "R33(L)" },
2715 { 292, "R33(U)" },
2716 { 296, "R34(L)" },
2717 { 300, "R34(U)" },
2718 { 304, "R35(L)" },
2719 { 308, "R35(U)" },
2720 { 312, "R36(L)" },
2721 { 316, "R36(U)" },
2722 { 320, "R37(L)" },
2723 { 324, "R37(U)" },
2724 { 328, "R38(L)" },
2725 { 332, "R38(U)" },
2726 { 336, "R39(L)" },
2727 { 340, "R39(U)" },
2728 { 344, "R40(L)" },
2729 { 348, "R40(U)" },
2730 { 352, "R41(L)" },
2731 { 356, "R41(U)" },
2732 { 360, "R42(L)" },
2733 { 364, "R42(U)" },
2734 { 368, "R43(L)" },
2735 { 372, "R43(U)" },
2736 { 376, "R44(L)" },
2737 { 380, "R44(U)" },
2738 { 384, "R45(L)" },
2739 { 388, "R45(U)" },
2740 { 392, "R46(L)" },
2741 { 396, "R46(U)" },
2742 { 400, "R47(L)" },
2743 { 404, "R47(U)" },
2744 { 408, "R48(L)" },
2745 { 412, "R48(U)" },
2746 { 416, "R49(L)" },
2747 { 420, "R49(U)" },
2748 { 424, "R50(L)" },
2749 { 428, "R50(U)" },
2750 { 432, "R51(L)" },
2751 { 436, "R51(U)" },
2752 { 440, "R52(L)" },
2753 { 444, "R52(U)" },
2754 { 448, "R53(L)" },
2755 { 452, "R53(U)" },
2756 { 456, "R54(L)" },
2757 { 460, "R54(U)" },
2758 { 464, "R55(L)" },
2759 { 468, "R55(U)" },
2760 { 472, "R56(L)" },
2761 { 476, "R56(U)" },
2762 { 480, "R57(L)" },
2763 { 484, "R57(U)" },
2764 { 488, "R58(L)" },
2765 { 492, "R58(U)" },
2766 { 496, "R59(L)" },
2767 { 500, "R59(U)" },
2768 { 504, "R60(L)" },
2769 { 508, "R60(U)" },
2770 { 512, "R61(L)" },
2771 { 516, "R61(U)" },
2772 { 520, "R62(L)" },
2773 { 524, "R62(U)" },
2774 { 528, "TR0(L)" },
2775 { 532, "TR0(U)" },
2776 { 536, "TR1(L)" },
2777 { 540, "TR1(U)" },
2778 { 544, "TR2(L)" },
2779 { 548, "TR2(U)" },
2780 { 552, "TR3(L)" },
2781 { 556, "TR3(U)" },
2782 { 560, "TR4(L)" },
2783 { 564, "TR4(U)" },
2784 { 568, "TR5(L)" },
2785 { 572, "TR5(U)" },
2786 { 576, "TR6(L)" },
2787 { 580, "TR6(U)" },
2788 { 584, "TR7(L)" },
2789 { 588, "TR7(U)" },
2790 /* This entry is in case pt_regs contains dregs (depends on
2791 the kernel build options). */
2792 { uoff(regs), "offsetof(struct user, regs)" },
2793 { uoff(fpu), "offsetof(struct user, fpu)" },
2794#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002795#ifdef ARM
2796 { uoff(regs.ARM_r0), "r0" },
2797 { uoff(regs.ARM_r1), "r1" },
2798 { uoff(regs.ARM_r2), "r2" },
2799 { uoff(regs.ARM_r3), "r3" },
2800 { uoff(regs.ARM_r4), "r4" },
2801 { uoff(regs.ARM_r5), "r5" },
2802 { uoff(regs.ARM_r6), "r6" },
2803 { uoff(regs.ARM_r7), "r7" },
2804 { uoff(regs.ARM_r8), "r8" },
2805 { uoff(regs.ARM_r9), "r9" },
2806 { uoff(regs.ARM_r10), "r10" },
2807 { uoff(regs.ARM_fp), "fp" },
2808 { uoff(regs.ARM_ip), "ip" },
2809 { uoff(regs.ARM_sp), "sp" },
2810 { uoff(regs.ARM_lr), "lr" },
2811 { uoff(regs.ARM_pc), "pc" },
2812 { uoff(regs.ARM_cpsr), "cpsr" },
2813#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002814
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002815#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002816 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002817#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002818#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002819 { uoff(i387), "offsetof(struct user, i387)" },
2820#else /* !I386 */
2821#ifdef M68K
2822 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2823#endif /* M68K */
2824#endif /* !I386 */
2825 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2826 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2827 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002828#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002829 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002830#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00002831#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002832 { uoff(start_data), "offsetof(struct user, start_data)" },
2833#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002834#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002835 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002836#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002837 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002838#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002839 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002840#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002841#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002842 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002843#endif
2844#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002845 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2846#endif
2847 { uoff(magic), "offsetof(struct user, magic)" },
2848 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002849#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002850 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2851#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002852#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002853#endif /* !ALPHA */
2854#endif /* !POWERPC/!SPARC */
2855#endif /* LINUX */
2856#ifdef SUNOS4
2857 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2858 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2859 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2860 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2861 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2862 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2863 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2864 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2865 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2866 { uoff(u_error), "offsetof(struct user, u_error)" },
2867 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2868 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2869 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2870 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2871 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2872 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2873 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2874 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2875 { uoff(u_code), "offsetof(struct user, u_code)" },
2876 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2877 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2878 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2879 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2880 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2881 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2882 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2883 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2884 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2885 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2886 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2887 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2888 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2889 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2890 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2891 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2892 { uoff(u_start), "offsetof(struct user, u_start)" },
2893 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2894 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2895 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2896 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2897 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2898 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2899 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2900 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2901 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2902#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002903#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002904 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002905#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002906 { 0, NULL },
2907};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002908#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002909
2910int
2911sys_ptrace(tcp)
2912struct tcb *tcp;
2913{
Roland McGrathd9f816f2004-09-04 03:39:20 +00002914 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002915 long addr;
2916
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002917 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002918 printxval(ptrace_cmds, tcp->u_arg[0],
2919#ifndef FREEBSD
2920 "PTRACE_???"
2921#else
2922 "PT_???"
2923#endif
2924 );
2925 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002926 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002927#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002928 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2929 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2930 for (x = struct_user_offsets; x->str; x++) {
2931 if (x->val >= addr)
2932 break;
2933 }
2934 if (!x->str)
2935 tprintf("%#lx, ", addr);
2936 else if (x->val > addr && x != struct_user_offsets) {
2937 x--;
2938 tprintf("%s + %ld, ", x->str, addr - x->val);
2939 }
2940 else
2941 tprintf("%s, ", x->str);
2942 }
2943 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002944#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002945 tprintf("%#lx, ", tcp->u_arg[2]);
2946#ifdef LINUX
2947 switch (tcp->u_arg[0]) {
2948 case PTRACE_PEEKDATA:
2949 case PTRACE_PEEKTEXT:
2950 case PTRACE_PEEKUSER:
2951 break;
2952 case PTRACE_CONT:
2953 case PTRACE_SINGLESTEP:
2954 case PTRACE_SYSCALL:
2955 case PTRACE_DETACH:
2956 printsignal(tcp->u_arg[3]);
2957 break;
2958 default:
2959 tprintf("%#lx", tcp->u_arg[3]);
2960 break;
2961 }
2962 } else {
2963 switch (tcp->u_arg[0]) {
2964 case PTRACE_PEEKDATA:
2965 case PTRACE_PEEKTEXT:
2966 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002967 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002968 break;
2969 }
2970 }
2971#endif /* LINUX */
2972#ifdef SUNOS4
2973 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2974 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2975 tprintf("%lu, ", tcp->u_arg[3]);
2976 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2977 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2978 tcp->u_arg[0] != PTRACE_READTEXT) {
2979 tprintf("%#lx", tcp->u_arg[3]);
2980 }
2981 } else {
2982 if (tcp->u_arg[0] == PTRACE_READDATA ||
2983 tcp->u_arg[0] == PTRACE_READTEXT) {
2984 tprintf("%lu, ", tcp->u_arg[3]);
2985 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2986 }
2987 }
2988#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002989#ifdef FREEBSD
2990 tprintf("%lu", tcp->u_arg[3]);
2991 }
2992#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002993 return 0;
2994}
2995
2996#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002997
2998#ifdef LINUX
Roland McGrathd9f816f2004-09-04 03:39:20 +00002999static const struct xlat futexops[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00003000 { FUTEX_WAIT, "FUTEX_WAIT" },
3001 { FUTEX_WAKE, "FUTEX_WAKE" },
3002 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00003003 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00003004 { 0, NULL }
3005};
3006
3007int
3008sys_futex(tcp)
3009struct tcb *tcp;
3010{
3011 if (entering(tcp)) {
3012 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00003013 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00003014 tprintf(", %ld", tcp->u_arg[2]);
3015 if (tcp->u_arg[1] == FUTEX_WAIT) {
3016 tprintf(", ");
3017 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00003018 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
3019 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00003020 }
3021 return 0;
3022}
3023
3024static void
Roland McGrath79fbda52004-04-14 02:45:55 +00003025print_affinitylist(tcp, list, len)
3026struct tcb *tcp;
3027long list;
Roland McGrath5a223472002-12-15 23:58:26 +00003028unsigned int len;
3029{
3030 int first = 1;
3031 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00003032 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003033 unsigned long w;
3034 umove(tcp, list, &w);
3035 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003036 first = 0;
3037 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003038 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003039 }
3040 tprintf(" }");
3041}
3042
3043int
3044sys_sched_setaffinity(tcp)
3045struct tcb *tcp;
3046{
3047 if (entering(tcp)) {
3048 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003049 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003050 }
3051 return 0;
3052}
3053
3054int
3055sys_sched_getaffinity(tcp)
3056struct tcb *tcp;
3057{
3058 if (entering(tcp)) {
3059 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3060 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003061 if (tcp->u_rval == -1)
3062 tprintf("%#lx", tcp->u_arg[2]);
3063 else
3064 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003065 }
3066 return 0;
3067}
Roland McGrath279d3782004-03-01 20:27:37 +00003068
Roland McGrathd9f816f2004-09-04 03:39:20 +00003069static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003070 { SCHED_OTHER, "SCHED_OTHER" },
3071 { SCHED_RR, "SCHED_RR" },
3072 { SCHED_FIFO, "SCHED_FIFO" },
3073 { 0, NULL }
3074};
3075
3076int
3077sys_sched_getscheduler(tcp)
3078struct tcb *tcp;
3079{
3080 if (entering(tcp)) {
3081 tprintf("%d", (int) tcp->u_arg[0]);
3082 } else if (! syserror(tcp)) {
3083 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3084 if (tcp->auxstr != NULL)
3085 return RVAL_STR;
3086 }
3087 return 0;
3088}
3089
3090int
3091sys_sched_setscheduler(tcp)
3092struct tcb *tcp;
3093{
3094 if (entering(tcp)) {
3095 struct sched_param p;
3096 tprintf("%d, ", (int) tcp->u_arg[0]);
3097 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3098 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3099 tprintf(", %lx", tcp->u_arg[2]);
3100 else
3101 tprintf(", { %d }", p.__sched_priority);
3102 }
3103 return 0;
3104}
3105
3106int
3107sys_sched_getparam(tcp)
3108struct tcb *tcp;
3109{
3110 if (entering(tcp)) {
3111 tprintf("%d, ", (int) tcp->u_arg[0]);
3112 } else {
3113 struct sched_param p;
3114 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3115 tprintf("%lx", tcp->u_arg[1]);
3116 else
3117 tprintf("{ %d }", p.__sched_priority);
3118 }
3119 return 0;
3120}
3121
3122int
3123sys_sched_setparam(tcp)
3124struct tcb *tcp;
3125{
3126 if (entering(tcp)) {
3127 struct sched_param p;
3128 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3129 tprintf("%d, %lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3130 else
3131 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3132 }
3133 return 0;
3134}
3135
3136int
3137sys_sched_get_priority_min(tcp)
3138struct tcb *tcp;
3139{
3140 if (entering(tcp)) {
3141 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3142 }
3143 return 0;
3144}
Roland McGrath5a223472002-12-15 23:58:26 +00003145#endif