blob: 14f3273b68e27eec305ee680f3d2265f834841a5 [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
60#ifdef SPARC
61# define fpq kernel_fpq
62# define fq kernel_fq
63# define fpu kernel_fpu
64#endif
65#include <asm/reg.h>
66#ifdef SPARC
67# undef fpq
68# undef fq
Roland McGrath5a223472002-12-15 23:58:26 +000069# undef fpu
Wichert Akkerman00a82ee2001-03-28 20:29:17 +000070#endif
71#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 Akkermanfaf72222000-02-19 23:59:03 +000081#elif defined(HAVE_LINUX_PTRACE_H)
82#undef PTRACE_SYSCALL
83#include <linux/ptrace.h>
Wichert Akkerman15dea971999-10-06 13:06:34 +000084#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000085
Roland McGrath5a223472002-12-15 23:58:26 +000086#ifdef HAVE_LINUX_FUTEX_H
87#include <linux/futex.h>
88#endif
89#if defined LINUX
90# ifndef FUTEX_WAIT
91# define FUTEX_WAIT 0
92# endif
93# ifndef FUTEX_WAKE
94# define FUTEX_WAKE 1
95# endif
96# ifndef FUTEX_FD
97# define FUTEX_FD 2
98# endif
99#endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000100
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000101#ifdef LINUX
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000102#include <asm/posix_types.h>
103#undef GETGROUPS_T
104#define GETGROUPS_T __kernel_gid_t
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000105#endif /* LINUX */
106
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000107#if defined(LINUX) && defined(IA64)
108# include <asm/ptrace_offsets.h>
109# include <asm/rse.h>
110#endif
111
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000112#ifdef HAVE_PRCTL
113#include <sys/prctl.h>
114#endif
115
116#ifndef WCOREDUMP
117#define WCOREDUMP(status) ((status) & 0200)
118#endif
119
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000120/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000121#if defined(HAVE_PRCTL)
122static struct xlat prctl_options[] = {
123#ifdef PR_MAXPROCS
124 { PR_MAXPROCS, "PR_MAXPROCS" },
125#endif
126#ifdef PR_ISBLOCKED
127 { PR_ISBLOCKED, "PR_ISBLOCKED" },
128#endif
129#ifdef PR_SETSTACKSIZE
130 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
131#endif
132#ifdef PR_GETSTACKSIZE
133 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
134#endif
135#ifdef PR_MAXPPROCS
136 { PR_MAXPPROCS, "PR_MAXPPROCS" },
137#endif
138#ifdef PR_UNBLKONEXEC
139 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
140#endif
141#ifdef PR_ATOMICSIM
142 { PR_ATOMICSIM, "PR_ATOMICSIM" },
143#endif
144#ifdef PR_SETEXITSIG
145 { PR_SETEXITSIG, "PR_SETEXITSIG" },
146#endif
147#ifdef PR_RESIDENT
148 { PR_RESIDENT, "PR_RESIDENT" },
149#endif
150#ifdef PR_ATTACHADDR
151 { PR_ATTACHADDR, "PR_ATTACHADDR" },
152#endif
153#ifdef PR_DETACHADDR
154 { PR_DETACHADDR, "PR_DETACHADDR" },
155#endif
156#ifdef PR_TERMCHILD
157 { PR_TERMCHILD, "PR_TERMCHILD" },
158#endif
159#ifdef PR_GETSHMASK
160 { PR_GETSHMASK, "PR_GETSHMASK" },
161#endif
162#ifdef PR_GETNSHARE
163 { PR_GETNSHARE, "PR_GETNSHARE" },
164#endif
165#if defined(PR_SET_PDEATHSIG)
166 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
167#endif
Wichert Akkerman8829a551999-06-11 13:18:40 +0000168#ifdef PR_COREPID
169 { PR_COREPID, "PR_COREPID" },
170#endif
171#ifdef PR_ATTACHADDRPERM
172 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
173#endif
174#ifdef PR_PTHREADEXIT
175 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
176#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000177#ifdef PR_SET_PDEATHSIG
178 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
179#endif
180#ifdef PR_GET_PDEATHSIG
181 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
182#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000183#ifdef PR_GET_UNALIGN
184 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
185#endif
186#ifdef PR_SET_UNALIGN
187 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
188#endif
189#ifdef PR_GET_KEEPCAPS
190 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
191#endif
192#ifdef PR_SET_KEEPCAPS
193 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
194#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000195 { 0, NULL },
196};
197
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000198
199const char *
200unalignctl_string (unsigned int ctl)
201{
202 static char buf[16];
203
204 switch (ctl) {
205#ifdef PR_UNALIGN_NOPRINT
206 case PR_UNALIGN_NOPRINT:
207 return "NOPRINT";
208#endif
209#ifdef PR_UNALIGN_SIGBUS
210 case PR_UNALIGN_SIGBUS:
211 return "SIGBUS";
212#endif
213 default:
214 break;
215 }
216 sprintf(buf, "%x", ctl);
217 return buf;
218}
219
220
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000221int
222sys_prctl(tcp)
223struct tcb *tcp;
224{
225 int i;
226
227 if (entering(tcp)) {
228 printxval(prctl_options, tcp->u_arg[0], "PR_???");
229 switch (tcp->u_arg[0]) {
230#ifdef PR_GETNSHARE
231 case PR_GETNSHARE:
232 break;
233#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000234#ifdef PR_SET_DEATHSIG
235 case PR_GET_PDEATHSIG:
236 break;
237#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000238#ifdef PR_SET_UNALIGN
239 case PR_SET_UNALIGN:
240 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
241 break;
242#endif
243#ifdef PR_GET_UNALIGN
244 case PR_GET_UNALIGN:
245 tprintf(", %#lx", tcp->u_arg[1]);
246 break;
247#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000248 default:
249 for (i = 1; i < tcp->u_nargs; i++)
250 tprintf(", %#lx", tcp->u_arg[i]);
251 break;
252 }
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000253 } else {
254 switch (tcp->u_arg[0]) {
255#ifdef PR_GET_PDEATHSIG
256 case PR_GET_PDEATHSIG:
257 for (i=1; i<tcp->u_nargs; i++)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +0000258 tprintf(", %#lx", tcp->u_arg[i]);
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000259 break;
260#endif
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000261#ifdef PR_SET_UNALIGN
262 case PR_SET_UNALIGN:
263 break;
264#endif
265#ifdef PR_GET_UNALIGN
266 case PR_GET_UNALIGN:
267 {
268 int ctl;
269
270 umove(tcp, tcp->u_arg[1], &ctl);
271 tcp->auxstr = unalignctl_string(ctl);
272 return RVAL_STR;
273 }
274#endif
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +0000275 default:
276 break;
277 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000278 }
279 return 0;
280}
281
282#endif /* HAVE_PRCTL */
283
284int
285sys_gethostid(tcp)
286struct tcb *tcp;
287{
288 if (exiting(tcp))
289 return RVAL_HEX;
290 return 0;
291}
292
293int
294sys_sethostname(tcp)
295struct tcb *tcp;
296{
297 if (entering(tcp)) {
298 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
299 tprintf(", %lu", tcp->u_arg[1]);
300 }
301 return 0;
302}
303
304int
305sys_gethostname(tcp)
306struct tcb *tcp;
307{
308 if (exiting(tcp)) {
309 if (syserror(tcp))
310 tprintf("%#lx", tcp->u_arg[0]);
311 else
312 printpath(tcp, tcp->u_arg[0]);
313 tprintf(", %lu", tcp->u_arg[1]);
314 }
315 return 0;
316}
317
318int
319sys_setdomainname(tcp)
320struct tcb *tcp;
321{
322 if (entering(tcp)) {
323 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
324 tprintf(", %lu", tcp->u_arg[1]);
325 }
326 return 0;
327}
328
Wichert Akkerman5daa0281999-03-15 19:49:42 +0000329#if !defined(LINUX)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000330
331int
332sys_getdomainname(tcp)
333struct tcb *tcp;
334{
335 if (exiting(tcp)) {
336 if (syserror(tcp))
337 tprintf("%#lx", tcp->u_arg[0]);
338 else
339 printpath(tcp, tcp->u_arg[0]);
340 tprintf(", %lu", tcp->u_arg[1]);
341 }
342 return 0;
343}
344#endif /* !LINUX */
345
346int
347sys_exit(tcp)
348struct tcb *tcp;
349{
350 if (exiting(tcp)) {
351 fprintf(stderr, "_exit returned!\n");
352 return -1;
353 }
354 /* special case: we stop tracing this process, finish line now */
355 tprintf("%ld) ", tcp->u_arg[0]);
356 tabto(acolumn);
357 tprintf("= ?");
358 printtrailer(tcp);
359 return 0;
360}
361
362int
363internal_exit(tcp)
364struct tcb *tcp;
365{
366 if (entering(tcp))
367 tcp->flags |= TCB_EXITING;
368 return 0;
369}
370
Roland McGrathee9d4352002-12-18 04:16:10 +0000371/* TCP is creating a child we want to follow.
372 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
373 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
374static int
375fork_tcb(struct tcb *tcp)
376{
377 if (nprocs == tcbtabsize) {
378 /* Allocate some more TCBs and expand the table.
379 We don't want to relocate the TCBs because our
380 callers have pointers and it would be a pain.
381 So tcbtab is a table of pointers. Since we never
382 free the TCBs, we allocate a single chunk of many. */
383 struct tcb **newtab = (struct tcb **)
384 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
385 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
386 sizeof *newtcbs);
387 int i;
388 if (newtab == NULL || newtcbs == NULL) {
389 if (newtab != NULL)
390 free(newtab);
391 tcp->flags &= ~TCB_FOLLOWFORK;
392 fprintf(stderr, "sys_fork: tcb table full\n");
393 return 1;
394 }
395 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
396 newtab[i] = &newtcbs[i - tcbtabsize];
397 tcbtabsize *= 2;
398 tcbtab = newtab;
399 }
400
401 tcp->flags |= TCB_FOLLOWFORK;
402 return 0;
403}
404
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000405#ifdef USE_PROCFS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000406
407int
408sys_fork(tcp)
409struct tcb *tcp;
410{
411 if (exiting(tcp)) {
412 if (getrval2(tcp)) {
413 tcp->auxstr = "child process";
414 return RVAL_UDECIMAL | RVAL_STR;
415 }
416 }
417 return 0;
418}
419
John Hughes4e36a812001-04-18 15:11:51 +0000420#if UNIXWARE > 2
421
422int
423sys_rfork(tcp)
424struct tcb *tcp;
425{
426 if (entering(tcp)) {
427 tprintf ("%ld", tcp->u_arg[0]);
428 }
429 else {
430 if (getrval2(tcp)) {
431 tcp->auxstr = "child process";
432 return RVAL_UDECIMAL | RVAL_STR;
433 }
434 }
435 return 0;
436}
437
438#endif
439
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000440int
441internal_fork(tcp)
442struct tcb *tcp;
443{
444 struct tcb *tcpchild;
445
446 if (exiting(tcp)) {
447 if (getrval2(tcp))
448 return 0;
449 if (!followfork)
450 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000451 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000452 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000453 if (syserror(tcp))
454 return 0;
455 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
456 fprintf(stderr, "sys_fork: tcb table full\n");
457 return 0;
458 }
Wichert Akkerman2e4ffe52000-09-03 23:57:48 +0000459 if (proc_open(tcpchild, 2) < 0)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000460 droptcb(tcpchild);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000461 }
462 return 0;
463}
464
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000465#else /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000466
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000467#ifdef LINUX
468
469/* defines copied from linux/sched.h since we can't include that
470 * ourselves (it conflicts with *lots* of libc includes)
471 */
472#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
473#define CLONE_VM 0x00000100 /* set if VM shared between processes */
474#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
475#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
476#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
Roland McGrath909875b2002-12-22 03:34:36 +0000477#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000478#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
479#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
480#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
Roland McGrath909875b2002-12-22 03:34:36 +0000481#define CLONE_THREAD 0x00010000 /* Same thread group? */
482#define CLONE_NEWNS 0x00020000 /* New namespace group? */
483#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
484#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
485#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
486#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
487#define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
488#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
489#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000490
491static struct xlat clone_flags[] = {
492 { CLONE_VM, "CLONE_VM" },
493 { CLONE_FS, "CLONE_FS" },
494 { CLONE_FILES, "CLONE_FILES" },
495 { CLONE_SIGHAND, "CLONE_SIGHAND" },
Roland McGrath909875b2002-12-22 03:34:36 +0000496 { CLONE_IDLETASK, "CLONE_IDLETASK"},
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000497 { CLONE_PTRACE, "CLONE_PTRACE" },
498 { CLONE_VFORK, "CLONE_VFORK" },
499 { CLONE_PARENT, "CLONE_PARENT" },
Roland McGrath909875b2002-12-22 03:34:36 +0000500 { CLONE_THREAD, "CLONE_THREAD" },
501 { CLONE_NEWNS, "CLONE_NEWNS" },
502 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
503 { CLONE_SETTLS, "CLONE_SETTLS" },
504 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
505 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
506 { CLONE_DETACHED, "CLONE_DETACHED" },
507 { CLONE_UNTRACED, "CLONE_UNTRACED" },
508 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000509 { 0, NULL },
510};
511
Roland McGrath909875b2002-12-22 03:34:36 +0000512# ifdef I386
513# include <asm/ldt.h>
514extern void print_ldt_entry();
515# endif
516
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000517int
518sys_clone(tcp)
519struct tcb *tcp;
520{
521 if (exiting(tcp)) {
522 tprintf("child_stack=%#lx, flags=", tcp->u_arg[1]);
523 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
524 tprintf("0");
Roland McGrath909875b2002-12-22 03:34:36 +0000525 if ((tcp->u_arg[0] & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
526 |CLONE_SETTLS)) == 0)
527 return 0;
528 if (tcp->u_arg[0] & CLONE_PARENT_SETTID) {
529 int pid;
530 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
531 tprintf(", [%d]", pid);
532 else
533 tprintf(", %#lx", tcp->u_arg[2]);
534 }
535 else
536 tprintf(", <ignored>");
537#ifdef I386
538 if (tcp->u_arg[0] & CLONE_SETTLS) {
539 struct modify_ldt_ldt_s copy;
540 if (umove(tcp, tcp->u_arg[3], &copy) != -1) {
541 tprintf(", {entry_number:%d, ",
542 copy.entry_number);
543 if (!verbose(tcp))
544 tprintf("...}");
545 else
546 print_ldt_entry(&copy);
547 }
548 else
549 tprintf(", %#lx", tcp->u_arg[3]);
550 }
551 else
552 tprintf(", <ignored>");
553# define TIDARG 4
554#else
555# define TIDARG 3
556#endif
557 if (tcp->u_arg[0] & CLONE_CHILD_SETTID)
558 tprintf(", %#lx", tcp->u_arg[TIDARG]);
559#undef TIDARG
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000560 }
561 return 0;
562}
563
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000564int
565sys_clone2(tcp)
566struct tcb *tcp;
567{
568 if (exiting(tcp)) {
569 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
570 tcp->u_arg[1], tcp->u_arg[2]);
571 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
572 tprintf("0");
573 }
574 return 0;
575}
576
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000577#endif
578
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000579int
580sys_fork(tcp)
581struct tcb *tcp;
582{
583 if (exiting(tcp))
584 return RVAL_UDECIMAL;
585 return 0;
586}
587
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000588int
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000589change_syscall(tcp, new)
590struct tcb *tcp;
591int new;
592{
593#if defined(LINUX)
594#if defined(I386)
595 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000596 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000597 return -1;
598 return 0;
Michal Ludvig0e035502002-09-23 15:41:01 +0000599#elif defined(X86_64)
600 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000601 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
Michal Ludvig0e035502002-09-23 15:41:01 +0000602 return -1;
603 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000604#elif defined(POWERPC)
Wichert Akkerman5c4c69b2001-04-12 09:00:47 +0000605 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R0), new) < 0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000606 return -1;
Michal Ludvig10a88d02002-10-07 14:31:00 +0000607#elif defined(S390) || defined(S390X)
608 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
609 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
610 return -1;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000611 return 0;
612#elif defined(M68K)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000613 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000614 return -1;
615 return 0;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000616#elif defined(SPARC)
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000617 struct regs regs;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000618 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)&regs, 0)<0)
619 return -1;
Wichert Akkerman00a82ee2001-03-28 20:29:17 +0000620 regs.r_g1=new;
Wichert Akkerman5ae21ea2000-05-01 01:53:59 +0000621 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)&regs, 0)<0)
622 return -1;
623 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000624#elif defined(MIPS)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000625 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000626 return -1;
627 return 0;
628#elif defined(ALPHA)
Wichert Akkermanc7926982000-04-10 22:22:31 +0000629 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000630 return -1;
631 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000632#elif defined(IA64)
633 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
634 return -1;
635 return 0;
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000636#elif defined(HPPA)
637 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
638 return -1;
639 return 0;
Wichert Akkermanccef6372002-05-01 16:39:22 +0000640#elif defined(SH)
641 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
642 return -1;
643 return 0;
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000644#else
645#warning Do not know how to handle change_syscall for this architecture
646#endif /* architecture */
647#endif /* LINUX */
648 return -1;
649}
650
651int
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000652setarg(tcp, argnum)
653 struct tcb *tcp;
654 int argnum;
655{
656#if defined (IA64)
657 {
658 unsigned long *bsp, *ap;
659
660 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
661 return -1;
662
663 ap = ia64_rse_skip_regs(bsp, argnum);
664 errno = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000665 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000666 if (errno)
667 return -1;
668
669 }
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000670#elif defined(I386)
671 {
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000672 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
Wichert Akkerman12f75d12000-02-14 16:23:40 +0000673 if (errno)
674 return -1;
675 }
Michal Ludvig0e035502002-09-23 15:41:01 +0000676#elif defined(X86_64)
677 {
678 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
679 if (errno)
680 return -1;
681 }
Roland McGrath3bb9c3d2002-12-16 20:40:48 +0000682#elif defined(POWERPC)
683#ifndef PT_ORIG_R3
684#define PT_ORIG_R3 34
685#endif
686 {
687 ptrace(PTRACE_POKEUSER, tcp->pid,
688 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*4),
689 tcp->u_arg[argnum]);
690 if (errno)
691 return -1;
692 }
Ralf Baechlee3816102000-08-01 00:06:06 +0000693#elif defined(MIPS)
694 {
695 errno = 0;
696 if (argnum < 4)
697 ptrace(PTRACE_POKEUSER, tcp->pid,
698 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
699 else {
700 unsigned long *sp;
701
702 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
703 return -1;
704
705 ptrace(PTRACE_POKEDATA, tcp->pid,
706 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
707 }
708 if (errno)
709 return -1;
710 }
Michal Ludvig10a88d02002-10-07 14:31:00 +0000711#elif defined(S390) || defined(S390X)
712 {
713 if(argnum <= 5)
714 ptrace(PTRACE_POKEUSER, tcp->pid,
Roland McGrath5a223472002-12-15 23:58:26 +0000715 (char *) (argnum==0 ? PT_ORIGGPR2 :
716 PT_GPR2 + argnum*sizeof(long)),
Michal Ludvig10a88d02002-10-07 14:31:00 +0000717 tcp->u_arg[argnum]);
718 else
719 return -E2BIG;
720 if (errno)
721 return -1;
722 }
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000723#else
Wichert Akkermanfaf72222000-02-19 23:59:03 +0000724# warning Sorry, setargs not implemented for this architecture.
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000725#endif
726 return 0;
727}
728
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000729#ifdef SYS_clone
730int
731internal_clone(tcp)
732struct tcb *tcp;
733{
Ulrich Drepper90512f01999-12-24 07:22:25 +0000734 struct tcb *tcpchild;
735 int pid;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000736 if (entering(tcp)) {
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +0000737 if (!followfork)
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000738 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000739 if (fork_tcb(tcp))
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000740 return 0;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000741 if (setbpt(tcp) < 0)
742 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000743 } else {
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000744 int bpt = tcp->flags & TCB_BPTSET;
745
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000746 if (!(tcp->flags & TCB_FOLLOWFORK))
747 return 0;
748
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000749 if (syserror(tcp)) {
750 if (bpt)
751 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000752 return 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000753 }
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000754
755 pid = tcp->u_rval;
756 if ((tcpchild = alloctcb(pid)) == NULL) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000757 if (bpt)
758 clearbpt(tcp);
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000759 fprintf(stderr, " [tcb table full]\n");
760 kill(pid, SIGKILL); /* XXX */
761 return 0;
762 }
763
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000764 /* Attach to the new child */
765 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000766 if (bpt)
767 clearbpt(tcp);
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000768 perror("PTRACE_ATTACH");
769 fprintf(stderr, "Too late?\n");
770 droptcb(tcpchild);
771 return 0;
772 }
773
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000774 if (bpt)
775 clearbpt(tcp);
776
Ulrich Drepper90512f01999-12-24 07:22:25 +0000777 tcpchild->flags |= TCB_ATTACHED;
Wichert Akkerman9b0c31d2000-09-03 21:56:29 +0000778 if (bpt) {
779 tcpchild->flags |= TCB_BPTSET;
780 tcpchild->baddr = tcp->baddr;
781 memcpy(tcpchild->inst, tcp->inst,
782 sizeof tcpchild->inst);
783 }
Ulrich Drepper90512f01999-12-24 07:22:25 +0000784 newoutf(tcpchild);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +0000785 tcpchild->parent = tcp;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000786 tcp->nchildren++;
787 if (!qflag)
788 fprintf(stderr, "Process %d attached\n", pid);
789 }
790 return 0;
791}
792#endif
793
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000794int
795internal_fork(tcp)
796struct tcb *tcp;
797{
798 struct tcb *tcpchild;
799 int pid;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000800 int dont_follow = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000801
802#ifdef SYS_vfork
Nate Sammonsccd8f211999-03-29 22:57:54 +0000803 if (tcp->scno == SYS_vfork) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000804 /* Attempt to make vfork into fork, which we can follow. */
Roland McGrath5a223472002-12-15 23:58:26 +0000805 if (!followvfork ||
Pavel Machek9a9f10b2000-02-01 16:22:52 +0000806 change_syscall(tcp, SYS_fork) < 0)
Nate Sammonsccd8f211999-03-29 22:57:54 +0000807 dont_follow = 1;
Nate Sammonsccd8f211999-03-29 22:57:54 +0000808 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000809#endif
810 if (entering(tcp)) {
Nate Sammonsccd8f211999-03-29 22:57:54 +0000811 if (!followfork || dont_follow)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000812 return 0;
Roland McGrathee9d4352002-12-18 04:16:10 +0000813 if (fork_tcb(tcp))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000814 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000815 if (setbpt(tcp) < 0)
816 return 0;
Wichert Akkerman7a0b6491999-12-23 15:08:17 +0000817 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000818 else {
819 int bpt = tcp->flags & TCB_BPTSET;
820
821 if (!(tcp->flags & TCB_FOLLOWFORK))
822 return 0;
823 if (bpt)
824 clearbpt(tcp);
825
826 if (syserror(tcp))
827 return 0;
828
829 pid = tcp->u_rval;
830 if ((tcpchild = alloctcb(pid)) == NULL) {
831 fprintf(stderr, " [tcb table full]\n");
832 kill(pid, SIGKILL); /* XXX */
833 return 0;
834 }
835#ifdef LINUX
Wichert Akkermanc1652e22001-03-27 12:17:16 +0000836#ifdef HPPA
837 /* The child must have run before it can be attached. */
838 /* This must be a bug in the parisc kernel, but I havn't
839 * identified it yet. Seems to be an issue associated
840 * with attaching to a process (which sends it a signal)
841 * before that process has ever been scheduled. When
842 * debugging, I started seeing crashes in
843 * arch/parisc/kernel/signal.c:do_signal(), apparently
844 * caused by r8 getting corrupt over the dequeue_signal()
845 * call. Didn't make much sense though...
846 */
847 {
848 struct timeval tv;
849 tv.tv_sec = 0;
850 tv.tv_usec = 10000;
851 select(0, NULL, NULL, NULL, &tv);
852 }
853#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000854 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
855 perror("PTRACE_ATTACH");
856 fprintf(stderr, "Too late?\n");
857 droptcb(tcpchild);
858 return 0;
859 }
860#endif /* LINUX */
861#ifdef SUNOS4
862#ifdef oldway
863 /* The child must have run before it can be attached. */
864 {
865 struct timeval tv;
866 tv.tv_sec = 0;
867 tv.tv_usec = 10000;
868 select(0, NULL, NULL, NULL, &tv);
869 }
870 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
871 perror("PTRACE_ATTACH");
872 fprintf(stderr, "Too late?\n");
873 droptcb(tcpchild);
874 return 0;
875 }
876#else /* !oldway */
877 /* Try to catch the new process as soon as possible. */
878 {
879 int i;
880 for (i = 0; i < 1024; i++)
881 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
882 break;
883 if (i == 1024) {
884 perror("PTRACE_ATTACH");
885 fprintf(stderr, "Too late?\n");
886 droptcb(tcpchild);
887 return 0;
888 }
889 }
890#endif /* !oldway */
891#endif /* SUNOS4 */
892 tcpchild->flags |= TCB_ATTACHED;
893 /* Child has BPT too, must be removed on first occasion */
894 if (bpt) {
895 tcpchild->flags |= TCB_BPTSET;
896 tcpchild->baddr = tcp->baddr;
897 memcpy(tcpchild->inst, tcp->inst,
898 sizeof tcpchild->inst);
899 }
900 newoutf(tcpchild);
901 tcpchild->parent = tcp;
902 tcp->nchildren++;
903 if (!qflag)
904 fprintf(stderr, "Process %d attached\n", pid);
905 }
906 return 0;
907}
908
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000909#endif /* !USE_PROCFS */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000910
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000911#if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000912
913int
914sys_vfork(tcp)
915struct tcb *tcp;
916{
917 if (exiting(tcp))
918 return RVAL_UDECIMAL;
919 return 0;
920}
921
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000922#endif /* SUNOS4 || LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000923
924#ifndef LINUX
925
926static char idstr[16];
927
928int
929sys_getpid(tcp)
930struct tcb *tcp;
931{
932 if (exiting(tcp)) {
933 sprintf(idstr, "ppid %lu", getrval2(tcp));
934 tcp->auxstr = idstr;
935 return RVAL_STR;
936 }
937 return 0;
938}
939
940int
941sys_getuid(tcp)
942struct tcb *tcp;
943{
944 if (exiting(tcp)) {
945 sprintf(idstr, "euid %lu", getrval2(tcp));
946 tcp->auxstr = idstr;
947 return RVAL_STR;
948 }
949 return 0;
950}
951
952int
953sys_getgid(tcp)
954struct tcb *tcp;
955{
956 if (exiting(tcp)) {
957 sprintf(idstr, "egid %lu", getrval2(tcp));
958 tcp->auxstr = idstr;
959 return RVAL_STR;
960 }
961 return 0;
962}
963
964#endif /* !LINUX */
965
966#ifdef LINUX
967
968int
969sys_setuid(tcp)
970struct tcb *tcp;
971{
972 if (entering(tcp)) {
973 tprintf("%u", (uid_t) tcp->u_arg[0]);
974 }
975 return 0;
976}
977
978int
979sys_setgid(tcp)
980struct tcb *tcp;
981{
982 if (entering(tcp)) {
983 tprintf("%u", (gid_t) tcp->u_arg[0]);
984 }
985 return 0;
986}
987
988int
989sys_getresuid(tcp)
990 struct tcb *tcp;
991{
992 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +0000993 __kernel_uid_t uid;
994 if (syserror(tcp))
995 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
996 tcp->u_arg[1], tcp->u_arg[2]);
997 else {
998 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
999 tprintf("%#lx, ", tcp->u_arg[0]);
1000 else
1001 tprintf("ruid %lu, ", (unsigned long) uid);
1002 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1003 tprintf("%#lx, ", tcp->u_arg[0]);
1004 else
1005 tprintf("euid %lu, ", (unsigned long) uid);
1006 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1007 tprintf("%#lx", tcp->u_arg[0]);
1008 else
1009 tprintf("suid %lu", (unsigned long) uid);
1010 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001011 }
1012 return 0;
1013}
1014
1015int
1016sys_getresgid(tcp)
1017struct tcb *tcp;
1018{
1019 if (exiting(tcp)) {
Wichert Akkerman2e2553a1999-05-09 00:29:58 +00001020 __kernel_gid_t gid;
1021 if (syserror(tcp))
1022 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1023 tcp->u_arg[1], tcp->u_arg[2]);
1024 else {
1025 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1026 tprintf("%#lx, ", tcp->u_arg[0]);
1027 else
1028 tprintf("rgid %lu, ", (unsigned long) gid);
1029 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1030 tprintf("%#lx, ", tcp->u_arg[0]);
1031 else
1032 tprintf("egid %lu, ", (unsigned long) gid);
1033 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1034 tprintf("%#lx", tcp->u_arg[0]);
1035 else
1036 tprintf("sgid %lu", (unsigned long) gid);
1037 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001038 }
1039 return 0;
1040}
1041
1042#endif /* LINUX */
1043
1044int
1045sys_setreuid(tcp)
1046struct tcb *tcp;
1047{
1048 if (entering(tcp)) {
1049 tprintf("%lu, %lu",
1050 (unsigned long) (uid_t) tcp->u_arg[0],
1051 (unsigned long) (uid_t) tcp->u_arg[1]);
1052 }
1053 return 0;
1054}
1055
1056int
1057sys_setregid(tcp)
1058struct tcb *tcp;
1059{
1060 if (entering(tcp)) {
1061 tprintf("%lu, %lu",
1062 (unsigned long) (gid_t) tcp->u_arg[0],
1063 (unsigned long) (gid_t) tcp->u_arg[1]);
1064 }
1065 return 0;
1066}
1067
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001068#if defined(LINUX) || defined(FREEBSD)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001069int
1070sys_setresuid(tcp)
1071 struct tcb *tcp;
1072{
1073 if (entering(tcp)) {
1074 tprintf("ruid %u, euid %u, suid %u",
1075 (uid_t) tcp->u_arg[0],
1076 (uid_t) tcp->u_arg[1],
1077 (uid_t) tcp->u_arg[2]);
1078 }
1079 return 0;
1080}
1081int
1082sys_setresgid(tcp)
1083 struct tcb *tcp;
1084{
1085 if (entering(tcp)) {
1086 tprintf("rgid %u, egid %u, sgid %u",
1087 (uid_t) tcp->u_arg[0],
1088 (uid_t) tcp->u_arg[1],
1089 (uid_t) tcp->u_arg[2]);
1090 }
1091 return 0;
1092}
1093
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001094#endif /* LINUX || FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001095
1096int
1097sys_setgroups(tcp)
1098struct tcb *tcp;
1099{
1100 int i, len;
1101 GETGROUPS_T *gidset;
1102
1103 if (entering(tcp)) {
1104 len = tcp->u_arg[0];
1105 tprintf("%u, ", len);
1106 if (len <= 0) {
1107 tprintf("[]");
1108 return 0;
1109 }
1110 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1111 if (gidset == NULL) {
1112 fprintf(stderr, "sys_setgroups: out of memory\n");
1113 return -1;
1114 }
1115 if (!verbose(tcp))
1116 tprintf("%#lx", tcp->u_arg[1]);
1117 else if (umoven(tcp, tcp->u_arg[1],
1118 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1119 tprintf("[?]");
1120 else {
1121 tprintf("[");
1122 for (i = 0; i < len; i++)
1123 tprintf("%s%lu", i ? ", " : "",
1124 (unsigned long) gidset[i]);
1125 tprintf("]");
1126 }
1127 free((char *) gidset);
1128 }
1129 return 0;
1130}
1131
1132int
1133sys_getgroups(tcp)
1134struct tcb *tcp;
1135{
1136 int i, len;
1137 GETGROUPS_T *gidset;
1138
1139 if (entering(tcp)) {
1140 len = tcp->u_arg[0];
1141 tprintf("%u, ", len);
1142 } else {
1143 len = tcp->u_rval;
1144 if (len <= 0) {
1145 tprintf("[]");
1146 return 0;
1147 }
1148 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1149 if (gidset == NULL) {
1150 fprintf(stderr, "sys_getgroups: out of memory\n");
1151 return -1;
1152 }
1153 if (!tcp->u_arg[1])
1154 tprintf("NULL");
1155 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1156 tprintf("%#lx", tcp->u_arg[1]);
1157 else if (umoven(tcp, tcp->u_arg[1],
1158 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1159 tprintf("[?]");
1160 else {
1161 tprintf("[");
1162 for (i = 0; i < len; i++)
1163 tprintf("%s%lu", i ? ", " : "",
1164 (unsigned long) gidset[i]);
1165 tprintf("]");
1166 }
1167 free((char *)gidset);
1168 }
1169 return 0;
1170}
1171
1172int
1173sys_setpgrp(tcp)
1174struct tcb *tcp;
1175{
1176 if (entering(tcp)) {
1177#ifndef SVR4
1178 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1179#endif /* !SVR4 */
1180 }
1181 return 0;
1182}
1183
1184int
1185sys_getpgrp(tcp)
1186struct tcb *tcp;
1187{
1188 if (entering(tcp)) {
1189#ifndef SVR4
1190 tprintf("%lu", tcp->u_arg[0]);
1191#endif /* !SVR4 */
1192 }
1193 return 0;
1194}
1195
1196int
1197sys_getsid(tcp)
1198struct tcb *tcp;
1199{
1200 if (entering(tcp)) {
1201 tprintf("%lu", tcp->u_arg[0]);
1202 }
1203 return 0;
1204}
1205
1206int
1207sys_setsid(tcp)
1208struct tcb *tcp;
1209{
1210 return 0;
1211}
1212
1213int
1214sys_getpgid(tcp)
1215struct tcb *tcp;
1216{
1217 if (entering(tcp)) {
1218 tprintf("%lu", tcp->u_arg[0]);
1219 }
1220 return 0;
1221}
1222
1223int
1224sys_setpgid(tcp)
1225struct tcb *tcp;
1226{
1227 if (entering(tcp)) {
1228 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1229 }
1230 return 0;
1231}
1232
John Hughesc61eb3d2002-05-17 11:37:50 +00001233#if UNIXWARE >= 2
1234
1235#include <sys/privilege.h>
1236
1237
1238static struct xlat procpriv_cmds [] = {
1239 { SETPRV, "SETPRV" },
1240 { CLRPRV, "CLRPRV" },
1241 { PUTPRV, "PUTPRV" },
1242 { GETPRV, "GETPRV" },
1243 { CNTPRV, "CNTPRV" },
1244 { 0, NULL },
1245};
1246
1247
1248static struct xlat procpriv_priv [] = {
1249 { P_OWNER, "P_OWNER" },
1250 { P_AUDIT, "P_AUDIT" },
1251 { P_COMPAT, "P_COMPAT" },
1252 { P_DACREAD, "P_DACREAD" },
1253 { P_DACWRITE, "P_DACWRITE" },
1254 { P_DEV, "P_DEV" },
1255 { P_FILESYS, "P_FILESYS" },
1256 { P_MACREAD, "P_MACREAD" },
1257 { P_MACWRITE, "P_MACWRITE" },
1258 { P_MOUNT, "P_MOUNT" },
1259 { P_MULTIDIR, "P_MULTIDIR" },
1260 { P_SETPLEVEL, "P_SETPLEVEL" },
1261 { P_SETSPRIV, "P_SETSPRIV" },
1262 { P_SETUID, "P_SETUID" },
1263 { P_SYSOPS, "P_SYSOPS" },
1264 { P_SETUPRIV, "P_SETUPRIV" },
1265 { P_DRIVER, "P_DRIVER" },
1266 { P_RTIME, "P_RTIME" },
1267 { P_MACUPGRADE, "P_MACUPGRADE" },
1268 { P_FSYSRANGE, "P_FSYSRANGE" },
1269 { P_SETFLEVEL, "P_SETFLEVEL" },
1270 { P_AUDITWR, "P_AUDITWR" },
1271 { P_TSHAR, "P_TSHAR" },
1272 { P_PLOCK, "P_PLOCK" },
1273 { P_CORE, "P_CORE" },
1274 { P_LOADMOD, "P_LOADMOD" },
1275 { P_BIND, "P_BIND" },
1276 { P_ALLPRIVS, "P_ALLPRIVS" },
1277 { 0, NULL },
1278};
1279
1280
1281static struct xlat procpriv_type [] = {
1282 { PS_FIX, "PS_FIX" },
1283 { PS_INH, "PS_INH" },
1284 { PS_MAX, "PS_MAX" },
1285 { PS_WKG, "PS_WKG" },
1286 { 0, NULL },
1287};
1288
1289
1290static void
1291printpriv(tcp, addr, len, opt)
1292struct tcb *tcp;
1293long addr;
1294int len;
1295struct xlat *opt;
1296{
1297 priv_t buf [128];
1298 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1299 int dots = len > max;
1300 int i;
Roland McGrath5a223472002-12-15 23:58:26 +00001301
John Hughesc61eb3d2002-05-17 11:37:50 +00001302 if (len > max) len = max;
Roland McGrath5a223472002-12-15 23:58:26 +00001303
John Hughesc61eb3d2002-05-17 11:37:50 +00001304 if (len <= 0 ||
1305 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1306 {
1307 tprintf ("%#lx", addr);
1308 return;
1309 }
1310
1311 tprintf ("[");
1312
1313 for (i = 0; i < len; ++i) {
1314 char *t, *p;
1315
1316 if (i) tprintf (", ");
1317
1318 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1319 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1320 {
1321 tprintf ("%s|%s", t, p);
1322 }
1323 else {
1324 tprintf ("%#lx", buf [i]);
1325 }
1326 }
1327
1328 if (dots) tprintf (" ...");
1329
1330 tprintf ("]");
1331}
1332
1333
1334int
1335sys_procpriv(tcp)
1336struct tcb *tcp;
1337{
1338 if (entering(tcp)) {
1339 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1340 switch (tcp->u_arg[0]) {
1341 case CNTPRV:
1342 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1343 break;
1344
1345 case GETPRV:
1346 break;
1347
1348 default:
1349 tprintf (", ");
1350 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1351 tprintf (", %ld", tcp->u_arg[2]);
1352 }
1353 }
1354 else if (tcp->u_arg[0] == GETPRV) {
1355 if (syserror (tcp)) {
1356 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1357 }
1358 else {
1359 tprintf (", ");
1360 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1361 tprintf (", %ld", tcp->u_arg[2]);
1362 }
1363 }
Roland McGrath5a223472002-12-15 23:58:26 +00001364
John Hughesc61eb3d2002-05-17 11:37:50 +00001365 return 0;
1366}
1367
1368#endif
1369
1370
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001371void
1372fake_execve(tcp, program, argv, envp)
1373struct tcb *tcp;
1374char *program;
1375char *argv[];
1376char *envp[];
1377{
1378 int i;
1379
1380#ifdef ARM
1381 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1382 return;
1383#else
1384 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1385 return;
1386#endif /* !ARM */
1387 printleader(tcp);
1388 tprintf("execve(");
1389 string_quote(program);
1390 tprintf(", [");
1391 for (i = 0; argv[i] != NULL; i++) {
1392 if (i != 0)
1393 tprintf(", ");
1394 string_quote(argv[i]);
1395 }
1396 for (i = 0; envp[i] != NULL; i++)
1397 ;
1398 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1399 tabto(acolumn);
1400 tprintf("= 0");
1401 printtrailer(tcp);
1402}
1403
1404static void
1405printargv(tcp, addr)
1406struct tcb *tcp;
1407long addr;
1408{
1409 char *cp;
1410 char *sep;
1411 int max = max_strlen / 2;
1412
1413 for (sep = ""; --max >= 0; sep = ", ") {
1414 if (!abbrev(tcp))
1415 max++;
1416 if (umove(tcp, addr, &cp) < 0) {
1417 tprintf("%#lx", addr);
1418 return;
1419 }
1420 if (cp == 0)
1421 break;
1422 tprintf(sep);
1423 printstr(tcp, (long) cp, -1);
1424 addr += sizeof(char *);
1425 }
1426 if (cp)
1427 tprintf(", ...");
1428}
1429
1430static void
1431printargc(fmt, tcp, addr)
1432char *fmt;
1433struct tcb *tcp;
1434long addr;
1435{
1436 int count;
1437 char *cp;
1438
1439 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1440 addr += sizeof(char *);
1441 }
1442 tprintf(fmt, count, count == 1 ? "" : "s");
1443}
1444
1445int
1446sys_execv(tcp)
1447struct tcb *tcp;
1448{
1449 if (entering(tcp)) {
1450 printpath(tcp, tcp->u_arg[0]);
1451 if (!verbose(tcp))
1452 tprintf(", %#lx", tcp->u_arg[1]);
1453#if 0
1454 else if (abbrev(tcp))
1455 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1456#endif
1457 else {
1458 tprintf(", [");
1459 printargv(tcp, tcp->u_arg[1]);
1460 tprintf("]");
1461 }
1462 }
1463 return 0;
1464}
1465
1466int
1467sys_execve(tcp)
1468struct tcb *tcp;
1469{
1470 if (entering(tcp)) {
1471 printpath(tcp, tcp->u_arg[0]);
1472 if (!verbose(tcp))
1473 tprintf(", %#lx", tcp->u_arg[1]);
1474#if 0
1475 else if (abbrev(tcp))
1476 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1477#endif
1478 else {
1479 tprintf(", [");
1480 printargv(tcp, tcp->u_arg[1]);
1481 tprintf("]");
1482 }
1483 if (!verbose(tcp))
1484 tprintf(", %#lx", tcp->u_arg[2]);
1485 else if (abbrev(tcp))
1486 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1487 else {
1488 tprintf(", [");
1489 printargv(tcp, tcp->u_arg[2]);
1490 tprintf("]");
1491 }
1492 }
1493#ifdef LINUX
Wichert Akkermanccef6372002-05-01 16:39:22 +00001494#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001495 tcp->flags |= TCB_WAITEXECVE;
Wichert Akkermanccef6372002-05-01 16:39:22 +00001496#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001497#endif /* LINUX */
1498 return 0;
1499}
1500
John Hughes4e36a812001-04-18 15:11:51 +00001501#if UNIXWARE > 2
1502
1503int sys_rexecve(tcp)
1504struct tcb *tcp;
1505{
1506 if (entering (tcp)) {
1507 sys_execve (tcp);
1508 tprintf (", %ld", tcp->u_arg[3]);
1509 }
1510 return 0;
1511}
1512
1513#endif
1514
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001515int
1516internal_exec(tcp)
1517struct tcb *tcp;
1518{
1519#ifdef SUNOS4
1520 if (exiting(tcp) && !syserror(tcp) && followfork)
1521 fixvfork(tcp);
1522#endif /* SUNOS4 */
1523 return 0;
1524}
1525
1526#ifdef LINUX
Roland McGrath7ec1d352002-12-17 04:50:44 +00001527#ifndef __WNOTHREAD
1528#define __WNOTHREAD 0x20000000
1529#endif
1530#ifndef __WALL
1531#define __WALL 0x40000000
1532#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001533#ifndef __WCLONE
Roland McGrath7ec1d352002-12-17 04:50:44 +00001534#define __WCLONE 0x80000000
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001535#endif
1536#endif /* LINUX */
1537
1538static struct xlat wait4_options[] = {
1539 { WNOHANG, "WNOHANG" },
1540#ifndef WSTOPPED
1541 { WUNTRACED, "WUNTRACED" },
1542#endif
1543#ifdef WEXITED
1544 { WEXITED, "WEXITED" },
1545#endif
1546#ifdef WTRAPPED
1547 { WTRAPPED, "WTRAPPED" },
1548#endif
1549#ifdef WSTOPPED
1550 { WSTOPPED, "WSTOPPED" },
1551#endif
1552#ifdef WCONTINUED
1553 { WCONTINUED, "WCONTINUED" },
1554#endif
1555#ifdef WNOWAIT
1556 { WNOWAIT, "WNOWAIT" },
1557#endif
1558#ifdef __WCLONE
1559 { __WCLONE, "__WCLONE" },
1560#endif
Roland McGrath7ec1d352002-12-17 04:50:44 +00001561#ifdef __WALL
1562 { __WALL, "__WALL" },
1563#endif
1564#ifdef __WNOTHREAD
1565 { __WNOTHREAD, "__WNOTHREAD" },
1566#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001567 { 0, NULL },
1568};
1569
1570static int
1571printstatus(status)
1572int status;
1573{
1574 int exited = 0;
1575
1576 /*
1577 * Here is a tricky presentation problem. This solution
1578 * is still not entirely satisfactory but since there
1579 * are no wait status constructors it will have to do.
1580 */
1581 if (WIFSTOPPED(status))
1582 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001583 signame(WSTOPSIG(status)));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001584 else if WIFSIGNALED(status)
1585 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
Nate Sammonsce780fc1999-03-29 23:23:13 +00001586 signame(WTERMSIG(status)),
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001587 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1588 else if WIFEXITED(status) {
1589 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1590 WEXITSTATUS(status));
1591 exited = 1;
1592 }
1593 else
1594 tprintf("[%#x]", status);
1595 return exited;
1596}
1597
1598static int
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001599printwaitn(tcp, n, bitness)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001600struct tcb *tcp;
1601int n;
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001602int bitness;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001603{
1604 int status;
1605 int exited = 0;
1606
1607 if (entering(tcp)) {
1608 tprintf("%ld, ", tcp->u_arg[0]);
1609 } else {
1610 /* status */
1611 if (!tcp->u_arg[1])
1612 tprintf("NULL");
1613 else if (syserror(tcp) || tcp->u_rval == 0)
1614 tprintf("%#lx", tcp->u_arg[1]);
1615 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1616 tprintf("[?]");
1617 else
1618 exited = printstatus(status);
1619 /* options */
1620 tprintf(", ");
1621 if (!printflags(wait4_options, tcp->u_arg[2]))
1622 tprintf("0");
1623 if (n == 4) {
1624 tprintf(", ");
1625 /* usage */
1626 if (!tcp->u_arg[3])
1627 tprintf("NULL");
1628#ifdef LINUX
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001629 else if (tcp->u_rval > 0) {
1630#ifdef LINUX_64BIT
1631 if (bitness)
1632 printrusage32(tcp, tcp->u_arg[3]);
1633 else
1634#endif
1635 printrusage(tcp, tcp->u_arg[3]);
1636 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001637#endif /* LINUX */
1638#ifdef SUNOS4
1639 else if (tcp->u_rval > 0 && exited)
1640 printrusage(tcp, tcp->u_arg[3]);
1641#endif /* SUNOS4 */
1642 else
1643 tprintf("%#lx", tcp->u_arg[3]);
1644 }
1645 }
1646 return 0;
1647}
1648
1649int
1650internal_wait(tcp)
1651struct tcb *tcp;
1652{
Roland McGrathb69f81b2002-12-21 23:25:18 +00001653 if (entering(tcp) && tcp->nchildren > 0) {
1654 /* There are children that this parent should block for.
1655 But ptrace made us the parent of the traced children
1656 and the real parent will get ECHILD from the wait call.
1657
1658 XXX If we attached with strace -f -p PID, then there
1659 may be untraced dead children the parent could be reaping
1660 now, but we make him block. */
1661
1662 /* ??? WTA: fix bug with hanging children */
1663
1664 if (!(tcp->u_arg[2] & WNOHANG)) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001665 /* There are traced children */
1666 tcp->flags |= TCB_SUSPENDED;
1667 tcp->waitpid = tcp->u_arg[0];
1668 }
1669 }
Roland McGrathb69f81b2002-12-21 23:25:18 +00001670 if (exiting(tcp) && tcp->u_error == ECHILD && tcp->nchildren > 0) {
1671 if (tcp->u_arg[2] & WNOHANG) {
1672 /* We must force a fake result of 0 instead of
1673 the ECHILD error. */
1674 extern int force_result();
1675 return force_result(tcp, 0, 0);
1676 }
1677 else
1678 fprintf(stderr,
1679 "internal_wait: should not have resumed %d\n",
1680 tcp->pid);
1681 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001682 return 0;
1683}
1684
1685#ifdef SVR4
1686
1687int
1688sys_wait(tcp)
1689struct tcb *tcp;
1690{
1691 if (exiting(tcp)) {
1692 /* The library wrapper stuffs this into the user variable. */
1693 if (!syserror(tcp))
1694 printstatus(getrval2(tcp));
1695 }
1696 return 0;
1697}
1698
1699#endif /* SVR4 */
1700
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001701#ifdef FREEBSD
1702int
1703sys_wait(tcp)
1704struct tcb *tcp;
1705{
1706 int status;
Roland McGrath5a223472002-12-15 23:58:26 +00001707
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001708 if (exiting(tcp)) {
1709 if (!syserror(tcp)) {
1710 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1711 tprintf("%#lx", tcp->u_arg[0]);
1712 else
1713 printstatus(status);
1714 }
1715 }
1716 return 0;
1717}
1718#endif
1719
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001720int
1721sys_waitpid(tcp)
1722struct tcb *tcp;
1723{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001724 return printwaitn(tcp, 3, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001725}
1726
1727int
1728sys_wait4(tcp)
1729struct tcb *tcp;
1730{
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001731 return printwaitn(tcp, 4, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001732}
1733
Wichert Akkermanf5eeabb1999-11-18 17:09:47 +00001734#ifdef ALPHA
1735int
1736sys_osf_wait4(tcp)
1737struct tcb *tcp;
1738{
1739 return printwaitn(tcp, 4, 1);
1740}
1741#endif
1742
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743#ifdef SVR4
1744
1745static struct xlat waitid_types[] = {
1746 { P_PID, "P_PID" },
1747 { P_PPID, "P_PPID" },
1748 { P_PGID, "P_PGID" },
1749 { P_SID, "P_SID" },
1750 { P_CID, "P_CID" },
1751 { P_UID, "P_UID" },
1752 { P_GID, "P_GID" },
1753 { P_ALL, "P_ALL" },
1754#ifdef P_LWPID
1755 { P_LWPID, "P_LWPID" },
1756#endif
1757 { 0, NULL },
1758};
1759
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001760int
1761sys_waitid(tcp)
1762struct tcb *tcp;
1763{
1764 siginfo_t si;
1765 int exited;
1766
1767 if (entering(tcp)) {
1768 printxval(waitid_types, tcp->u_arg[0], "P_???");
1769 tprintf(", %ld, ", tcp->u_arg[1]);
1770 if (tcp->nchildren > 0) {
1771 /* There are traced children */
1772 tcp->flags |= TCB_SUSPENDED;
1773 tcp->waitpid = tcp->u_arg[0];
1774 }
1775 }
1776 else {
1777 /* siginfo */
1778 exited = 0;
1779 if (!tcp->u_arg[2])
1780 tprintf("NULL");
1781 else if (syserror(tcp))
1782 tprintf("%#lx", tcp->u_arg[2]);
1783 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1784 tprintf("{???}");
1785 else
John Hughes58265892001-10-18 15:13:53 +00001786 printsiginfo(&si, verbose (tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001787 /* options */
1788 tprintf(", ");
1789 if (!printflags(wait4_options, tcp->u_arg[3]))
1790 tprintf("0");
1791 }
1792 return 0;
1793}
1794
1795#endif /* SVR4 */
1796
1797int
1798sys_alarm(tcp)
1799struct tcb *tcp;
1800{
1801 if (entering(tcp))
1802 tprintf("%lu", tcp->u_arg[0]);
1803 return 0;
1804}
1805
1806int
1807sys_uname(tcp)
1808struct tcb *tcp;
1809{
1810 struct utsname uname;
1811
1812 if (exiting(tcp)) {
1813 if (syserror(tcp) || !verbose(tcp))
1814 tprintf("%#lx", tcp->u_arg[0]);
1815 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1816 tprintf("{...}");
1817 else if (!abbrev(tcp)) {
1818
1819 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1820 uname.sysname, uname.nodename);
1821 tprintf("release=\"%s\", version=\"%s\", ",
1822 uname.release, uname.version);
1823 tprintf("machine=\"%s\"", uname.machine);
1824#ifdef LINUX
1825#ifndef __GLIBC__
1826 tprintf(", domainname=\"%s\"", uname.domainname);
1827#endif /* __GLIBC__ */
1828#endif /* LINUX */
1829 tprintf("}");
1830 }
1831 else
1832 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1833 uname.sysname, uname.nodename);
1834 }
1835 return 0;
1836}
1837
1838#ifndef SVR4
1839
1840static struct xlat ptrace_cmds[] = {
Roland McGrath5a223472002-12-15 23:58:26 +00001841#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001842 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1843 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1844 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1845 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1846 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1847 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1848 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1849 { PTRACE_CONT, "PTRACE_CONT" },
1850 { PTRACE_KILL, "PTRACE_KILL" },
1851 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1852 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1853 { PTRACE_DETACH, "PTRACE_DETACH" },
1854#ifdef SUNOS4
1855 { PTRACE_GETREGS, "PTRACE_GETREGS" },
1856 { PTRACE_SETREGS, "PTRACE_SETREGS" },
1857 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
1858 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
1859 { PTRACE_READDATA, "PTRACE_READDATA" },
1860 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1861 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1862 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1863 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1864 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1865#ifdef SPARC
1866 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1867 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1868#else /* !SPARC */
1869 { PTRACE_22, "PTRACE_PTRACE_22" },
1870 { PTRACE_23, "PTRACE_PTRACE_23" },
1871#endif /* !SPARC */
1872#endif /* SUNOS4 */
1873 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1874#ifdef SUNOS4
1875 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1876#ifdef I386
1877 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1878 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1879 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
1880#else /* !I386 */
1881 { PTRACE_26, "PTRACE_26" },
1882 { PTRACE_27, "PTRACE_27" },
1883 { PTRACE_28, "PTRACE_28" },
1884#endif /* !I386 */
1885 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
1886#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001887#else /* FREEBSD */
1888 { PT_TRACE_ME, "PT_TRACE_ME" },
1889 { PT_READ_I, "PT_READ_I" },
1890 { PT_READ_D, "PT_READ_D" },
1891 { PT_WRITE_I, "PT_WRITE_I" },
1892 { PT_WRITE_D, "PT_WRITE_D" },
John Hughesa2278142001-09-28 16:21:30 +00001893#ifdef PT_READ_U
1894 { PT_READ_U, "PT_READ_U" },
1895#endif
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001896 { PT_CONTINUE, "PT_CONTINUE" },
1897 { PT_KILL, "PT_KILL" },
1898 { PT_STEP, "PT_STEP" },
1899 { PT_ATTACH, "PT_ATTACH" },
1900 { PT_DETACH, "PT_DETACH" },
1901 { PT_GETREGS, "PT_GETREGS" },
1902 { PT_SETREGS, "PT_SETREGS" },
1903 { PT_GETFPREGS, "PT_GETFPREGS" },
1904 { PT_SETFPREGS, "PT_SETFPREGS" },
1905 { PT_GETDBREGS, "PT_GETDBREGS" },
1906 { PT_SETDBREGS, "PT_SETDBREGS" },
1907#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001908 { 0, NULL },
1909};
1910
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00001911#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001912#ifndef SUNOS4_KERNEL_ARCH_KLUDGE
1913static
1914#endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
1915struct xlat struct_user_offsets[] = {
1916#ifdef LINUX
Michal Ludvig10a88d02002-10-07 14:31:00 +00001917#if defined(S390) || defined(S390X)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00001918 { PT_PSWMASK, "psw_mask" },
1919 { PT_PSWADDR, "psw_addr" },
1920 { PT_GPR0, "gpr0" },
1921 { PT_GPR1, "gpr1" },
1922 { PT_GPR2, "gpr2" },
1923 { PT_GPR3, "gpr3" },
1924 { PT_GPR4, "gpr4" },
1925 { PT_GPR5, "gpr5" },
1926 { PT_GPR6, "gpr6" },
1927 { PT_GPR7, "gpr7" },
1928 { PT_GPR8, "gpr8" },
1929 { PT_GPR9, "gpr9" },
1930 { PT_GPR10, "gpr10" },
1931 { PT_GPR11, "gpr11" },
1932 { PT_GPR12, "gpr12" },
1933 { PT_GPR13, "gpr13" },
1934 { PT_GPR14, "gpr14" },
1935 { PT_GPR15, "gpr15" },
1936 { PT_ACR0, "acr0" },
1937 { PT_ACR1, "acr1" },
1938 { PT_ACR2, "acr2" },
1939 { PT_ACR3, "acr3" },
1940 { PT_ACR4, "acr4" },
1941 { PT_ACR5, "acr5" },
1942 { PT_ACR6, "acr6" },
1943 { PT_ACR7, "acr7" },
1944 { PT_ACR8, "acr8" },
1945 { PT_ACR9, "acr9" },
1946 { PT_ACR10, "acr10" },
1947 { PT_ACR11, "acr11" },
1948 { PT_ACR12, "acr12" },
1949 { PT_ACR13, "acr13" },
1950 { PT_ACR14, "acr14" },
1951 { PT_ACR15, "acr15" },
1952 { PT_ORIGGPR2, "orig_gpr2" },
1953 { PT_FPC, "fpc" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00001954#if defined(S390)
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00001955 { PT_FPR0_HI, "fpr0.hi" },
1956 { PT_FPR0_LO, "fpr0.lo" },
1957 { PT_FPR1_HI, "fpr1.hi" },
1958 { PT_FPR1_LO, "fpr1.lo" },
1959 { PT_FPR2_HI, "fpr2.hi" },
1960 { PT_FPR2_LO, "fpr2.lo" },
1961 { PT_FPR3_HI, "fpr3.hi" },
1962 { PT_FPR3_LO, "fpr3.lo" },
1963 { PT_FPR4_HI, "fpr4.hi" },
1964 { PT_FPR4_LO, "fpr4.lo" },
1965 { PT_FPR5_HI, "fpr5.hi" },
1966 { PT_FPR5_LO, "fpr5.lo" },
1967 { PT_FPR6_HI, "fpr6.hi" },
1968 { PT_FPR6_LO, "fpr6.lo" },
1969 { PT_FPR7_HI, "fpr7.hi" },
1970 { PT_FPR7_LO, "fpr7.lo" },
1971 { PT_FPR8_HI, "fpr8.hi" },
1972 { PT_FPR8_LO, "fpr8.lo" },
1973 { PT_FPR9_HI, "fpr9.hi" },
1974 { PT_FPR9_LO, "fpr9.lo" },
1975 { PT_FPR10_HI, "fpr10.hi" },
1976 { PT_FPR10_LO, "fpr10.lo" },
1977 { PT_FPR11_HI, "fpr11.hi" },
1978 { PT_FPR11_LO, "fpr11.lo" },
1979 { PT_FPR12_HI, "fpr12.hi" },
1980 { PT_FPR12_LO, "fpr12.lo" },
1981 { PT_FPR13_HI, "fpr13.hi" },
1982 { PT_FPR13_LO, "fpr13.lo" },
1983 { PT_FPR14_HI, "fpr14.hi" },
1984 { PT_FPR14_LO, "fpr14.lo" },
1985 { PT_FPR15_HI, "fpr15.hi" },
1986 { PT_FPR15_LO, "fpr15.lo" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00001987#endif
1988#if defined(S390X)
1989 { PT_FPR0, "fpr0" },
1990 { PT_FPR1, "fpr1" },
1991 { PT_FPR2, "fpr2" },
1992 { PT_FPR3, "fpr3" },
1993 { PT_FPR4, "fpr4" },
1994 { PT_FPR5, "fpr5" },
1995 { PT_FPR6, "fpr6" },
1996 { PT_FPR7, "fpr7" },
1997 { PT_FPR8, "fpr8" },
1998 { PT_FPR9, "fpr9" },
1999 { PT_FPR10, "fpr10" },
2000 { PT_FPR11, "fpr11" },
2001 { PT_FPR12, "fpr12" },
2002 { PT_FPR13, "fpr13" },
2003 { PT_FPR14, "fpr14" },
2004 { PT_FPR15, "fpr15" },
2005#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002006 { PT_CR_9, "cr9" },
2007 { PT_CR_10, "cr10" },
2008 { PT_CR_11, "cr11" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002009 { PT_IEEE_IP, "ieee_exception_ip" },
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002010#endif
2011#if defined(SPARC)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002012 /* XXX No support for these offsets yet. */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002013#elif defined(HPPA)
2014 /* XXX No support for these offsets yet. */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002015#elif defined(POWERPC)
Roland McGrath5a223472002-12-15 23:58:26 +00002016#ifndef PT_ORIG_R3
2017#define PT_ORIG_R3 34
2018#endif
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002019 { 4*PT_R0, "4*PT_R0" },
2020 { 4*PT_R1, "4*PT_R1" },
2021 { 4*PT_R2, "4*PT_R2" },
2022 { 4*PT_R3, "4*PT_R3" },
2023 { 4*PT_R4, "4*PT_R4" },
2024 { 4*PT_R5, "4*PT_R5" },
2025 { 4*PT_R6, "4*PT_R6" },
2026 { 4*PT_R7, "4*PT_R7" },
2027 { 4*PT_R8, "4*PT_R8" },
2028 { 4*PT_R9, "4*PT_R9" },
2029 { 4*PT_R10, "4*PT_R10" },
2030 { 4*PT_R11, "4*PT_R11" },
2031 { 4*PT_R12, "4*PT_R12" },
2032 { 4*PT_R13, "4*PT_R13" },
2033 { 4*PT_R14, "4*PT_R14" },
2034 { 4*PT_R15, "4*PT_R15" },
2035 { 4*PT_R16, "4*PT_R16" },
2036 { 4*PT_R17, "4*PT_R17" },
2037 { 4*PT_R18, "4*PT_R18" },
2038 { 4*PT_R19, "4*PT_R19" },
2039 { 4*PT_R20, "4*PT_R20" },
2040 { 4*PT_R21, "4*PT_R21" },
2041 { 4*PT_R22, "4*PT_R22" },
2042 { 4*PT_R23, "4*PT_R23" },
2043 { 4*PT_R24, "4*PT_R24" },
2044 { 4*PT_R25, "4*PT_R25" },
2045 { 4*PT_R26, "4*PT_R26" },
2046 { 4*PT_R27, "4*PT_R27" },
2047 { 4*PT_R28, "4*PT_R28" },
2048 { 4*PT_R29, "4*PT_R29" },
2049 { 4*PT_R30, "4*PT_R30" },
2050 { 4*PT_R31, "4*PT_R31" },
2051 { 4*PT_NIP, "4*PT_NIP" },
2052 { 4*PT_MSR, "4*PT_MSR" },
2053 { 4*PT_ORIG_R3, "4*PT_ORIG_R3" },
2054 { 4*PT_CTR, "4*PT_CTR" },
2055 { 4*PT_LNK, "4*PT_LNK" },
2056 { 4*PT_XER, "4*PT_XER" },
2057 { 4*PT_CCR, "4*PT_CCR" },
2058 { 4*PT_FPR0, "4*PT_FPR0" },
Roland McGrath5a223472002-12-15 23:58:26 +00002059#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002060#ifdef ALPHA
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00002061 { 0, "r0" },
2062 { 1, "r1" },
2063 { 2, "r2" },
2064 { 3, "r3" },
2065 { 4, "r4" },
2066 { 5, "r5" },
2067 { 6, "r6" },
2068 { 7, "r7" },
2069 { 8, "r8" },
2070 { 9, "r9" },
2071 { 10, "r10" },
2072 { 11, "r11" },
2073 { 12, "r12" },
2074 { 13, "r13" },
2075 { 14, "r14" },
2076 { 15, "r15" },
2077 { 16, "r16" },
2078 { 17, "r17" },
2079 { 18, "r18" },
2080 { 19, "r19" },
2081 { 20, "r20" },
2082 { 21, "r21" },
2083 { 22, "r22" },
2084 { 23, "r23" },
2085 { 24, "r24" },
2086 { 25, "r25" },
2087 { 26, "r26" },
2088 { 27, "r27" },
2089 { 28, "r28" },
2090 { 29, "gp" },
2091 { 30, "fp" },
2092 { 31, "zero" },
2093 { 32, "fp0" },
2094 { 33, "fp" },
2095 { 34, "fp2" },
2096 { 35, "fp3" },
2097 { 36, "fp4" },
2098 { 37, "fp5" },
2099 { 38, "fp6" },
2100 { 39, "fp7" },
2101 { 40, "fp8" },
2102 { 41, "fp9" },
2103 { 42, "fp10" },
2104 { 43, "fp11" },
2105 { 44, "fp12" },
2106 { 45, "fp13" },
2107 { 46, "fp14" },
2108 { 47, "fp15" },
2109 { 48, "fp16" },
2110 { 49, "fp17" },
2111 { 50, "fp18" },
2112 { 51, "fp19" },
2113 { 52, "fp20" },
2114 { 53, "fp21" },
2115 { 54, "fp22" },
2116 { 55, "fp23" },
2117 { 56, "fp24" },
2118 { 57, "fp25" },
2119 { 58, "fp26" },
2120 { 59, "fp27" },
2121 { 60, "fp28" },
2122 { 61, "fp29" },
2123 { 62, "fp30" },
2124 { 63, "fp31" },
2125 { 64, "pc" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126#else /* !ALPHA */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002127#ifdef IA64
2128 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2129 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2130 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2131 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2132 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2133 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2134 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2135 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2136 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2137 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2138 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2139 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2140 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2141 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2142 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2143 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2144 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2145 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2146 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2147 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2148 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2149 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2150 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2151 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2152 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2153 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2154 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2155 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2156 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2157 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2158 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2159 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2160 /* switch stack: */
2161 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2162 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2163 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2164 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2165 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2166 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2167 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2168 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2169 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2170 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002171 { PT_B0, "kb0" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002172 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2173 { PT_B4, "b4" }, { PT_B5, "b5" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002174 { PT_AR_PFS, "kar.pfs" },
2175 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2176 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2177 { PT_PR, "k.pr" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002178 /* pt_regs */
2179 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
Wichert Akkerman82b162e2001-08-03 11:51:28 +00002180 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002181 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2182 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2183 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2184 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2185 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2186 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2187 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2188 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2189 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2190 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2191 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2192 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2193 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2194 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2195 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2196#else /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002197#ifdef I386
2198 { 4*EBX, "4*EBX" },
2199 { 4*ECX, "4*ECX" },
2200 { 4*EDX, "4*EDX" },
2201 { 4*ESI, "4*ESI" },
2202 { 4*EDI, "4*EDI" },
2203 { 4*EBP, "4*EBP" },
2204 { 4*EAX, "4*EAX" },
2205 { 4*DS, "4*DS" },
2206 { 4*ES, "4*ES" },
2207 { 4*FS, "4*FS" },
2208 { 4*GS, "4*GS" },
2209 { 4*ORIG_EAX, "4*ORIG_EAX" },
2210 { 4*EIP, "4*EIP" },
2211 { 4*CS, "4*CS" },
2212 { 4*EFL, "4*EFL" },
2213 { 4*UESP, "4*UESP" },
2214 { 4*SS, "4*SS" },
2215#else /* !I386 */
Michal Ludvig0e035502002-09-23 15:41:01 +00002216#ifdef X86_64
2217 { 8*RDI, "8*RDI" },
2218 { 8*RSI, "8*RSI" },
2219 { 8*RDX, "8*RDX" },
2220 { 8*R10, "8*R10" },
2221 { 8*R8, "8*R8" },
2222 { 8*R9, "8*R9" },
2223 { 8*RBX, "8*RBX" },
2224 { 8*RCX, "8*RCX" },
2225 { 8*RBP, "8*RBP" },
2226 { 8*RAX, "8*RAX" },
2227#if 0
2228 { 8*DS, "8*DS" },
2229 { 8*ES, "8*ES" },
2230 { 8*FS, "8*FS" },
2231 { 8*GS, "8*GS" },
2232#endif
2233 { 8*ORIG_RAX, "8*ORIG_EAX" },
2234 { 8*RIP, "8*RIP" },
2235 { 8*CS, "8*CS" },
2236 { 8*EFLAGS, "8*EFL" },
2237 { 8*RSP, "8*RSP" },
2238 { 8*SS, "8*SS" },
2239 { 8*R11, "8*R11" },
2240 { 8*R12, "8*R12" },
2241 { 8*R13, "8*R13" },
2242 { 8*R14, "8*R14" },
2243 { 8*R15, "8*R15" },
2244#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002245#ifdef M68K
2246 { 4*PT_D1, "4*PT_D1" },
2247 { 4*PT_D2, "4*PT_D2" },
2248 { 4*PT_D3, "4*PT_D3" },
2249 { 4*PT_D4, "4*PT_D4" },
2250 { 4*PT_D5, "4*PT_D5" },
2251 { 4*PT_D6, "4*PT_D6" },
2252 { 4*PT_D7, "4*PT_D7" },
2253 { 4*PT_A0, "4*PT_A0" },
2254 { 4*PT_A1, "4*PT_A1" },
2255 { 4*PT_A2, "4*PT_A2" },
2256 { 4*PT_A3, "4*PT_A3" },
2257 { 4*PT_A4, "4*PT_A4" },
2258 { 4*PT_A5, "4*PT_A5" },
2259 { 4*PT_A6, "4*PT_A6" },
2260 { 4*PT_D0, "4*PT_D0" },
2261 { 4*PT_USP, "4*PT_USP" },
2262 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2263 { 4*PT_SR, "4*PT_SR" },
2264 { 4*PT_PC, "4*PT_PC" },
2265#endif /* M68K */
2266#endif /* !I386 */
Wichert Akkermanccef6372002-05-01 16:39:22 +00002267#ifdef SH
2268 { 4*REG_REG0, "4*REG_REG0" },
2269 { 4*(REG_REG0+1), "4*REG_REG1" },
2270 { 4*(REG_REG0+2), "4*REG_REG2" },
2271 { 4*(REG_REG0+3), "4*REG_REG3" },
2272 { 4*(REG_REG0+4), "4*REG_REG4" },
2273 { 4*(REG_REG0+5), "4*REG_REG5" },
2274 { 4*(REG_REG0+6), "4*REG_REG6" },
2275 { 4*(REG_REG0+7), "4*REG_REG7" },
2276 { 4*(REG_REG0+8), "4*REG_REG8" },
2277 { 4*(REG_REG0+9), "4*REG_REG9" },
2278 { 4*(REG_REG0+10), "4*REG_REG10" },
2279 { 4*(REG_REG0+11), "4*REG_REG11" },
2280 { 4*(REG_REG0+12), "4*REG_REG12" },
2281 { 4*(REG_REG0+13), "4*REG_REG13" },
2282 { 4*(REG_REG0+14), "4*REG_REG14" },
2283 { 4*REG_REG15, "4*REG_REG15" },
2284 { 4*REG_PC, "4*REG_PC" },
2285 { 4*REG_PR, "4*REG_PR" },
2286 { 4*REG_SR, "4*REG_SR" },
2287 { 4*REG_GBR, "4*REG_GBR" },
2288 { 4*REG_MACH, "4*REG_MACH" },
2289 { 4*REG_MACL, "4*REG_MACL" },
2290 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2291 { 4*REG_FPUL, "4*REG_FPUL" },
2292 { 4*REG_FPREG0, "4*REG_FPREG0" },
2293 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2294 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2295 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2296 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2297 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2298 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2299 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2300 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2301 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2302 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2303 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2304 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2305 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2306 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2307 { 4*REG_FPREG15, "4*REG_FPREG15" },
2308 { 4*REG_XDREG0, "4*REG_XDREG0" },
2309 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2310 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2311 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2312 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2313 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2314 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2315 { 4*REG_XDREG14, "4*REG_XDREG14" },
2316 { 4*REG_FPSCR, "4*REG_FPSCR" },
2317#endif /* SH */
2318
Michal Ludvig10a88d02002-10-07 14:31:00 +00002319#if !defined(S390) && !defined(S390X) && !defined(MIPS)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002320 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002321#endif
Michal Ludvig0e035502002-09-23 15:41:01 +00002322#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002323 { uoff(i387), "offsetof(struct user, i387)" },
2324#else /* !I386 */
2325#ifdef M68K
2326 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2327#endif /* M68K */
2328#endif /* !I386 */
2329 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2330 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2331 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2332 { uoff(start_code), "offsetof(struct user, start_code)" },
2333 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2334 { uoff(signal), "offsetof(struct user, signal)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002335#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002336 { uoff(reserved), "offsetof(struct user, reserved)" },
Wichert Akkermanf90da011999-10-31 21:15:38 +00002337#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002338 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
Michal Ludvig10a88d02002-10-07 14:31:00 +00002339#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002340 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2341#endif
2342 { uoff(magic), "offsetof(struct user, magic)" },
2343 { uoff(u_comm), "offsetof(struct user, u_comm)" },
Michal Ludvig0e035502002-09-23 15:41:01 +00002344#if defined(I386) || defined(X86_64)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002345 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2346#endif /* I386 */
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00002347#endif /* !IA64 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002348#endif /* !ALPHA */
2349#endif /* !POWERPC/!SPARC */
2350#endif /* LINUX */
2351#ifdef SUNOS4
2352 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2353 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2354 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2355 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2356 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2357 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2358 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2359 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2360 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2361 { uoff(u_error), "offsetof(struct user, u_error)" },
2362 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2363 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2364 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2365 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2366 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2367 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2368 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2369 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2370 { uoff(u_code), "offsetof(struct user, u_code)" },
2371 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2372 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2373 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2374 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2375 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2376 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2377 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2378 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2379 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2380 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2381 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2382 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2383 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2384 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2385 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2386 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2387 { uoff(u_start), "offsetof(struct user, u_start)" },
2388 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2389 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2390 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2391 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2392 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2393 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2394 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2395 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2396 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2397#endif /* SUNOS4 */
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002398#ifndef HPPA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002399 { sizeof(struct user), "sizeof(struct user)" },
Wichert Akkermanc1652e22001-03-27 12:17:16 +00002400#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002401 { 0, NULL },
2402};
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002403#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002404
2405int
2406sys_ptrace(tcp)
2407struct tcb *tcp;
2408{
2409 char *cmd;
2410 struct xlat *x;
2411 long addr;
2412
2413 cmd = xlookup(ptrace_cmds, tcp->u_arg[0]);
2414 if (!cmd)
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002415#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002416 cmd = "PTRACE_???";
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002417#else
2418 cmd = "PT_???";
Roland McGrath5a223472002-12-15 23:58:26 +00002419#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002420 if (entering(tcp)) {
2421 tprintf("%s, %lu, ", cmd, tcp->u_arg[1]);
2422 addr = tcp->u_arg[2];
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002423#ifndef FREEBSD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002424 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2425 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2426 for (x = struct_user_offsets; x->str; x++) {
2427 if (x->val >= addr)
2428 break;
2429 }
2430 if (!x->str)
2431 tprintf("%#lx, ", addr);
2432 else if (x->val > addr && x != struct_user_offsets) {
2433 x--;
2434 tprintf("%s + %ld, ", x->str, addr - x->val);
2435 }
2436 else
2437 tprintf("%s, ", x->str);
2438 }
2439 else
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002440#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002441 tprintf("%#lx, ", tcp->u_arg[2]);
2442#ifdef LINUX
2443 switch (tcp->u_arg[0]) {
2444 case PTRACE_PEEKDATA:
2445 case PTRACE_PEEKTEXT:
2446 case PTRACE_PEEKUSER:
2447 break;
2448 case PTRACE_CONT:
2449 case PTRACE_SINGLESTEP:
2450 case PTRACE_SYSCALL:
2451 case PTRACE_DETACH:
2452 printsignal(tcp->u_arg[3]);
2453 break;
2454 default:
2455 tprintf("%#lx", tcp->u_arg[3]);
2456 break;
2457 }
2458 } else {
2459 switch (tcp->u_arg[0]) {
2460 case PTRACE_PEEKDATA:
2461 case PTRACE_PEEKTEXT:
2462 case PTRACE_PEEKUSER:
2463 printnum(tcp, tcp->u_arg[3], "%#x");
2464 break;
2465 }
2466 }
2467#endif /* LINUX */
2468#ifdef SUNOS4
2469 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2470 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2471 tprintf("%lu, ", tcp->u_arg[3]);
2472 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2473 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2474 tcp->u_arg[0] != PTRACE_READTEXT) {
2475 tprintf("%#lx", tcp->u_arg[3]);
2476 }
2477 } else {
2478 if (tcp->u_arg[0] == PTRACE_READDATA ||
2479 tcp->u_arg[0] == PTRACE_READTEXT) {
2480 tprintf("%lu, ", tcp->u_arg[3]);
2481 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2482 }
2483 }
2484#endif /* SUNOS4 */
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +00002485#ifdef FREEBSD
2486 tprintf("%lu", tcp->u_arg[3]);
2487 }
2488#endif /* FREEBSD */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002489 return 0;
2490}
2491
2492#endif /* !SVR4 */
Roland McGrath5a223472002-12-15 23:58:26 +00002493
2494#ifdef LINUX
2495static struct xlat futexops[] = {
2496 { FUTEX_WAIT, "FUTEX_WAIT" },
2497 { FUTEX_WAKE, "FUTEX_WAKE" },
2498 { FUTEX_FD, "FUTEX_FD" },
2499 { 0, NULL }
2500};
2501
2502int
2503sys_futex(tcp)
2504struct tcb *tcp;
2505{
2506 if (entering(tcp)) {
2507 tprintf("%p, ", (void *) tcp->u_arg[0]);
2508 printflags(futexops, tcp->u_arg[1]);
2509 tprintf(", %ld, ", tcp->u_arg[2]);
2510 printtv(tcp, tcp->u_arg[3]);
2511 }
2512 return 0;
2513}
2514
2515static void
2516print_affinitylist(list, len)
2517unsigned long *list;
2518unsigned int len;
2519{
2520 int first = 1;
2521 tprintf(" {");
2522 while (len > sizeof (unsigned long)) {
2523 tprintf("%s %lx", first ? "" : ",", *list++);
2524 first = 0;
2525 len -= sizeof (unsigned long);
2526 }
2527 tprintf(" }");
2528}
2529
2530int
2531sys_sched_setaffinity(tcp)
2532struct tcb *tcp;
2533{
2534 if (entering(tcp)) {
2535 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2536 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2537 }
2538 return 0;
2539}
2540
2541int
2542sys_sched_getaffinity(tcp)
2543struct tcb *tcp;
2544{
2545 if (entering(tcp)) {
2546 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2547 } else {
2548 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);
2549 }
2550 return 0;
2551}
2552#endif