blob: f1f6701d74b6ef434165e8ff083a30e064337ef1 [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 +00001578static void
1579printargv(tcp, addr)
1580struct tcb *tcp;
1581long addr;
1582{
1583 char *cp;
1584 char *sep;
1585 int max = max_strlen / 2;
1586
1587 for (sep = ""; --max >= 0; sep = ", ") {
1588 if (!abbrev(tcp))
1589 max++;
1590 if (umove(tcp, addr, &cp) < 0) {
1591 tprintf("%#lx", addr);
1592 return;
1593 }
1594 if (cp == 0)
1595 break;
1596 tprintf(sep);
1597 printstr(tcp, (long) cp, -1);
1598 addr += sizeof(char *);
1599 }
1600 if (cp)
1601 tprintf(", ...");
1602}
1603
1604static void
1605printargc(fmt, tcp, addr)
1606char *fmt;
1607struct tcb *tcp;
1608long addr;
1609{
1610 int count;
1611 char *cp;
1612
1613 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1614 addr += sizeof(char *);
1615 }
1616 tprintf(fmt, count, count == 1 ? "" : "s");
1617}
1618
1619int
1620sys_execv(tcp)
1621struct tcb *tcp;
1622{
1623 if (entering(tcp)) {
1624 printpath(tcp, tcp->u_arg[0]);
1625 if (!verbose(tcp))
1626 tprintf(", %#lx", tcp->u_arg[1]);
1627#if 0
1628 else if (abbrev(tcp))
1629 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1630#endif
1631 else {
1632 tprintf(", [");
1633 printargv(tcp, tcp->u_arg[1]);
1634 tprintf("]");
1635 }
1636 }
1637 return 0;
1638}
1639
1640int
1641sys_execve(tcp)
1642struct tcb *tcp;
1643{
1644 if (entering(tcp)) {
1645 printpath(tcp, tcp->u_arg[0]);
1646 if (!verbose(tcp))
1647 tprintf(", %#lx", tcp->u_arg[1]);
1648#if 0
1649 else if (abbrev(tcp))
1650 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1651#endif
1652 else {
1653 tprintf(", [");
1654 printargv(tcp, tcp->u_arg[1]);
1655 tprintf("]");
1656 }
1657 if (!verbose(tcp))
1658 tprintf(", %#lx", tcp->u_arg[2]);
1659 else if (abbrev(tcp))
1660 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1661 else {
1662 tprintf(", [");
1663 printargv(tcp, tcp->u_arg[2]);
1664 tprintf("]");
1665 }
1666 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001667 return 0;
1668}
1669
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001670#if UNIXWARE > 2
John Hughes4e36a812001-04-18 15:11:51 +00001671
1672int sys_rexecve(tcp)
1673struct tcb *tcp;
1674{
1675 if (entering (tcp)) {
1676 sys_execve (tcp);
1677 tprintf (", %ld", tcp->u_arg[3]);
1678 }
1679 return 0;
1680}
1681
Roland McGrath5ef24ab2004-02-20 02:22:35 +00001682#endif
John Hughes4e36a812001-04-18 15:11:51 +00001683
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001684int
1685internal_exec(tcp)
1686struct tcb *tcp;
1687{
1688#ifdef SUNOS4
1689 if (exiting(tcp) && !syserror(tcp) && followfork)
1690 fixvfork(tcp);
1691#endif /* SUNOS4 */
Roland McGrathfdb097f2004-07-12 07:38:55 +00001692#if defined LINUX && defined TCB_WAITEXECVE
1693 if (exiting(tcp) && syserror(tcp))
1694 tcp->flags &= ~TCB_WAITEXECVE;
1695 else
1696 tcp->flags |= TCB_WAITEXECVE;
1697#endif /* LINUX && TCB_WAITEXECVE */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001698 return 0;
1699}
1700
1701#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001702#ifndef __WNOTHREAD
1703#define __WNOTHREAD 0x20000000
1704#endif
1705#ifndef __WALL
1706#define __WALL 0x40000000
1707#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001708#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001709#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001710#endif
1711#endif /* LINUX */
1712
Roland McGrathd9f816f2004-09-04 03:39:20 +00001713static const struct xlat wait4_options[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001714 { WNOHANG, "WNOHANG" },
1715#ifndef WSTOPPED
1716 { WUNTRACED, "WUNTRACED" },
1717#endif
1718#ifdef WEXITED
1719 { WEXITED, "WEXITED" },
1720#endif
1721#ifdef WTRAPPED
1722 { WTRAPPED, "WTRAPPED" },
1723#endif
1724#ifdef WSTOPPED
1725 { WSTOPPED, "WSTOPPED" },
1726#endif
1727#ifdef WCONTINUED
1728 { WCONTINUED, "WCONTINUED" },
1729#endif
1730#ifdef WNOWAIT
1731 { WNOWAIT, "WNOWAIT" },
1732#endif
1733#ifdef __WCLONE
1734 { __WCLONE, "__WCLONE" },
1735#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001736#ifdef __WALL
1737 { __WALL, "__WALL" },
1738#endif
1739#ifdef __WNOTHREAD
1740 { __WNOTHREAD, "__WNOTHREAD" },
1741#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001742 { 0, NULL },
1743};
1744
Roland McGrath5e02a572004-10-19 23:33:47 +00001745#if !defined WCOREFLAG && defined WCOREFLG
1746# define WCOREFLAG WCOREFLG
1747#endif
1748#ifndef WCOREFLAG
1749#define WCOREFLAG 0x80
1750#endif
1751
1752#ifndef W_STOPCODE
1753#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1754#endif
1755#ifndef W_EXITCODE
1756#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1757#endif
1758
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001759static int
1760printstatus(status)
1761int status;
1762{
1763 int exited = 0;
1764
1765 /*
1766 * Here is a tricky presentation problem. This solution
1767 * is still not entirely satisfactory but since there
1768 * are no wait status constructors it will have to do.
1769 */
Roland McGrath79fbda52004-04-14 02:45:55 +00001770 if (WIFSTOPPED(status)) {
1771 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001772 signame(WSTOPSIG(status)));
Roland McGrath79fbda52004-04-14 02:45:55 +00001773 status &= ~W_STOPCODE(WSTOPSIG(status));
1774 }
1775 else if (WIFSIGNALED(status)) {
1776 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001777 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001778 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
Roland McGrath79fbda52004-04-14 02:45:55 +00001779 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1780 }
1781 else if (WIFEXITED(status)) {
1782 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001783 WEXITSTATUS(status));
1784 exited = 1;
Roland McGrath79fbda52004-04-14 02:45:55 +00001785 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001786 }
Roland McGrath79fbda52004-04-14 02:45:55 +00001787 else {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788 tprintf("[%#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001789 return 0;
1790 }
1791
1792 if (status == 0)
1793 tprintf("]");
1794 else
Roland McGrathf8cc83c2004-06-04 01:24:07 +00001795 tprintf(" | %#x]", status);
Roland McGrath79fbda52004-04-14 02:45:55 +00001796
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001797 return exited;
1798}
1799
1800static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001801printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001802struct tcb *tcp;
1803int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001804int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001805{
1806 int status;
1807 int exited = 0;
1808
1809 if (entering(tcp)) {
1810 tprintf("%ld, ", tcp->u_arg[0]);
1811 } else {
1812 /* status */
1813 if (!tcp->u_arg[1])
1814 tprintf("NULL");
1815 else if (syserror(tcp) || tcp->u_rval == 0)
1816 tprintf("%#lx", tcp->u_arg[1]);
1817 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1818 tprintf("[?]");
1819 else
1820 exited = printstatus(status);
1821 /* options */
1822 tprintf(", ");
1823 if (!printflags(wait4_options, tcp->u_arg[2]))
1824 tprintf("0");
1825 if (n == 4) {
1826 tprintf(", ");
1827 /* usage */
1828 if (!tcp->u_arg[3])
1829 tprintf("NULL");
1830#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001831 else if (tcp->u_rval > 0) {
1832#ifdef LINUX_64BIT
1833 if (bitness)
1834 printrusage32(tcp, tcp->u_arg[3]);
1835 else
1836#endif
1837 printrusage(tcp, tcp->u_arg[3]);
1838 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001839#endif /* LINUX */
1840#ifdef SUNOS4
1841 else if (tcp->u_rval > 0 && exited)
1842 printrusage(tcp, tcp->u_arg[3]);
1843#endif /* SUNOS4 */
1844 else
1845 tprintf("%#lx", tcp->u_arg[3]);
1846 }
1847 }
1848 return 0;
1849}
1850
1851int
Roland McGrathc74c0b72004-09-01 19:39:46 +00001852internal_wait(tcp, flagarg)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001853struct tcb *tcp;
Roland McGrathc74c0b72004-09-01 19:39:46 +00001854int flagarg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001855{
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001856 int got_kids;
1857
1858#ifdef TCB_CLONE_THREAD
1859 if (tcp->flags & TCB_CLONE_THREAD)
1860 /* The children we wait for are our parent's children. */
1861 got_kids = (tcp->parent->nchildren
1862 > tcp->parent->nclone_detached);
1863 else
1864 got_kids = (tcp->nchildren > tcp->nclone_detached);
1865#else
1866 got_kids = tcp->nchildren > 0;
1867#endif
1868
1869 if (entering(tcp) && got_kids) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001870 /* There are children that this parent should block for.
1871 But ptrace made us the parent of the traced children
1872 and the real parent will get ECHILD from the wait call.
1873
1874 XXX If we attached with strace -f -p PID, then there
1875 may be untraced dead children the parent could be reaping
1876 now, but we make him block. */
1877
1878 /* ??? WTA: fix bug with hanging children */
1879
Roland McGrathc74c0b72004-09-01 19:39:46 +00001880 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
Roland McGrath09623452003-05-23 02:27:13 +00001881 /*
1882 * There are traced children. We'll make the parent
1883 * block to avoid a false ECHILD error due to our
1884 * ptrace having stolen the children. However,
1885 * we shouldn't block if there are zombies to reap.
1886 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1887 */
Roland McGrathfccfb942003-10-01 21:59:44 +00001888 struct tcb *child = NULL;
Roland McGrath09623452003-05-23 02:27:13 +00001889 if (tcp->nzombies > 0 &&
1890 (tcp->u_arg[0] == -1 ||
Roland McGrathfccfb942003-10-01 21:59:44 +00001891 (child = pid2tcb(tcp->u_arg[0])) == NULL))
Roland McGrath09623452003-05-23 02:27:13 +00001892 return 0;
Roland McGrathfccfb942003-10-01 21:59:44 +00001893 if (tcp->u_arg[0] > 0) {
1894 /*
1895 * If the parent waits for a specified child
1896 * PID, then it must get ECHILD right away
1897 * if that PID is not one of its children.
1898 * Make sure that the requested PID matches
1899 * one of the parent's children that we are
1900 * tracing, and don't suspend it otherwise.
1901 */
1902 if (child == NULL)
1903 child = pid2tcb(tcp->u_arg[0]);
1904 if (child == NULL || child->parent != (
1905#ifdef TCB_CLONE_THREAD
1906 (tcp->flags & TCB_CLONE_THREAD)
1907 ? tcp->parent :
1908#endif
1909 tcp))
1910 return 0;
1911 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001912 tcp->flags |= TCB_SUSPENDED;
1913 tcp->waitpid = tcp->u_arg[0];
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001914#ifdef TCB_CLONE_THREAD
1915 if (tcp->flags & TCB_CLONE_THREAD)
1916 tcp->parent->nclone_waiting++;
1917#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001918 }
1919 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001920 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
Roland McGrathc74c0b72004-09-01 19:39:46 +00001921 if (tcp->u_arg[flagarg] & WNOHANG) {
Roland McGrathb69f81b2002-12-21 23:25:18 +00001922 /* We must force a fake result of 0 instead of
1923 the ECHILD error. */
1924 extern int force_result();
1925 return force_result(tcp, 0, 0);
1926 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001927 }
Roland McGrath09623452003-05-23 02:27:13 +00001928 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1929 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1930 /*
1931 * We just reaped a child we don't know about,
1932 * presumably a zombie we already droptcb'd.
1933 */
1934 tcp->nzombies--;
1935 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001936 return 0;
1937}
1938
1939#ifdef SVR4
1940
1941int
1942sys_wait(tcp)
1943struct tcb *tcp;
1944{
1945 if (exiting(tcp)) {
1946 /* The library wrapper stuffs this into the user variable. */
1947 if (!syserror(tcp))
1948 printstatus(getrval2(tcp));
1949 }
1950 return 0;
1951}
1952
1953#endif /* SVR4 */
1954
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001955#ifdef FREEBSD
1956int
1957sys_wait(tcp)
1958struct tcb *tcp;
1959{
1960 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001961
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001962 if (exiting(tcp)) {
1963 if (!syserror(tcp)) {
1964 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1965 tprintf("%#lx", tcp->u_arg[0]);
1966 else
1967 printstatus(status);
1968 }
1969 }
1970 return 0;
1971}
1972#endif
1973
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001974int
1975sys_waitpid(tcp)
1976struct tcb *tcp;
1977{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001978 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001979}
1980
1981int
1982sys_wait4(tcp)
1983struct tcb *tcp;
1984{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001985 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001986}
1987
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001988#ifdef ALPHA
1989int
1990sys_osf_wait4(tcp)
1991struct tcb *tcp;
1992{
1993 return printwaitn(tcp, 4, 1);
1994}
1995#endif
1996
Roland McGrathc74c0b72004-09-01 19:39:46 +00001997#if defined SVR4 || defined LINUX
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001998
Roland McGrathd9f816f2004-09-04 03:39:20 +00001999static const struct xlat waitid_types[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002000 { P_PID, "P_PID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002001#ifdef P_PPID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 { P_PPID, "P_PPID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002003#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002004 { P_PGID, "P_PGID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002005#ifdef P_SID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002006 { P_SID, "P_SID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002007#endif
2008#ifdef P_CID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002009 { P_CID, "P_CID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002010#endif
2011#ifdef P_UID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002012 { P_UID, "P_UID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002013#endif
2014#ifdef P_GID
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002015 { P_GID, "P_GID" },
Roland McGrathc74c0b72004-09-01 19:39:46 +00002016#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002017 { P_ALL, "P_ALL" },
2018#ifdef P_LWPID
2019 { P_LWPID, "P_LWPID" },
2020#endif
2021 { 0, NULL },
2022};
2023
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002024int
2025sys_waitid(tcp)
2026struct tcb *tcp;
2027{
2028 siginfo_t si;
2029 int exited;
2030
2031 if (entering(tcp)) {
2032 printxval(waitid_types, tcp->u_arg[0], "P_???");
2033 tprintf(", %ld, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002034 }
2035 else {
2036 /* siginfo */
2037 exited = 0;
2038 if (!tcp->u_arg[2])
2039 tprintf("NULL");
2040 else if (syserror(tcp))
2041 tprintf("%#lx", tcp->u_arg[2]);
2042 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2043 tprintf("{???}");
2044 else
John Hughes58265892001-10-18 15:13:53 +00002045 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002046 /* options */
2047 tprintf(", ");
2048 if (!printflags(wait4_options, tcp->u_arg[3]))
2049 tprintf("0");
Roland McGrath39426a32004-10-06 22:02:59 +00002050 if (tcp->u_nargs > 4) {
2051 /* usage */
2052 tprintf(", ");
2053 if (!tcp->u_arg[4])
2054 tprintf("NULL");
2055 else if (tcp->u_error)
2056 tprintf("%#lx", tcp->u_arg[4]);
2057 else
2058 printrusage(tcp, tcp->u_arg[4]);
2059 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002060 }
2061 return 0;
2062}
2063
Roland McGrathc74c0b72004-09-01 19:39:46 +00002064#endif /* SVR4 or LINUX */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002065
2066int
2067sys_alarm(tcp)
2068struct tcb *tcp;
2069{
2070 if (entering(tcp))
2071 tprintf("%lu", tcp->u_arg[0]);
2072 return 0;
2073}
2074
2075int
2076sys_uname(tcp)
2077struct tcb *tcp;
2078{
2079 struct utsname uname;
2080
2081 if (exiting(tcp)) {
2082 if (syserror(tcp) || !verbose(tcp))
2083 tprintf("%#lx", tcp->u_arg[0]);
2084 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2085 tprintf("{...}");
2086 else if (!abbrev(tcp)) {
2087
2088 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2089 uname.sysname, uname.nodename);
2090 tprintf("release=\"%s\", version=\"%s\", ",
2091 uname.release, uname.version);
2092 tprintf("machine=\"%s\"", uname.machine);
2093#ifdef LINUX
2094#ifndef __GLIBC__
2095 tprintf(", domainname=\"%s\"", uname.domainname);
2096#endif /* __GLIBC__ */
2097#endif /* LINUX */
2098 tprintf("}");
2099 }
2100 else
2101 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2102 uname.sysname, uname.nodename);
2103 }
2104 return 0;
2105}
2106
2107#ifndef SVR4
2108
Roland McGrathd9f816f2004-09-04 03:39:20 +00002109static const struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002110#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002111 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2112 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2113 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2114 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2115 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2116 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2117 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2118 { PTRACE_CONT, "PTRACE_CONT" },
2119 { PTRACE_KILL, "PTRACE_KILL" },
2120 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2121 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2122 { PTRACE_DETACH, "PTRACE_DETACH" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002123#ifdef PTRACE_GETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002124 { PTRACE_GETREGS, "PTRACE_GETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002125#endif
2126#ifdef PTRACE_SETREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002127 { PTRACE_SETREGS, "PTRACE_SETREGS" },
Roland McGrathbf621d42003-01-14 09:46:21 +00002128#endif
2129#ifdef PTRACE_GETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002130 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002131#endif
2132#ifdef PTRACE_SETFPREGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002133 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
Roland McGrathbf621d42003-01-14 09:46:21 +00002134#endif
2135#ifdef PTRACE_GETFPXREGS
2136 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2137#endif
2138#ifdef PTRACE_SETFPXREGS
2139 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2140#endif
2141#ifdef SUNOS4
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002142 { PTRACE_READDATA, "PTRACE_READDATA" },
2143 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2144 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2145 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2146 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2147 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2148#ifdef SPARC
2149 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2150 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2151#else /* !SPARC */
2152 { PTRACE_22, "PTRACE_PTRACE_22" },
2153 { PTRACE_23, "PTRACE_PTRACE_23" },
2154#endif /* !SPARC */
2155#endif /* SUNOS4 */
2156 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2157#ifdef SUNOS4
2158 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2159#ifdef I386
2160 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2161 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2162 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2163#else /* !I386 */
2164 { PTRACE_26, "PTRACE_26" },
2165 { PTRACE_27, "PTRACE_27" },
2166 { PTRACE_28, "PTRACE_28" },
2167#endif /* !I386 */
2168 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2169#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002170#else /* FREEBSD */
2171 { PT_TRACE_ME, "PT_TRACE_ME" },
2172 { PT_READ_I, "PT_READ_I" },
2173 { PT_READ_D, "PT_READ_D" },
2174 { PT_WRITE_I, "PT_WRITE_I" },
2175 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00002176#ifdef PT_READ_U
2177 { PT_READ_U, "PT_READ_U" },
2178#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002179 { PT_CONTINUE, "PT_CONTINUE" },
2180 { PT_KILL, "PT_KILL" },
2181 { PT_STEP, "PT_STEP" },
2182 { PT_ATTACH, "PT_ATTACH" },
2183 { PT_DETACH, "PT_DETACH" },
2184 { PT_GETREGS, "PT_GETREGS" },
2185 { PT_SETREGS, "PT_SETREGS" },
2186 { PT_GETFPREGS, "PT_GETFPREGS" },
2187 { PT_SETFPREGS, "PT_SETFPREGS" },
2188 { PT_GETDBREGS, "PT_GETDBREGS" },
2189 { PT_SETDBREGS, "PT_SETDBREGS" },
2190#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002191 { 0, NULL },
2192};
2193
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002194#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002195#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2196static
2197#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
Roland McGrathd9f816f2004-09-04 03:39:20 +00002198const struct xlat struct_user_offsets[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002199#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00002200#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002201 { PT_PSWMASK, "psw_mask" },
2202 { PT_PSWADDR, "psw_addr" },
2203 { PT_GPR0, "gpr0" },
2204 { PT_GPR1, "gpr1" },
2205 { PT_GPR2, "gpr2" },
2206 { PT_GPR3, "gpr3" },
2207 { PT_GPR4, "gpr4" },
2208 { PT_GPR5, "gpr5" },
2209 { PT_GPR6, "gpr6" },
2210 { PT_GPR7, "gpr7" },
2211 { PT_GPR8, "gpr8" },
2212 { PT_GPR9, "gpr9" },
2213 { PT_GPR10, "gpr10" },
2214 { PT_GPR11, "gpr11" },
2215 { PT_GPR12, "gpr12" },
2216 { PT_GPR13, "gpr13" },
2217 { PT_GPR14, "gpr14" },
2218 { PT_GPR15, "gpr15" },
2219 { PT_ACR0, "acr0" },
2220 { PT_ACR1, "acr1" },
2221 { PT_ACR2, "acr2" },
2222 { PT_ACR3, "acr3" },
2223 { PT_ACR4, "acr4" },
2224 { PT_ACR5, "acr5" },
2225 { PT_ACR6, "acr6" },
2226 { PT_ACR7, "acr7" },
2227 { PT_ACR8, "acr8" },
2228 { PT_ACR9, "acr9" },
2229 { PT_ACR10, "acr10" },
2230 { PT_ACR11, "acr11" },
2231 { PT_ACR12, "acr12" },
2232 { PT_ACR13, "acr13" },
2233 { PT_ACR14, "acr14" },
2234 { PT_ACR15, "acr15" },
2235 { PT_ORIGGPR2, "orig_gpr2" },
2236 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002237#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002238 { PT_FPR0_HI, "fpr0.hi" },
2239 { PT_FPR0_LO, "fpr0.lo" },
2240 { PT_FPR1_HI, "fpr1.hi" },
2241 { PT_FPR1_LO, "fpr1.lo" },
2242 { PT_FPR2_HI, "fpr2.hi" },
2243 { PT_FPR2_LO, "fpr2.lo" },
2244 { PT_FPR3_HI, "fpr3.hi" },
2245 { PT_FPR3_LO, "fpr3.lo" },
2246 { PT_FPR4_HI, "fpr4.hi" },
2247 { PT_FPR4_LO, "fpr4.lo" },
2248 { PT_FPR5_HI, "fpr5.hi" },
2249 { PT_FPR5_LO, "fpr5.lo" },
2250 { PT_FPR6_HI, "fpr6.hi" },
2251 { PT_FPR6_LO, "fpr6.lo" },
2252 { PT_FPR7_HI, "fpr7.hi" },
2253 { PT_FPR7_LO, "fpr7.lo" },
2254 { PT_FPR8_HI, "fpr8.hi" },
2255 { PT_FPR8_LO, "fpr8.lo" },
2256 { PT_FPR9_HI, "fpr9.hi" },
2257 { PT_FPR9_LO, "fpr9.lo" },
2258 { PT_FPR10_HI, "fpr10.hi" },
2259 { PT_FPR10_LO, "fpr10.lo" },
2260 { PT_FPR11_HI, "fpr11.hi" },
2261 { PT_FPR11_LO, "fpr11.lo" },
2262 { PT_FPR12_HI, "fpr12.hi" },
2263 { PT_FPR12_LO, "fpr12.lo" },
2264 { PT_FPR13_HI, "fpr13.hi" },
2265 { PT_FPR13_LO, "fpr13.lo" },
2266 { PT_FPR14_HI, "fpr14.hi" },
2267 { PT_FPR14_LO, "fpr14.lo" },
2268 { PT_FPR15_HI, "fpr15.hi" },
2269 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002270#endif
2271#if defined(S390X)
2272 { PT_FPR0, "fpr0" },
2273 { PT_FPR1, "fpr1" },
2274 { PT_FPR2, "fpr2" },
2275 { PT_FPR3, "fpr3" },
2276 { PT_FPR4, "fpr4" },
2277 { PT_FPR5, "fpr5" },
2278 { PT_FPR6, "fpr6" },
2279 { PT_FPR7, "fpr7" },
2280 { PT_FPR8, "fpr8" },
2281 { PT_FPR9, "fpr9" },
2282 { PT_FPR10, "fpr10" },
2283 { PT_FPR11, "fpr11" },
2284 { PT_FPR12, "fpr12" },
2285 { PT_FPR13, "fpr13" },
2286 { PT_FPR14, "fpr14" },
2287 { PT_FPR15, "fpr15" },
2288#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002289 { PT_CR_9, "cr9" },
2290 { PT_CR_10, "cr10" },
2291 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002292 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002293#endif
2294#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002295 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002296#elif defined(HPPA)
2297 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002298#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002299#ifndef PT_ORIG_R3
2300#define PT_ORIG_R3 34
2301#endif
Roland McGratheb285352003-01-14 09:59:00 +00002302#define REGSIZE (sizeof(unsigned long))
2303 { REGSIZE*PT_R0, "r0" },
2304 { REGSIZE*PT_R1, "r1" },
2305 { REGSIZE*PT_R2, "r2" },
2306 { REGSIZE*PT_R3, "r3" },
2307 { REGSIZE*PT_R4, "r4" },
2308 { REGSIZE*PT_R5, "r5" },
2309 { REGSIZE*PT_R6, "r6" },
2310 { REGSIZE*PT_R7, "r7" },
2311 { REGSIZE*PT_R8, "r8" },
2312 { REGSIZE*PT_R9, "r9" },
2313 { REGSIZE*PT_R10, "r10" },
2314 { REGSIZE*PT_R11, "r11" },
2315 { REGSIZE*PT_R12, "r12" },
2316 { REGSIZE*PT_R13, "r13" },
2317 { REGSIZE*PT_R14, "r14" },
2318 { REGSIZE*PT_R15, "r15" },
2319 { REGSIZE*PT_R16, "r16" },
2320 { REGSIZE*PT_R17, "r17" },
2321 { REGSIZE*PT_R18, "r18" },
2322 { REGSIZE*PT_R19, "r19" },
2323 { REGSIZE*PT_R20, "r20" },
2324 { REGSIZE*PT_R21, "r21" },
2325 { REGSIZE*PT_R22, "r22" },
2326 { REGSIZE*PT_R23, "r23" },
2327 { REGSIZE*PT_R24, "r24" },
2328 { REGSIZE*PT_R25, "r25" },
2329 { REGSIZE*PT_R26, "r26" },
2330 { REGSIZE*PT_R27, "r27" },
2331 { REGSIZE*PT_R28, "r28" },
2332 { REGSIZE*PT_R29, "r29" },
2333 { REGSIZE*PT_R30, "r30" },
2334 { REGSIZE*PT_R31, "r31" },
2335 { REGSIZE*PT_NIP, "NIP" },
2336 { REGSIZE*PT_MSR, "MSR" },
2337 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2338 { REGSIZE*PT_CTR, "CTR" },
2339 { REGSIZE*PT_LNK, "LNK" },
2340 { REGSIZE*PT_XER, "XER" },
2341 { REGSIZE*PT_CCR, "CCR" },
2342 { REGSIZE*PT_FPR0, "FPR0" },
2343#undef REGSIZE
Roland McGrath5a223472002-12-15 23:58:26 +00002344#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002345#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002346 { 0, "r0" },
2347 { 1, "r1" },
2348 { 2, "r2" },
2349 { 3, "r3" },
2350 { 4, "r4" },
2351 { 5, "r5" },
2352 { 6, "r6" },
2353 { 7, "r7" },
2354 { 8, "r8" },
2355 { 9, "r9" },
2356 { 10, "r10" },
2357 { 11, "r11" },
2358 { 12, "r12" },
2359 { 13, "r13" },
2360 { 14, "r14" },
2361 { 15, "r15" },
2362 { 16, "r16" },
2363 { 17, "r17" },
2364 { 18, "r18" },
2365 { 19, "r19" },
2366 { 20, "r20" },
2367 { 21, "r21" },
2368 { 22, "r22" },
2369 { 23, "r23" },
2370 { 24, "r24" },
2371 { 25, "r25" },
2372 { 26, "r26" },
2373 { 27, "r27" },
2374 { 28, "r28" },
2375 { 29, "gp" },
2376 { 30, "fp" },
2377 { 31, "zero" },
2378 { 32, "fp0" },
2379 { 33, "fp" },
2380 { 34, "fp2" },
2381 { 35, "fp3" },
2382 { 36, "fp4" },
2383 { 37, "fp5" },
2384 { 38, "fp6" },
2385 { 39, "fp7" },
2386 { 40, "fp8" },
2387 { 41, "fp9" },
2388 { 42, "fp10" },
2389 { 43, "fp11" },
2390 { 44, "fp12" },
2391 { 45, "fp13" },
2392 { 46, "fp14" },
2393 { 47, "fp15" },
2394 { 48, "fp16" },
2395 { 49, "fp17" },
2396 { 50, "fp18" },
2397 { 51, "fp19" },
2398 { 52, "fp20" },
2399 { 53, "fp21" },
2400 { 54, "fp22" },
2401 { 55, "fp23" },
2402 { 56, "fp24" },
2403 { 57, "fp25" },
2404 { 58, "fp26" },
2405 { 59, "fp27" },
2406 { 60, "fp28" },
2407 { 61, "fp29" },
2408 { 62, "fp30" },
2409 { 63, "fp31" },
2410 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002411#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002412#ifdef IA64
2413 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2414 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2415 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2416 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2417 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2418 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2419 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2420 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2421 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2422 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2423 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2424 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2425 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2426 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2427 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2428 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2429 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2430 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2431 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2432 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2433 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2434 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2435 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2436 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2437 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2438 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2439 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2440 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2441 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2442 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2443 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2444 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2445 /* switch stack: */
2446 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2447 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2448 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2449 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2450 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2451 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2452 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2453 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2454 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2455 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002456 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2457 { PT_B4, "b4" }, { PT_B5, "b5" },
Roland McGrathca4e10c2004-01-13 10:13:20 +00002458 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002459 /* pt_regs */
Roland McGrathca4e10c2004-01-13 10:13:20 +00002460 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2461 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002462 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2463 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2464 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2465 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2466 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2467 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2468 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2469 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2470 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2471 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2472 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2473 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2474 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2475 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2476 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
Roland McGrathfb1bc072004-03-01 21:29:24 +00002477# ifdef PT_AR_CSD
2478 { PT_AR_CSD, "ar.csd" },
2479# endif
2480# ifdef PT_AR_SSD
2481 { PT_AR_SSD, "ar.ssd" },
2482# endif
Roland McGrathca4e10c2004-01-13 10:13:20 +00002483 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002484#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002485#ifdef I386
2486 { 4*EBX, "4*EBX" },
2487 { 4*ECX, "4*ECX" },
2488 { 4*EDX, "4*EDX" },
2489 { 4*ESI, "4*ESI" },
2490 { 4*EDI, "4*EDI" },
2491 { 4*EBP, "4*EBP" },
2492 { 4*EAX, "4*EAX" },
2493 { 4*DS, "4*DS" },
2494 { 4*ES, "4*ES" },
2495 { 4*FS, "4*FS" },
2496 { 4*GS, "4*GS" },
2497 { 4*ORIG_EAX, "4*ORIG_EAX" },
2498 { 4*EIP, "4*EIP" },
2499 { 4*CS, "4*CS" },
2500 { 4*EFL, "4*EFL" },
2501 { 4*UESP, "4*UESP" },
2502 { 4*SS, "4*SS" },
2503#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002504#ifdef X86_64
2505 { 8*RDI, "8*RDI" },
2506 { 8*RSI, "8*RSI" },
2507 { 8*RDX, "8*RDX" },
2508 { 8*R10, "8*R10" },
2509 { 8*R8, "8*R8" },
2510 { 8*R9, "8*R9" },
2511 { 8*RBX, "8*RBX" },
2512 { 8*RCX, "8*RCX" },
2513 { 8*RBP, "8*RBP" },
2514 { 8*RAX, "8*RAX" },
2515#if 0
2516 { 8*DS, "8*DS" },
2517 { 8*ES, "8*ES" },
2518 { 8*FS, "8*FS" },
2519 { 8*GS, "8*GS" },
2520#endif
2521 { 8*ORIG_RAX, "8*ORIG_EAX" },
2522 { 8*RIP, "8*RIP" },
2523 { 8*CS, "8*CS" },
2524 { 8*EFLAGS, "8*EFL" },
2525 { 8*RSP, "8*RSP" },
2526 { 8*SS, "8*SS" },
2527 { 8*R11, "8*R11" },
2528 { 8*R12, "8*R12" },
2529 { 8*R13, "8*R13" },
2530 { 8*R14, "8*R14" },
2531 { 8*R15, "8*R15" },
2532#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002533#ifdef M68K
2534 { 4*PT_D1, "4*PT_D1" },
2535 { 4*PT_D2, "4*PT_D2" },
2536 { 4*PT_D3, "4*PT_D3" },
2537 { 4*PT_D4, "4*PT_D4" },
2538 { 4*PT_D5, "4*PT_D5" },
2539 { 4*PT_D6, "4*PT_D6" },
2540 { 4*PT_D7, "4*PT_D7" },
2541 { 4*PT_A0, "4*PT_A0" },
2542 { 4*PT_A1, "4*PT_A1" },
2543 { 4*PT_A2, "4*PT_A2" },
2544 { 4*PT_A3, "4*PT_A3" },
2545 { 4*PT_A4, "4*PT_A4" },
2546 { 4*PT_A5, "4*PT_A5" },
2547 { 4*PT_A6, "4*PT_A6" },
2548 { 4*PT_D0, "4*PT_D0" },
2549 { 4*PT_USP, "4*PT_USP" },
2550 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2551 { 4*PT_SR, "4*PT_SR" },
2552 { 4*PT_PC, "4*PT_PC" },
2553#endif /* M68K */
2554#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002555#ifdef SH
2556 { 4*REG_REG0, "4*REG_REG0" },
2557 { 4*(REG_REG0+1), "4*REG_REG1" },
2558 { 4*(REG_REG0+2), "4*REG_REG2" },
2559 { 4*(REG_REG0+3), "4*REG_REG3" },
2560 { 4*(REG_REG0+4), "4*REG_REG4" },
2561 { 4*(REG_REG0+5), "4*REG_REG5" },
2562 { 4*(REG_REG0+6), "4*REG_REG6" },
2563 { 4*(REG_REG0+7), "4*REG_REG7" },
2564 { 4*(REG_REG0+8), "4*REG_REG8" },
2565 { 4*(REG_REG0+9), "4*REG_REG9" },
2566 { 4*(REG_REG0+10), "4*REG_REG10" },
2567 { 4*(REG_REG0+11), "4*REG_REG11" },
2568 { 4*(REG_REG0+12), "4*REG_REG12" },
2569 { 4*(REG_REG0+13), "4*REG_REG13" },
2570 { 4*(REG_REG0+14), "4*REG_REG14" },
2571 { 4*REG_REG15, "4*REG_REG15" },
2572 { 4*REG_PC, "4*REG_PC" },
2573 { 4*REG_PR, "4*REG_PR" },
2574 { 4*REG_SR, "4*REG_SR" },
2575 { 4*REG_GBR, "4*REG_GBR" },
2576 { 4*REG_MACH, "4*REG_MACH" },
2577 { 4*REG_MACL, "4*REG_MACL" },
2578 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2579 { 4*REG_FPUL, "4*REG_FPUL" },
2580 { 4*REG_FPREG0, "4*REG_FPREG0" },
2581 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2582 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2583 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2584 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2585 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2586 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2587 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2588 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2589 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2590 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2591 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2592 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2593 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2594 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2595 { 4*REG_FPREG15, "4*REG_FPREG15" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002596#ifdef REG_XDREG0
Wichert Akkermanccef6372002-05-01 16:39:22 +00002597 { 4*REG_XDREG0, "4*REG_XDREG0" },
2598 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2599 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2600 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2601 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2602 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2603 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2604 { 4*REG_XDREG14, "4*REG_XDREG14" },
Roland McGrathc0f8bbd2003-08-21 09:58:00 +00002605#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002606 { 4*REG_FPSCR, "4*REG_FPSCR" },
2607#endif /* SH */
Roland McGrathf5a47772003-06-26 22:40:42 +00002608#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002609 { 0, "PC(L)" },
2610 { 4, "PC(U)" },
2611 { 8, "SR(L)" },
2612 { 12, "SR(U)" },
2613 { 16, "syscall no.(L)" },
2614 { 20, "syscall_no.(U)" },
2615 { 24, "R0(L)" },
2616 { 28, "R0(U)" },
2617 { 32, "R1(L)" },
2618 { 36, "R1(U)" },
2619 { 40, "R2(L)" },
2620 { 44, "R2(U)" },
2621 { 48, "R3(L)" },
2622 { 52, "R3(U)" },
2623 { 56, "R4(L)" },
2624 { 60, "R4(U)" },
2625 { 64, "R5(L)" },
2626 { 68, "R5(U)" },
2627 { 72, "R6(L)" },
2628 { 76, "R6(U)" },
2629 { 80, "R7(L)" },
2630 { 84, "R7(U)" },
2631 { 88, "R8(L)" },
2632 { 92, "R8(U)" },
2633 { 96, "R9(L)" },
2634 { 100, "R9(U)" },
2635 { 104, "R10(L)" },
2636 { 108, "R10(U)" },
2637 { 112, "R11(L)" },
2638 { 116, "R11(U)" },
2639 { 120, "R12(L)" },
2640 { 124, "R12(U)" },
2641 { 128, "R13(L)" },
2642 { 132, "R13(U)" },
2643 { 136, "R14(L)" },
2644 { 140, "R14(U)" },
2645 { 144, "R15(L)" },
2646 { 148, "R15(U)" },
2647 { 152, "R16(L)" },
2648 { 156, "R16(U)" },
2649 { 160, "R17(L)" },
2650 { 164, "R17(U)" },
2651 { 168, "R18(L)" },
2652 { 172, "R18(U)" },
2653 { 176, "R19(L)" },
2654 { 180, "R19(U)" },
2655 { 184, "R20(L)" },
2656 { 188, "R20(U)" },
2657 { 192, "R21(L)" },
2658 { 196, "R21(U)" },
2659 { 200, "R22(L)" },
2660 { 204, "R22(U)" },
2661 { 208, "R23(L)" },
2662 { 212, "R23(U)" },
2663 { 216, "R24(L)" },
2664 { 220, "R24(U)" },
2665 { 224, "R25(L)" },
2666 { 228, "R25(U)" },
2667 { 232, "R26(L)" },
2668 { 236, "R26(U)" },
2669 { 240, "R27(L)" },
2670 { 244, "R27(U)" },
2671 { 248, "R28(L)" },
2672 { 252, "R28(U)" },
2673 { 256, "R29(L)" },
2674 { 260, "R29(U)" },
2675 { 264, "R30(L)" },
2676 { 268, "R30(U)" },
2677 { 272, "R31(L)" },
2678 { 276, "R31(U)" },
2679 { 280, "R32(L)" },
2680 { 284, "R32(U)" },
2681 { 288, "R33(L)" },
2682 { 292, "R33(U)" },
2683 { 296, "R34(L)" },
2684 { 300, "R34(U)" },
2685 { 304, "R35(L)" },
2686 { 308, "R35(U)" },
2687 { 312, "R36(L)" },
2688 { 316, "R36(U)" },
2689 { 320, "R37(L)" },
2690 { 324, "R37(U)" },
2691 { 328, "R38(L)" },
2692 { 332, "R38(U)" },
2693 { 336, "R39(L)" },
2694 { 340, "R39(U)" },
2695 { 344, "R40(L)" },
2696 { 348, "R40(U)" },
2697 { 352, "R41(L)" },
2698 { 356, "R41(U)" },
2699 { 360, "R42(L)" },
2700 { 364, "R42(U)" },
2701 { 368, "R43(L)" },
2702 { 372, "R43(U)" },
2703 { 376, "R44(L)" },
2704 { 380, "R44(U)" },
2705 { 384, "R45(L)" },
2706 { 388, "R45(U)" },
2707 { 392, "R46(L)" },
2708 { 396, "R46(U)" },
2709 { 400, "R47(L)" },
2710 { 404, "R47(U)" },
2711 { 408, "R48(L)" },
2712 { 412, "R48(U)" },
2713 { 416, "R49(L)" },
2714 { 420, "R49(U)" },
2715 { 424, "R50(L)" },
2716 { 428, "R50(U)" },
2717 { 432, "R51(L)" },
2718 { 436, "R51(U)" },
2719 { 440, "R52(L)" },
2720 { 444, "R52(U)" },
2721 { 448, "R53(L)" },
2722 { 452, "R53(U)" },
2723 { 456, "R54(L)" },
2724 { 460, "R54(U)" },
2725 { 464, "R55(L)" },
2726 { 468, "R55(U)" },
2727 { 472, "R56(L)" },
2728 { 476, "R56(U)" },
2729 { 480, "R57(L)" },
2730 { 484, "R57(U)" },
2731 { 488, "R58(L)" },
2732 { 492, "R58(U)" },
2733 { 496, "R59(L)" },
2734 { 500, "R59(U)" },
2735 { 504, "R60(L)" },
2736 { 508, "R60(U)" },
2737 { 512, "R61(L)" },
2738 { 516, "R61(U)" },
2739 { 520, "R62(L)" },
2740 { 524, "R62(U)" },
2741 { 528, "TR0(L)" },
2742 { 532, "TR0(U)" },
2743 { 536, "TR1(L)" },
2744 { 540, "TR1(U)" },
2745 { 544, "TR2(L)" },
2746 { 548, "TR2(U)" },
2747 { 552, "TR3(L)" },
2748 { 556, "TR3(U)" },
2749 { 560, "TR4(L)" },
2750 { 564, "TR4(U)" },
2751 { 568, "TR5(L)" },
2752 { 572, "TR5(U)" },
2753 { 576, "TR6(L)" },
2754 { 580, "TR6(U)" },
2755 { 584, "TR7(L)" },
2756 { 588, "TR7(U)" },
2757 /* This entry is in case pt_regs contains dregs (depends on
2758 the kernel build options). */
2759 { uoff(regs), "offsetof(struct user, regs)" },
2760 { uoff(fpu), "offsetof(struct user, fpu)" },
2761#endif
Roland McGrath0f87c492003-06-03 23:29:04 +00002762#ifdef ARM
2763 { uoff(regs.ARM_r0), "r0" },
2764 { uoff(regs.ARM_r1), "r1" },
2765 { uoff(regs.ARM_r2), "r2" },
2766 { uoff(regs.ARM_r3), "r3" },
2767 { uoff(regs.ARM_r4), "r4" },
2768 { uoff(regs.ARM_r5), "r5" },
2769 { uoff(regs.ARM_r6), "r6" },
2770 { uoff(regs.ARM_r7), "r7" },
2771 { uoff(regs.ARM_r8), "r8" },
2772 { uoff(regs.ARM_r9), "r9" },
2773 { uoff(regs.ARM_r10), "r10" },
2774 { uoff(regs.ARM_fp), "fp" },
2775 { uoff(regs.ARM_ip), "ip" },
2776 { uoff(regs.ARM_sp), "sp" },
2777 { uoff(regs.ARM_lr), "lr" },
2778 { uoff(regs.ARM_pc), "pc" },
2779 { uoff(regs.ARM_cpsr), "cpsr" },
2780#endif
Wichert Akkermanccef6372002-05-01 16:39:22 +00002781
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002782#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002783 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002784#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002785#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002786 { uoff(i387), "offsetof(struct user, i387)" },
2787#else /* !I386 */
2788#ifdef M68K
2789 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2790#endif /* M68K */
2791#endif /* !I386 */
2792 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2793 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2794 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002795#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002796 { uoff(start_code), "offsetof(struct user, start_code)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002797#endif
Roland McGrathf5a47772003-06-26 22:40:42 +00002798#ifdef SH64
Roland McGrathe1e584b2003-06-02 19:18:58 +00002799 { uoff(start_data), "offsetof(struct user, start_data)" },
2800#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002801#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002802 { uoff(start_stack), "offsetof(struct user, start_stack)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002803#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002804 { uoff(signal), "offsetof(struct user, signal)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002805#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002806 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002807#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002808#if !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002809 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Roland McGrath6d1a65c2004-07-12 07:44:08 +00002810#endif
2811#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002812 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2813#endif
2814 { uoff(magic), "offsetof(struct user, magic)" },
2815 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002816#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002817 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2818#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002819#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002820#endif /* !ALPHA */
2821#endif /* !POWERPC/!SPARC */
2822#endif /* LINUX */
2823#ifdef SUNOS4
2824 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2825 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2826 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2827 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2828 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2829 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2830 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2831 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2832 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2833 { uoff(u_error), "offsetof(struct user, u_error)" },
2834 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2835 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2836 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2837 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2838 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2839 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2840 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2841 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2842 { uoff(u_code), "offsetof(struct user, u_code)" },
2843 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2844 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2845 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2846 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2847 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2848 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2849 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2850 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2851 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2852 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2853 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2854 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2855 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2856 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2857 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2858 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2859 { uoff(u_start), "offsetof(struct user, u_start)" },
2860 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2861 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2862 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2863 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2864 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2865 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2866 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2867 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2868 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2869#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002870#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002871 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002872#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002873 { 0, NULL },
2874};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002875#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002876
2877int
2878sys_ptrace(tcp)
2879struct tcb *tcp;
2880{
Roland McGrathd9f816f2004-09-04 03:39:20 +00002881 const struct xlat *x;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002882 long addr;
2883
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002884 if (entering(tcp)) {
Roland McGrathbf621d42003-01-14 09:46:21 +00002885 printxval(ptrace_cmds, tcp->u_arg[0],
2886#ifndef FREEBSD
2887 "PTRACE_???"
2888#else
2889 "PT_???"
2890#endif
2891 );
2892 tprintf(", %lu, ", tcp->u_arg[1]);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002893 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002894#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002895 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2896 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2897 for (x = struct_user_offsets; x->str; x++) {
2898 if (x->val >= addr)
2899 break;
2900 }
2901 if (!x->str)
2902 tprintf("%#lx, ", addr);
2903 else if (x->val > addr && x != struct_user_offsets) {
2904 x--;
2905 tprintf("%s + %ld, ", x->str, addr - x->val);
2906 }
2907 else
2908 tprintf("%s, ", x->str);
2909 }
2910 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002911#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002912 tprintf("%#lx, ", tcp->u_arg[2]);
2913#ifdef LINUX
2914 switch (tcp->u_arg[0]) {
2915 case PTRACE_PEEKDATA:
2916 case PTRACE_PEEKTEXT:
2917 case PTRACE_PEEKUSER:
2918 break;
2919 case PTRACE_CONT:
2920 case PTRACE_SINGLESTEP:
2921 case PTRACE_SYSCALL:
2922 case PTRACE_DETACH:
2923 printsignal(tcp->u_arg[3]);
2924 break;
2925 default:
2926 tprintf("%#lx", tcp->u_arg[3]);
2927 break;
2928 }
2929 } else {
2930 switch (tcp->u_arg[0]) {
2931 case PTRACE_PEEKDATA:
2932 case PTRACE_PEEKTEXT:
2933 case PTRACE_PEEKUSER:
Roland McGratheb285352003-01-14 09:59:00 +00002934 printnum(tcp, tcp->u_arg[3], "%#lx");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002935 break;
2936 }
2937 }
2938#endif /* LINUX */
2939#ifdef SUNOS4
2940 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2941 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2942 tprintf("%lu, ", tcp->u_arg[3]);
2943 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2944 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2945 tcp->u_arg[0] != PTRACE_READTEXT) {
2946 tprintf("%#lx", tcp->u_arg[3]);
2947 }
2948 } else {
2949 if (tcp->u_arg[0] == PTRACE_READDATA ||
2950 tcp->u_arg[0] == PTRACE_READTEXT) {
2951 tprintf("%lu, ", tcp->u_arg[3]);
2952 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2953 }
2954 }
2955#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002956#ifdef FREEBSD
2957 tprintf("%lu", tcp->u_arg[3]);
2958 }
2959#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002960 return 0;
2961}
2962
2963#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002964
2965#ifdef LINUX
Roland McGrathd9f816f2004-09-04 03:39:20 +00002966static const struct xlat futexops[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00002967 { FUTEX_WAIT, "FUTEX_WAIT" },
2968 { FUTEX_WAKE, "FUTEX_WAKE" },
2969 { FUTEX_FD, "FUTEX_FD" },
Roland McGrath88812d62003-06-26 22:27:23 +00002970 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
Roland McGrath5a223472002-12-15 23:58:26 +00002971 { 0, NULL }
2972};
2973
2974int
2975sys_futex(tcp)
2976struct tcb *tcp;
2977{
2978 if (entering(tcp)) {
2979 tprintf("%p, ", (void *) tcp->u_arg[0]);
Roland McGrath88812d62003-06-26 22:27:23 +00002980 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
Roland McGrath8dfa04a2003-03-05 04:07:55 +00002981 tprintf(", %ld", tcp->u_arg[2]);
2982 if (tcp->u_arg[1] == FUTEX_WAIT) {
2983 tprintf(", ");
2984 printtv(tcp, tcp->u_arg[3]);
Roland McGrath88812d62003-06-26 22:27:23 +00002985 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2986 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
Roland McGrath5a223472002-12-15 23:58:26 +00002987 }
2988 return 0;
2989}
2990
2991static void
Roland McGrath79fbda52004-04-14 02:45:55 +00002992print_affinitylist(tcp, list, len)
2993struct tcb *tcp;
2994long list;
Roland McGrath5a223472002-12-15 23:58:26 +00002995unsigned int len;
2996{
2997 int first = 1;
2998 tprintf(" {");
Roland McGratha2f34962003-05-23 00:14:04 +00002999 while (len >= sizeof (unsigned long)) {
Roland McGrath79fbda52004-04-14 02:45:55 +00003000 unsigned long w;
3001 umove(tcp, list, &w);
3002 tprintf("%s %lx", first ? "" : ",", w);
Roland McGrath5a223472002-12-15 23:58:26 +00003003 first = 0;
3004 len -= sizeof (unsigned long);
Roland McGrath79fbda52004-04-14 02:45:55 +00003005 list += sizeof(unsigned long);
Roland McGrath5a223472002-12-15 23:58:26 +00003006 }
3007 tprintf(" }");
3008}
3009
3010int
3011sys_sched_setaffinity(tcp)
3012struct tcb *tcp;
3013{
3014 if (entering(tcp)) {
3015 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath79fbda52004-04-14 02:45:55 +00003016 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
Roland McGrath5a223472002-12-15 23:58:26 +00003017 }
3018 return 0;
3019}
3020
3021int
3022sys_sched_getaffinity(tcp)
3023struct tcb *tcp;
3024{
3025 if (entering(tcp)) {
3026 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3027 } else {
Roland McGrath79fbda52004-04-14 02:45:55 +00003028 if (tcp->u_rval == -1)
3029 tprintf("%#lx", tcp->u_arg[2]);
3030 else
3031 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
Roland McGrath5a223472002-12-15 23:58:26 +00003032 }
3033 return 0;
3034}
Roland McGrath279d3782004-03-01 20:27:37 +00003035
Roland McGrathd9f816f2004-09-04 03:39:20 +00003036static const struct xlat schedulers[] = {
Roland McGrath279d3782004-03-01 20:27:37 +00003037 { SCHED_OTHER, "SCHED_OTHER" },
3038 { SCHED_RR, "SCHED_RR" },
3039 { SCHED_FIFO, "SCHED_FIFO" },
3040 { 0, NULL }
3041};
3042
3043int
3044sys_sched_getscheduler(tcp)
3045struct tcb *tcp;
3046{
3047 if (entering(tcp)) {
3048 tprintf("%d", (int) tcp->u_arg[0]);
3049 } else if (! syserror(tcp)) {
3050 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3051 if (tcp->auxstr != NULL)
3052 return RVAL_STR;
3053 }
3054 return 0;
3055}
3056
3057int
3058sys_sched_setscheduler(tcp)
3059struct tcb *tcp;
3060{
3061 if (entering(tcp)) {
3062 struct sched_param p;
3063 tprintf("%d, ", (int) tcp->u_arg[0]);
3064 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3065 if (umove(tcp, tcp->u_arg[2], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003066 tprintf(", %#lx", tcp->u_arg[2]);
Roland McGrath279d3782004-03-01 20:27:37 +00003067 else
3068 tprintf(", { %d }", p.__sched_priority);
3069 }
3070 return 0;
3071}
3072
3073int
3074sys_sched_getparam(tcp)
3075struct tcb *tcp;
3076{
3077 if (entering(tcp)) {
3078 tprintf("%d, ", (int) tcp->u_arg[0]);
3079 } else {
3080 struct sched_param p;
3081 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003082 tprintf("%#lx", tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003083 else
3084 tprintf("{ %d }", p.__sched_priority);
3085 }
3086 return 0;
3087}
3088
3089int
3090sys_sched_setparam(tcp)
3091struct tcb *tcp;
3092{
3093 if (entering(tcp)) {
3094 struct sched_param p;
3095 if (umove(tcp, tcp->u_arg[1], &p) < 0)
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003096 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
Roland McGrath279d3782004-03-01 20:27:37 +00003097 else
3098 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3099 }
3100 return 0;
3101}
3102
3103int
3104sys_sched_get_priority_min(tcp)
3105struct tcb *tcp;
3106{
3107 if (entering(tcp)) {
3108 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3109 }
3110 return 0;
3111}
Roland McGrathc2d5eb02005-02-02 04:16:56 +00003112
3113#ifdef X86_64
3114#include <asm/prctl.h>
3115
3116static const struct xlat archvals[] = {
3117 { ARCH_SET_GS, "ARCH_SET_GS" },
3118 { ARCH_SET_FS, "ARCH_SET_FS" },
3119 { ARCH_GET_FS, "ARCH_GET_FS" },
3120 { ARCH_GET_GS, "ARCH_GET_GS" },
3121 { 0, NULL },
3122};
3123
3124int
3125sys_arch_prctl(tcp)
3126struct tcb *tcp;
3127{
3128 if (entering(tcp)) {
3129 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3130 if (tcp->u_arg[0] == ARCH_SET_GS
3131 || tcp->u_arg[0] == ARCH_SET_FS)
3132 tprintf(", %#lx", tcp->u_arg[1]);
3133 } else {
3134 if (tcp->u_arg[0] == ARCH_GET_GS
3135 || tcp->u_arg[0] == ARCH_GET_FS) {
3136 long int v;
3137 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3138 tprintf(", [%#lx]", v);
3139 else
3140 tprintf(", %#lx", tcp->u_arg[1]);
3141 }
3142 }
3143 return 0;
3144}
3145#endif
3146
Roland McGrath5a223472002-12-15 23:58:26 +00003147#endif