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