1 /*
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>
5 * 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>
9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
11
12 *
13 * 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: process.c,v 1.97 2005/06/08 20:45:28 roland Exp $
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 #ifdef HAVE_ANDROID_OS
49 #include <asm/user.h>
50 #else
51 #include <sys/user.h>
52 #endif
53 #include <sys/syscall.h>
54 #include <signal.h>
55 #ifdef SUNOS4
56 #include <machine/reg.h>
57 #endif /* SUNOS4 */
58
59 #ifdef FREEBSD
60 #include <sys/ptrace.h>
61 #endif
62
63 #ifdef HAVE_ANDROID_OS
64 /* for struct sched_param */
65 #define sched_priority __sched_priority
66 #endif
67
68 #if HAVE_ASM_REG_H
69 #if defined (SPARC) || defined (SPARC64)
70 # define fpq kernel_fpq
71 # define fq kernel_fq
72 # define fpu kernel_fpu
73 #endif /* SPARC || SPARC64 */
74 #include <asm/reg.h>
75 #if defined (SPARC) || defined (SPARC64)
76 # undef fpq
77 # undef fq
78 # undef fpu
79 #endif /* SPARC || SPARC64 */
80 #endif /* HAVE_ASM_REG_H */
81
82 #ifdef HAVE_SYS_REG_H
83 # include <sys/reg.h>
84 #ifndef PTRACE_PEEKUSR
85 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
86 #endif
87 #ifndef PTRACE_POKEUSR
88 # define PTRACE_POKEUSR PTRACE_POKEUSER
89 #endif
90 #endif
91
92 #ifdef HAVE_LINUX_PTRACE_H
93 #undef PTRACE_SYSCALL
94 # ifdef HAVE_STRUCT_IA64_FPREG
95 # define ia64_fpreg XXX_ia64_fpreg
96 # endif
97 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
98 # define pt_all_user_regs XXX_pt_all_user_regs
99 # endif
100 #include <linux/ptrace.h>
101 # undef ia64_fpreg
102 # undef pt_all_user_regs
103 #endif
104
105 #if defined (LINUX) && defined (SPARC64)
106 # define r_pc r_tpc
107 # undef PTRACE_GETREGS
108 # define PTRACE_GETREGS PTRACE_GETREGS64
109 # undef PTRACE_SETREGS
110 # define PTRACE_SETREGS PTRACE_SETREGS64
111 #endif /* LINUX && SPARC64 */
112
113 #ifdef HAVE_LINUX_FUTEX_H
114 #include <linux/futex.h>
115 #endif
116 #if defined LINUX
117 # ifndef FUTEX_WAIT
118 # define FUTEX_WAIT 0
119 # endif
120 # ifndef FUTEX_WAKE
121 # define FUTEX_WAKE 1
122 # endif
123 # ifndef FUTEX_FD
124 # define FUTEX_FD 2
125 # endif
126 # ifndef FUTEX_REQUEUE
127 # define FUTEX_REQUEUE 3
128 # endif
129 #endif
130
131 #ifdef LINUX
132 #include <sched.h>
133 #include <asm/posix_types.h>
134 #undef GETGROUPS_T
135 #define GETGROUPS_T __kernel_gid_t
136 #undef GETGROUPS32_T
137 #define GETGROUPS32_T __kernel_gid32_t
138 #endif /* LINUX */
139
140 #if defined(LINUX) && defined(IA64)
141 # include <asm/ptrace_offsets.h>
142 # include <asm/rse.h>
143 #endif
144
145 #ifdef HAVE_PRCTL
146 #include <sys/prctl.h>
147 #endif
148
149 #ifndef WCOREDUMP
150 #define WCOREDUMP(status) ((status) & 0200)
151 #endif
152
153 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
154 #if defined(HAVE_PRCTL)
155 static const struct xlat prctl_options[] = {
156 #ifdef PR_MAXPROCS
157 { PR_MAXPROCS, "PR_MAXPROCS" },
158 #endif
159 #ifdef PR_ISBLOCKED
160 { PR_ISBLOCKED, "PR_ISBLOCKED" },
161 #endif
162 #ifdef PR_SETSTACKSIZE
163 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
164 #endif
165 #ifdef PR_GETSTACKSIZE
166 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
167 #endif
168 #ifdef PR_MAXPPROCS
169 { PR_MAXPPROCS, "PR_MAXPPROCS" },
170 #endif
171 #ifdef PR_UNBLKONEXEC
172 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
173 #endif
174 #ifdef PR_ATOMICSIM
175 { PR_ATOMICSIM, "PR_ATOMICSIM" },
176 #endif
177 #ifdef PR_SETEXITSIG
178 { PR_SETEXITSIG, "PR_SETEXITSIG" },
179 #endif
180 #ifdef PR_RESIDENT
181 { PR_RESIDENT, "PR_RESIDENT" },
182 #endif
183 #ifdef PR_ATTACHADDR
184 { PR_ATTACHADDR, "PR_ATTACHADDR" },
185 #endif
186 #ifdef PR_DETACHADDR
187 { PR_DETACHADDR, "PR_DETACHADDR" },
188 #endif
189 #ifdef PR_TERMCHILD
190 { PR_TERMCHILD, "PR_TERMCHILD" },
191 #endif
192 #ifdef PR_GETSHMASK
193 { PR_GETSHMASK, "PR_GETSHMASK" },
194 #endif
195 #ifdef PR_GETNSHARE
196 { PR_GETNSHARE, "PR_GETNSHARE" },
197 #endif
198 #if defined(PR_SET_PDEATHSIG)
199 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
200 #endif
201 #ifdef PR_COREPID
202 { PR_COREPID, "PR_COREPID" },
203 #endif
204 #ifdef PR_ATTACHADDRPERM
205 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
206 #endif
207 #ifdef PR_PTHREADEXIT
208 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
209 #endif
210 #ifdef PR_SET_PDEATHSIG
211 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
212 #endif
213 #ifdef PR_GET_PDEATHSIG
214 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
215 #endif
216 #ifdef PR_GET_UNALIGN
217 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
218 #endif
219 #ifdef PR_SET_UNALIGN
220 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
221 #endif
222 #ifdef PR_GET_KEEPCAPS
223 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
224 #endif
225 #ifdef PR_SET_KEEPCAPS
226 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
227 #endif
228 { 0, NULL },
229 };
230
231
232 static const char *
unalignctl_string(unsigned int ctl)233 unalignctl_string (unsigned int ctl)
234 {
235 static char buf[16];
236
237 switch (ctl) {
238 #ifdef PR_UNALIGN_NOPRINT
239 case PR_UNALIGN_NOPRINT:
240 return "NOPRINT";
241 #endif
242 #ifdef PR_UNALIGN_SIGBUS
243 case PR_UNALIGN_SIGBUS:
244 return "SIGBUS";
245 #endif
246 default:
247 break;
248 }
249 sprintf(buf, "%x", ctl);
250 return buf;
251 }
252
253
254 int
sys_prctl(tcp)255 sys_prctl(tcp)
256 struct tcb *tcp;
257 {
258 int i;
259
260 if (entering(tcp)) {
261 printxval(prctl_options, tcp->u_arg[0], "PR_???");
262 switch (tcp->u_arg[0]) {
263 #ifdef PR_GETNSHARE
264 case PR_GETNSHARE:
265 break;
266 #endif
267 #ifdef PR_SET_DEATHSIG
268 case PR_GET_PDEATHSIG:
269 break;
270 #endif
271 #ifdef PR_SET_UNALIGN
272 case PR_SET_UNALIGN:
273 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
274 break;
275 #endif
276 #ifdef PR_GET_UNALIGN
277 case PR_GET_UNALIGN:
278 tprintf(", %#lx", tcp->u_arg[1]);
279 break;
280 #endif
281 default:
282 for (i = 1; i < tcp->u_nargs; i++)
283 tprintf(", %#lx", tcp->u_arg[i]);
284 break;
285 }
286 } else {
287 switch (tcp->u_arg[0]) {
288 #ifdef PR_GET_PDEATHSIG
289 case PR_GET_PDEATHSIG:
290 for (i=1; i<tcp->u_nargs; i++)
291 tprintf(", %#lx", tcp->u_arg[i]);
292 break;
293 #endif
294 #ifdef PR_SET_UNALIGN
295 case PR_SET_UNALIGN:
296 break;
297 #endif
298 #ifdef PR_GET_UNALIGN
299 case PR_GET_UNALIGN:
300 {
301 int ctl;
302
303 umove(tcp, tcp->u_arg[1], &ctl);
304 tcp->auxstr = unalignctl_string(ctl);
305 return RVAL_STR;
306 }
307 #endif
308 default:
309 break;
310 }
311 }
312 return 0;
313 }
314
315 #endif /* HAVE_PRCTL */
316
317 int
sys_gethostid(tcp)318 sys_gethostid(tcp)
319 struct tcb *tcp;
320 {
321 if (exiting(tcp))
322 return RVAL_HEX;
323 return 0;
324 }
325
326 int
sys_sethostname(tcp)327 sys_sethostname(tcp)
328 struct tcb *tcp;
329 {
330 if (entering(tcp)) {
331 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
332 tprintf(", %lu", tcp->u_arg[1]);
333 }
334 return 0;
335 }
336
337 int
sys_gethostname(tcp)338 sys_gethostname(tcp)
339 struct tcb *tcp;
340 {
341 if (exiting(tcp)) {
342 if (syserror(tcp))
343 tprintf("%#lx", tcp->u_arg[0]);
344 else
345 printpath(tcp, tcp->u_arg[0]);
346 tprintf(", %lu", tcp->u_arg[1]);
347 }
348 return 0;
349 }
350
351 int
sys_setdomainname(tcp)352 sys_setdomainname(tcp)
353 struct tcb *tcp;
354 {
355 if (entering(tcp)) {
356 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
357 tprintf(", %lu", tcp->u_arg[1]);
358 }
359 return 0;
360 }
361
362 #if !defined(LINUX)
363
364 int
sys_getdomainname(tcp)365 sys_getdomainname(tcp)
366 struct tcb *tcp;
367 {
368 if (exiting(tcp)) {
369 if (syserror(tcp))
370 tprintf("%#lx", tcp->u_arg[0]);
371 else
372 printpath(tcp, tcp->u_arg[0]);
373 tprintf(", %lu", tcp->u_arg[1]);
374 }
375 return 0;
376 }
377 #endif /* !LINUX */
378
379 int
sys_exit(tcp)380 sys_exit(tcp)
381 struct tcb *tcp;
382 {
383 if (exiting(tcp)) {
384 fprintf(stderr, "_exit returned!\n");
385 return -1;
386 }
387 /* special case: we stop tracing this process, finish line now */
388 tprintf("%ld) ", tcp->u_arg[0]);
389 tabto(acolumn);
390 tprintf("= ?");
391 printtrailer(tcp);
392 return 0;
393 }
394
395 int
internal_exit(tcp)396 internal_exit(tcp)
397 struct tcb *tcp;
398 {
399 if (entering(tcp)) {
400 tcp->flags |= TCB_EXITING;
401 #ifdef __NR_exit_group
402 # ifdef IA64
403 if (ia32) {
404 if (tcp->scno == 252)
405 tcp->flags |= TCB_GROUP_EXITING;
406 } else
407 # endif
408 if (known_scno(tcp) == __NR_exit_group)
409 tcp->flags |= TCB_GROUP_EXITING;
410 #endif
411 }
412 return 0;
413 }
414
415 /* TCP is creating a child we want to follow.
416 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
417 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
418 static int
fork_tcb(struct tcb * tcp)419 fork_tcb(struct tcb *tcp)
420 {
421 if (nprocs == tcbtabsize) {
422 if (expand_tcbtab()) {
423 tcp->flags &= ~TCB_FOLLOWFORK;
424 fprintf(stderr, "sys_fork: tcb table full\n");
425 }
426 }
427
428 tcp->flags |= TCB_FOLLOWFORK;
429 return 0;
430 }
431
432 #ifdef USE_PROCFS
433
434 int
sys_fork(tcp)435 sys_fork(tcp)
436 struct tcb *tcp;
437 {
438 if (exiting(tcp)) {
439 if (getrval2(tcp)) {
440 tcp->auxstr = "child process";
441 return RVAL_UDECIMAL | RVAL_STR;
442 }
443 }
444 return 0;
445 }
446
447 #if UNIXWARE > 2
448
449 int
sys_rfork(tcp)450 sys_rfork(tcp)
451 struct tcb *tcp;
452 {
453 if (entering(tcp)) {
454 tprintf ("%ld", tcp->u_arg[0]);
455 }
456 else {
457 if (getrval2(tcp)) {
458 tcp->auxstr = "child process";
459 return RVAL_UDECIMAL | RVAL_STR;
460 }
461 }
462 return 0;
463 }
464
465 #endif
466
467 int
internal_fork(tcp)468 internal_fork(tcp)
469 struct tcb *tcp;
470 {
471 struct tcb *tcpchild;
472
473 if (exiting(tcp)) {
474 #ifdef SYS_rfork
475 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
476 return 0;
477 #endif
478 if (getrval2(tcp))
479 return 0;
480 if (!followfork)
481 return 0;
482 if (fork_tcb(tcp))
483 return 0;
484 if (syserror(tcp))
485 return 0;
486 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
487 fprintf(stderr, "sys_fork: tcb table full\n");
488 return 0;
489 }
490 if (proc_open(tcpchild, 2) < 0)
491 droptcb(tcpchild);
492 }
493 return 0;
494 }
495
496 #else /* !USE_PROCFS */
497
498 #ifdef LINUX
499
500 /* defines copied from linux/sched.h since we can't include that
501 * ourselves (it conflicts with *lots* of libc includes)
502 */
503 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
504 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
505 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
506 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
507 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
508 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
509 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
510 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
511 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
512 #define CLONE_THREAD 0x00010000 /* Same thread group? */
513 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
514 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
515 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
516 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
517 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
518 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
519 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
520 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
521
522 static const struct xlat clone_flags[] = {
523 { CLONE_VM, "CLONE_VM" },
524 { CLONE_FS, "CLONE_FS" },
525 { CLONE_FILES, "CLONE_FILES" },
526 { CLONE_SIGHAND, "CLONE_SIGHAND" },
527 { CLONE_IDLETASK, "CLONE_IDLETASK"},
528 { CLONE_PTRACE, "CLONE_PTRACE" },
529 { CLONE_VFORK, "CLONE_VFORK" },
530 { CLONE_PARENT, "CLONE_PARENT" },
531 { CLONE_THREAD, "CLONE_THREAD" },
532 { CLONE_NEWNS, "CLONE_NEWNS" },
533 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
534 { CLONE_SETTLS, "CLONE_SETTLS" },
535 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
536 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
537 { CLONE_DETACHED, "CLONE_DETACHED" },
538 { CLONE_UNTRACED, "CLONE_UNTRACED" },
539 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
540 { 0, NULL },
541 };
542
543 # ifdef I386
544 # include <asm/ldt.h>
545 # ifdef HAVE_STRUCT_USER_DESC
546 # define modify_ldt_ldt_s user_desc
547 # endif
548 extern void print_ldt_entry();
549 # endif
550
551 # if defined IA64
552 # define ARG_FLAGS 0
553 # define ARG_STACK 1
554 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
555 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
556 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
557 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
558 # elif defined S390 || defined S390X
559 # define ARG_STACK 0
560 # define ARG_FLAGS 1
561 # define ARG_PTID 2
562 # define ARG_CTID 3
563 # define ARG_TLS 4
564 # elif defined X86_64 || defined ALPHA
565 # define ARG_FLAGS 0
566 # define ARG_STACK 1
567 # define ARG_PTID 2
568 # define ARG_CTID 3
569 # define ARG_TLS 4
570 # else
571 # define ARG_FLAGS 0
572 # define ARG_STACK 1
573 # define ARG_PTID 2
574 # define ARG_TLS 3
575 # define ARG_CTID 4
576 # endif
577
578 int
sys_clone(tcp)579 sys_clone(tcp)
580 struct tcb *tcp;
581 {
582 if (exiting(tcp)) {
583 unsigned long flags = tcp->u_arg[ARG_FLAGS];
584 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
585 # ifdef ARG_STACKSIZE
586 if (ARG_STACKSIZE != -1)
587 tprintf("stack_size=%#lx, ",
588 tcp->u_arg[ARG_STACKSIZE]);
589 # endif
590 tprintf("flags=");
591 printflags(clone_flags, flags &~ CSIGNAL, NULL);
592 if ((flags & CSIGNAL) != 0)
593 tprintf("|%s", signame(flags & CSIGNAL));
594 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
595 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
596 return 0;
597 if (flags & CLONE_PARENT_SETTID)
598 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
599 if (flags & CLONE_SETTLS) {
600 # ifdef I386
601 struct modify_ldt_ldt_s copy;
602 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
603 tprintf(", {entry_number:%d, ",
604 copy.entry_number);
605 if (!verbose(tcp))
606 tprintf("...}");
607 else
608 print_ldt_entry(©);
609 }
610 else
611 # endif
612 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
613 }
614 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
615 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
616 }
617 return 0;
618 }
619 #endif
620
621 int
sys_fork(tcp)622 sys_fork(tcp)
623 struct tcb *tcp;
624 {
625 if (exiting(tcp))
626 return RVAL_UDECIMAL;
627 return 0;
628 }
629
630 int
change_syscall(tcp,new)631 change_syscall(tcp, new)
632 struct tcb *tcp;
633 int new;
634 {
635 #if defined(LINUX)
636 #if defined(I386)
637 /* Attempt to make vfork into fork, which we can follow. */
638 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
639 return -1;
640 return 0;
641 #elif defined(X86_64)
642 /* Attempt to make vfork into fork, which we can follow. */
643 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
644 return -1;
645 return 0;
646 #elif defined(POWERPC)
647 if (ptrace(PTRACE_POKEUSER, tcp->pid,
648 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
649 return -1;
650 return 0;
651 #elif defined(S390) || defined(S390X)
652 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
653 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
654 return -1;
655 return 0;
656 #elif defined(M68K)
657 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
658 return -1;
659 return 0;
660 #elif defined(SPARC) || defined(SPARC64)
661 struct regs regs;
662 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
663 return -1;
664 regs.r_g1=new;
665 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
666 return -1;
667 return 0;
668 #elif defined(MIPS)
669 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
670 return -1;
671 return 0;
672 #elif defined(ALPHA)
673 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
674 return -1;
675 return 0;
676 #elif defined(IA64)
677 if (ia32) {
678 switch (new) {
679 case 2: break; /* x86 SYS_fork */
680 case SYS_clone: new = 120; break;
681 default:
682 fprintf(stderr, "%s: unexpected syscall %d\n",
683 __FUNCTION__, new);
684 return -1;
685 }
686 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
687 return -1;
688 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
689 return -1;
690 return 0;
691 #elif defined(HPPA)
692 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
693 return -1;
694 return 0;
695 #elif defined(SH)
696 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
697 return -1;
698 return 0;
699 #elif defined(SH64)
700 /* Top half of reg encodes the no. of args n as 0x1n.
701 Assume 0 args as kernel never actually checks... */
702 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
703 0x100000 | new) < 0)
704 return -1;
705 return 0;
706 #elif defined(ARM)
707 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
708 # ifndef PTRACE_SET_SYSCALL
709 # define PTRACE_SET_SYSCALL 23
710 # endif
711
712 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
713 return -1;
714
715 return 0;
716 #else
717 #warning Do not know how to handle change_syscall for this architecture
718 #endif /* architecture */
719 #endif /* LINUX */
720 return -1;
721 }
722
723 #if 0
724 int
setarg(tcp,argnum)725 setarg(tcp, argnum)
726 struct tcb *tcp;
727 int argnum;
728 {
729 #if defined (IA64)
730 {
731 unsigned long *bsp, *ap;
732
733 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
734 return -1;
735
736 ap = ia64_rse_skip_regs(bsp, argnum);
737 errno = 0;
738 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
739 if (errno)
740 return -1;
741
742 }
743 #elif defined(I386)
744 {
745 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
746 if (errno)
747 return -1;
748 }
749 #elif defined(X86_64)
750 {
751 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
752 if (errno)
753 return -1;
754 }
755 #elif defined(POWERPC)
756 #ifndef PT_ORIG_R3
757 #define PT_ORIG_R3 34
758 #endif
759 {
760 ptrace(PTRACE_POKEUSER, tcp->pid,
761 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
762 tcp->u_arg[argnum]);
763 if (errno)
764 return -1;
765 }
766 #elif defined(MIPS)
767 {
768 errno = 0;
769 if (argnum < 4)
770 ptrace(PTRACE_POKEUSER, tcp->pid,
771 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
772 else {
773 unsigned long *sp;
774
775 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
776 return -1;
777
778 ptrace(PTRACE_POKEDATA, tcp->pid,
779 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
780 }
781 if (errno)
782 return -1;
783 }
784 #elif defined(S390) || defined(S390X)
785 {
786 if(argnum <= 5)
787 ptrace(PTRACE_POKEUSER, tcp->pid,
788 (char *) (argnum==0 ? PT_ORIGGPR2 :
789 PT_GPR2 + argnum*sizeof(long)),
790 tcp->u_arg[argnum]);
791 else
792 return -E2BIG;
793 if (errno)
794 return -1;
795 }
796 #else
797 # warning Sorry, setargs not implemented for this architecture.
798 #endif
799 return 0;
800 }
801 #endif
802
803 #if defined SYS_clone || defined SYS_clone2 || defined __NR_clone
804 int
internal_clone(tcp)805 internal_clone(tcp)
806 struct tcb *tcp;
807 {
808 struct tcb *tcpchild;
809 int pid;
810 if (entering(tcp)) {
811 if (!followfork)
812 return 0;
813 if (fork_tcb(tcp))
814 return 0;
815 if (setbpt(tcp) < 0)
816 return 0;
817 } else {
818 int bpt = tcp->flags & TCB_BPTSET;
819
820 if (!(tcp->flags & TCB_FOLLOWFORK))
821 return 0;
822
823 if (syserror(tcp)) {
824 if (bpt)
825 clearbpt(tcp);
826 return 0;
827 }
828
829 pid = tcp->u_rval;
830
831 #ifdef CLONE_PTRACE /* See new setbpt code. */
832 tcpchild = pid2tcb(pid);
833 if (tcpchild != NULL) {
834 /* The child already reported its startup trap
835 before the parent reported its syscall return. */
836 if ((tcpchild->flags
837 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
838 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
839 fprintf(stderr, "\
840 [preattached child %d of %d in weird state!]\n",
841 pid, tcp->pid);
842 }
843 else
844 #endif
845 if ((tcpchild = alloctcb(pid)) == NULL) {
846 if (bpt)
847 clearbpt(tcp);
848 fprintf(stderr, " [tcb table full]\n");
849 kill(pid, SIGKILL); /* XXX */
850 return 0;
851 }
852
853 #ifndef CLONE_PTRACE
854 /* Attach to the new child */
855 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
856 if (bpt)
857 clearbpt(tcp);
858 perror("PTRACE_ATTACH");
859 fprintf(stderr, "Too late?\n");
860 droptcb(tcpchild);
861 return 0;
862 }
863 #endif
864
865 if (bpt)
866 clearbpt(tcp);
867
868 tcpchild->flags |= TCB_ATTACHED;
869 /* Child has BPT too, must be removed on first occasion. */
870 if (bpt) {
871 tcpchild->flags |= TCB_BPTSET;
872 tcpchild->baddr = tcp->baddr;
873 memcpy(tcpchild->inst, tcp->inst,
874 sizeof tcpchild->inst);
875 }
876 tcpchild->parent = tcp;
877 tcp->nchildren++;
878 if (tcpchild->flags & TCB_SUSPENDED) {
879 /* The child was born suspended, due to our having
880 forced CLONE_PTRACE. */
881 if (bpt)
882 clearbpt(tcpchild);
883
884 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
885 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
886 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
887 return -1;
888 }
889
890 if (!qflag)
891 fprintf(stderr, "\
892 Process %u resumed (parent %d ready)\n",
893 pid, tcp->pid);
894 }
895 else {
896 newoutf(tcpchild);
897 if (!qflag)
898 fprintf(stderr, "Process %d attached\n", pid);
899 }
900
901 #ifdef TCB_CLONE_THREAD
902 {
903 /*
904 * Save the flags used in this call,
905 * in case we point TCP to our parent below.
906 */
907 int call_flags = tcp->u_arg[ARG_FLAGS];
908 if ((tcp->flags & TCB_CLONE_THREAD) &&
909 tcp->parent != NULL) {
910 /* The parent in this clone is itself a
911 thread belonging to another process.
912 There is no meaning to the parentage
913 relationship of the new child with the
914 thread, only with the process. We
915 associate the new thread with our
916 parent. Since this is done for every
917 new thread, there will never be a
918 TCB_CLONE_THREAD process that has
919 children. */
920 --tcp->nchildren;
921 tcp = tcp->parent;
922 tcpchild->parent = tcp;
923 ++tcp->nchildren;
924 }
925 if (call_flags & CLONE_THREAD) {
926 tcpchild->flags |= TCB_CLONE_THREAD;
927 ++tcp->nclone_threads;
928 }
929 if (call_flags & CLONE_DETACHED) {
930 tcpchild->flags |= TCB_CLONE_DETACHED;
931 ++tcp->nclone_detached;
932 }
933 }
934 #endif
935
936 }
937 return 0;
938 }
939 #endif
940
941 int
internal_fork(tcp)942 internal_fork(tcp)
943 struct tcb *tcp;
944 {
945 #ifdef LINUX
946 /* We do special magic with clone for any clone or fork. */
947 return internal_clone(tcp);
948 #else
949
950 struct tcb *tcpchild;
951 int pid;
952 int dont_follow = 0;
953
954 #ifdef SYS_vfork
955 if (known_scno(tcp) == SYS_vfork) {
956 /* Attempt to make vfork into fork, which we can follow. */
957 if (!followvfork ||
958 change_syscall(tcp, SYS_fork) < 0)
959 dont_follow = 1;
960 }
961 #endif
962 if (entering(tcp)) {
963 if (!followfork || dont_follow)
964 return 0;
965 if (fork_tcb(tcp))
966 return 0;
967 if (setbpt(tcp) < 0)
968 return 0;
969 }
970 else {
971 int bpt = tcp->flags & TCB_BPTSET;
972
973 if (!(tcp->flags & TCB_FOLLOWFORK))
974 return 0;
975 if (bpt)
976 clearbpt(tcp);
977
978 if (syserror(tcp))
979 return 0;
980
981 pid = tcp->u_rval;
982 if ((tcpchild = alloctcb(pid)) == NULL) {
983 fprintf(stderr, " [tcb table full]\n");
984 kill(pid, SIGKILL); /* XXX */
985 return 0;
986 }
987 #ifdef LINUX
988 #ifdef HPPA
989 /* The child must have run before it can be attached. */
990 /* This must be a bug in the parisc kernel, but I havn't
991 * identified it yet. Seems to be an issue associated
992 * with attaching to a process (which sends it a signal)
993 * before that process has ever been scheduled. When
994 * debugging, I started seeing crashes in
995 * arch/parisc/kernel/signal.c:do_signal(), apparently
996 * caused by r8 getting corrupt over the dequeue_signal()
997 * call. Didn't make much sense though...
998 */
999 {
1000 struct timeval tv;
1001 tv.tv_sec = 0;
1002 tv.tv_usec = 10000;
1003 select(0, NULL, NULL, NULL, &tv);
1004 }
1005 #endif
1006 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1007 perror("PTRACE_ATTACH");
1008 fprintf(stderr, "Too late?\n");
1009 droptcb(tcpchild);
1010 return 0;
1011 }
1012 #endif /* LINUX */
1013 #ifdef SUNOS4
1014 #ifdef oldway
1015 /* The child must have run before it can be attached. */
1016 {
1017 struct timeval tv;
1018 tv.tv_sec = 0;
1019 tv.tv_usec = 10000;
1020 select(0, NULL, NULL, NULL, &tv);
1021 }
1022 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1023 perror("PTRACE_ATTACH");
1024 fprintf(stderr, "Too late?\n");
1025 droptcb(tcpchild);
1026 return 0;
1027 }
1028 #else /* !oldway */
1029 /* Try to catch the new process as soon as possible. */
1030 {
1031 int i;
1032 for (i = 0; i < 1024; i++)
1033 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1034 break;
1035 if (i == 1024) {
1036 perror("PTRACE_ATTACH");
1037 fprintf(stderr, "Too late?\n");
1038 droptcb(tcpchild);
1039 return 0;
1040 }
1041 }
1042 #endif /* !oldway */
1043 #endif /* SUNOS4 */
1044 tcpchild->flags |= TCB_ATTACHED;
1045 /* Child has BPT too, must be removed on first occasion */
1046 if (bpt) {
1047 tcpchild->flags |= TCB_BPTSET;
1048 tcpchild->baddr = tcp->baddr;
1049 memcpy(tcpchild->inst, tcp->inst,
1050 sizeof tcpchild->inst);
1051 }
1052 newoutf(tcpchild);
1053 tcpchild->parent = tcp;
1054 tcp->nchildren++;
1055 if (!qflag)
1056 fprintf(stderr, "Process %d attached\n", pid);
1057 }
1058 return 0;
1059 #endif
1060 }
1061
1062 #endif /* !USE_PROCFS */
1063
1064 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1065
1066 int
sys_vfork(tcp)1067 sys_vfork(tcp)
1068 struct tcb *tcp;
1069 {
1070 if (exiting(tcp))
1071 return RVAL_UDECIMAL;
1072 return 0;
1073 }
1074
1075 #endif /* SUNOS4 || LINUX || FREEBSD */
1076
1077 #ifndef LINUX
1078
1079 static char idstr[16];
1080
1081 int
sys_getpid(tcp)1082 sys_getpid(tcp)
1083 struct tcb *tcp;
1084 {
1085 if (exiting(tcp)) {
1086 sprintf(idstr, "ppid %lu", getrval2(tcp));
1087 tcp->auxstr = idstr;
1088 return RVAL_STR;
1089 }
1090 return 0;
1091 }
1092
1093 int
sys_getuid(tcp)1094 sys_getuid(tcp)
1095 struct tcb *tcp;
1096 {
1097 if (exiting(tcp)) {
1098 sprintf(idstr, "euid %lu", getrval2(tcp));
1099 tcp->auxstr = idstr;
1100 return RVAL_STR;
1101 }
1102 return 0;
1103 }
1104
1105 int
sys_getgid(tcp)1106 sys_getgid(tcp)
1107 struct tcb *tcp;
1108 {
1109 if (exiting(tcp)) {
1110 sprintf(idstr, "egid %lu", getrval2(tcp));
1111 tcp->auxstr = idstr;
1112 return RVAL_STR;
1113 }
1114 return 0;
1115 }
1116
1117 #endif /* !LINUX */
1118
1119 #ifdef LINUX
1120
1121 int
sys_setuid(tcp)1122 sys_setuid(tcp)
1123 struct tcb *tcp;
1124 {
1125 if (entering(tcp)) {
1126 tprintf("%u", (uid_t) tcp->u_arg[0]);
1127 }
1128 return 0;
1129 }
1130
1131 int
sys_setgid(tcp)1132 sys_setgid(tcp)
1133 struct tcb *tcp;
1134 {
1135 if (entering(tcp)) {
1136 tprintf("%u", (gid_t) tcp->u_arg[0]);
1137 }
1138 return 0;
1139 }
1140
1141 int
sys_getresuid(tcp)1142 sys_getresuid(tcp)
1143 struct tcb *tcp;
1144 {
1145 if (exiting(tcp)) {
1146 __kernel_uid_t uid;
1147 if (syserror(tcp))
1148 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1149 tcp->u_arg[1], tcp->u_arg[2]);
1150 else {
1151 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1152 tprintf("%#lx, ", tcp->u_arg[0]);
1153 else
1154 tprintf("[%lu], ", (unsigned long) uid);
1155 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1156 tprintf("%#lx, ", tcp->u_arg[1]);
1157 else
1158 tprintf("[%lu], ", (unsigned long) uid);
1159 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1160 tprintf("%#lx", tcp->u_arg[2]);
1161 else
1162 tprintf("[%lu]", (unsigned long) uid);
1163 }
1164 }
1165 return 0;
1166 }
1167
1168 int
sys_getresgid(tcp)1169 sys_getresgid(tcp)
1170 struct tcb *tcp;
1171 {
1172 if (exiting(tcp)) {
1173 __kernel_gid_t gid;
1174 if (syserror(tcp))
1175 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1176 tcp->u_arg[1], tcp->u_arg[2]);
1177 else {
1178 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1179 tprintf("%#lx, ", tcp->u_arg[0]);
1180 else
1181 tprintf("[%lu], ", (unsigned long) gid);
1182 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1183 tprintf("%#lx, ", tcp->u_arg[1]);
1184 else
1185 tprintf("[%lu], ", (unsigned long) gid);
1186 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1187 tprintf("%#lx", tcp->u_arg[2]);
1188 else
1189 tprintf("[%lu]", (unsigned long) gid);
1190 }
1191 }
1192 return 0;
1193 }
1194
1195 #endif /* LINUX */
1196
1197 int
sys_setreuid(tcp)1198 sys_setreuid(tcp)
1199 struct tcb *tcp;
1200 {
1201 if (entering(tcp)) {
1202 printuid("", tcp->u_arg[0]);
1203 printuid(", ", tcp->u_arg[1]);
1204 }
1205 return 0;
1206 }
1207
1208 int
sys_setregid(tcp)1209 sys_setregid(tcp)
1210 struct tcb *tcp;
1211 {
1212 if (entering(tcp)) {
1213 printuid("", tcp->u_arg[0]);
1214 printuid(", ", tcp->u_arg[1]);
1215 }
1216 return 0;
1217 }
1218
1219 #if defined(LINUX) || defined(FREEBSD)
1220 int
sys_setresuid(tcp)1221 sys_setresuid(tcp)
1222 struct tcb *tcp;
1223 {
1224 if (entering(tcp)) {
1225 printuid("", tcp->u_arg[0]);
1226 printuid(", ", tcp->u_arg[1]);
1227 printuid(", ", tcp->u_arg[2]);
1228 }
1229 return 0;
1230 }
1231 int
sys_setresgid(tcp)1232 sys_setresgid(tcp)
1233 struct tcb *tcp;
1234 {
1235 if (entering(tcp)) {
1236 printuid("", tcp->u_arg[0]);
1237 printuid(", ", tcp->u_arg[1]);
1238 printuid(", ", tcp->u_arg[2]);
1239 }
1240 return 0;
1241 }
1242
1243 #endif /* LINUX || FREEBSD */
1244
1245 int
sys_setgroups(tcp)1246 sys_setgroups(tcp)
1247 struct tcb *tcp;
1248 {
1249 if (entering(tcp)) {
1250 unsigned long len, size, start, cur, end, abbrev_end;
1251 GETGROUPS_T gid;
1252 int failed = 0;
1253
1254 len = tcp->u_arg[0];
1255 tprintf("%lu, ", len);
1256 if (len == 0) {
1257 tprintf("[]");
1258 return 0;
1259 }
1260 start = tcp->u_arg[1];
1261 if (start == 0) {
1262 tprintf("NULL");
1263 return 0;
1264 }
1265 size = len * sizeof(gid);
1266 end = start + size;
1267 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1268 tprintf("%#lx", start);
1269 return 0;
1270 }
1271 if (abbrev(tcp)) {
1272 abbrev_end = start + max_strlen * sizeof(gid);
1273 if (abbrev_end < start)
1274 abbrev_end = end;
1275 } else {
1276 abbrev_end = end;
1277 }
1278 tprintf("[");
1279 for (cur = start; cur < end; cur += sizeof(gid)) {
1280 if (cur > start)
1281 tprintf(", ");
1282 if (cur >= abbrev_end) {
1283 tprintf("...");
1284 break;
1285 }
1286 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1287 tprintf("?");
1288 failed = 1;
1289 break;
1290 }
1291 tprintf("%lu", (unsigned long) gid);
1292 }
1293 tprintf("]");
1294 if (failed)
1295 tprintf(" %#lx", tcp->u_arg[1]);
1296 }
1297 return 0;
1298 }
1299
1300 int
sys_getgroups(tcp)1301 sys_getgroups(tcp)
1302 struct tcb *tcp;
1303 {
1304 unsigned long len;
1305
1306 if (entering(tcp)) {
1307 len = tcp->u_arg[0];
1308 tprintf("%lu, ", len);
1309 } else {
1310 unsigned long size, start, cur, end, abbrev_end;
1311 GETGROUPS_T gid;
1312 int failed = 0;
1313
1314 len = tcp->u_rval;
1315 if (len == 0) {
1316 tprintf("[]");
1317 return 0;
1318 }
1319 start = tcp->u_arg[1];
1320 if (start == 0) {
1321 tprintf("NULL");
1322 return 0;
1323 }
1324 if (tcp->u_arg[0] == 0) {
1325 tprintf("%#lx", start);
1326 return 0;
1327 }
1328 size = len * sizeof(gid);
1329 end = start + size;
1330 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1331 size / sizeof(gid) != len || end < start) {
1332 tprintf("%#lx", start);
1333 return 0;
1334 }
1335 if (abbrev(tcp)) {
1336 abbrev_end = start + max_strlen * sizeof(gid);
1337 if (abbrev_end < start)
1338 abbrev_end = end;
1339 } else {
1340 abbrev_end = end;
1341 }
1342 tprintf("[");
1343 for (cur = start; cur < end; cur += sizeof(gid)) {
1344 if (cur > start)
1345 tprintf(", ");
1346 if (cur >= abbrev_end) {
1347 tprintf("...");
1348 break;
1349 }
1350 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1351 tprintf("?");
1352 failed = 1;
1353 break;
1354 }
1355 tprintf("%lu", (unsigned long) gid);
1356 }
1357 tprintf("]");
1358 if (failed)
1359 tprintf(" %#lx", tcp->u_arg[1]);
1360 }
1361 return 0;
1362 }
1363
1364 #ifdef LINUX
1365 int
sys_setgroups32(tcp)1366 sys_setgroups32(tcp)
1367 struct tcb *tcp;
1368 {
1369 if (entering(tcp)) {
1370 unsigned long len, size, start, cur, end, abbrev_end;
1371 GETGROUPS32_T gid;
1372 int failed = 0;
1373
1374 len = tcp->u_arg[0];
1375 tprintf("%lu, ", len);
1376 if (len == 0) {
1377 tprintf("[]");
1378 return 0;
1379 }
1380 start = tcp->u_arg[1];
1381 if (start == 0) {
1382 tprintf("NULL");
1383 return 0;
1384 }
1385 size = len * sizeof(gid);
1386 end = start + size;
1387 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1388 tprintf("%#lx", start);
1389 return 0;
1390 }
1391 if (abbrev(tcp)) {
1392 abbrev_end = start + max_strlen * sizeof(gid);
1393 if (abbrev_end < start)
1394 abbrev_end = end;
1395 } else {
1396 abbrev_end = end;
1397 }
1398 tprintf("[");
1399 for (cur = start; cur < end; cur += sizeof(gid)) {
1400 if (cur > start)
1401 tprintf(", ");
1402 if (cur >= abbrev_end) {
1403 tprintf("...");
1404 break;
1405 }
1406 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1407 tprintf("?");
1408 failed = 1;
1409 break;
1410 }
1411 tprintf("%lu", (unsigned long) gid);
1412 }
1413 tprintf("]");
1414 if (failed)
1415 tprintf(" %#lx", tcp->u_arg[1]);
1416 }
1417 return 0;
1418 }
1419
1420 int
sys_getgroups32(tcp)1421 sys_getgroups32(tcp)
1422 struct tcb *tcp;
1423 {
1424 unsigned long len;
1425
1426 if (entering(tcp)) {
1427 len = tcp->u_arg[0];
1428 tprintf("%lu, ", len);
1429 } else {
1430 unsigned long size, start, cur, end, abbrev_end;
1431 GETGROUPS32_T gid;
1432 int failed = 0;
1433
1434 len = tcp->u_rval;
1435 if (len == 0) {
1436 tprintf("[]");
1437 return 0;
1438 }
1439 start = tcp->u_arg[1];
1440 if (start == 0) {
1441 tprintf("NULL");
1442 return 0;
1443 }
1444 size = len * sizeof(gid);
1445 end = start + size;
1446 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1447 size / sizeof(gid) != len || end < start) {
1448 tprintf("%#lx", start);
1449 return 0;
1450 }
1451 if (abbrev(tcp)) {
1452 abbrev_end = start + max_strlen * sizeof(gid);
1453 if (abbrev_end < start)
1454 abbrev_end = end;
1455 } else {
1456 abbrev_end = end;
1457 }
1458 tprintf("[");
1459 for (cur = start; cur < end; cur += sizeof(gid)) {
1460 if (cur > start)
1461 tprintf(", ");
1462 if (cur >= abbrev_end) {
1463 tprintf("...");
1464 break;
1465 }
1466 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1467 tprintf("?");
1468 failed = 1;
1469 break;
1470 }
1471 tprintf("%lu", (unsigned long) gid);
1472 }
1473 tprintf("]");
1474 if (failed)
1475 tprintf(" %#lx", tcp->u_arg[1]);
1476 }
1477 return 0;
1478 }
1479 #endif /* LINUX */
1480
1481 int
sys_setpgrp(tcp)1482 sys_setpgrp(tcp)
1483 struct tcb *tcp;
1484 {
1485 if (entering(tcp)) {
1486 #ifndef SVR4
1487 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1488 #endif /* !SVR4 */
1489 }
1490 return 0;
1491 }
1492
1493 int
sys_getpgrp(tcp)1494 sys_getpgrp(tcp)
1495 struct tcb *tcp;
1496 {
1497 if (entering(tcp)) {
1498 #ifndef SVR4
1499 tprintf("%lu", tcp->u_arg[0]);
1500 #endif /* !SVR4 */
1501 }
1502 return 0;
1503 }
1504
1505 int
sys_getsid(tcp)1506 sys_getsid(tcp)
1507 struct tcb *tcp;
1508 {
1509 if (entering(tcp)) {
1510 tprintf("%lu", tcp->u_arg[0]);
1511 }
1512 return 0;
1513 }
1514
1515 int
sys_setsid(tcp)1516 sys_setsid(tcp)
1517 struct tcb *tcp;
1518 {
1519 return 0;
1520 }
1521
1522 int
sys_getpgid(tcp)1523 sys_getpgid(tcp)
1524 struct tcb *tcp;
1525 {
1526 if (entering(tcp)) {
1527 tprintf("%lu", tcp->u_arg[0]);
1528 }
1529 return 0;
1530 }
1531
1532 int
sys_setpgid(tcp)1533 sys_setpgid(tcp)
1534 struct tcb *tcp;
1535 {
1536 if (entering(tcp)) {
1537 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1538 }
1539 return 0;
1540 }
1541
1542 #if UNIXWARE >= 2
1543
1544 #include <sys/privilege.h>
1545
1546
1547 static const struct xlat procpriv_cmds [] = {
1548 { SETPRV, "SETPRV" },
1549 { CLRPRV, "CLRPRV" },
1550 { PUTPRV, "PUTPRV" },
1551 { GETPRV, "GETPRV" },
1552 { CNTPRV, "CNTPRV" },
1553 { 0, NULL },
1554 };
1555
1556
1557 static const struct xlat procpriv_priv [] = {
1558 { P_OWNER, "P_OWNER" },
1559 { P_AUDIT, "P_AUDIT" },
1560 { P_COMPAT, "P_COMPAT" },
1561 { P_DACREAD, "P_DACREAD" },
1562 { P_DACWRITE, "P_DACWRITE" },
1563 { P_DEV, "P_DEV" },
1564 { P_FILESYS, "P_FILESYS" },
1565 { P_MACREAD, "P_MACREAD" },
1566 { P_MACWRITE, "P_MACWRITE" },
1567 { P_MOUNT, "P_MOUNT" },
1568 { P_MULTIDIR, "P_MULTIDIR" },
1569 { P_SETPLEVEL, "P_SETPLEVEL" },
1570 { P_SETSPRIV, "P_SETSPRIV" },
1571 { P_SETUID, "P_SETUID" },
1572 { P_SYSOPS, "P_SYSOPS" },
1573 { P_SETUPRIV, "P_SETUPRIV" },
1574 { P_DRIVER, "P_DRIVER" },
1575 { P_RTIME, "P_RTIME" },
1576 { P_MACUPGRADE, "P_MACUPGRADE" },
1577 { P_FSYSRANGE, "P_FSYSRANGE" },
1578 { P_SETFLEVEL, "P_SETFLEVEL" },
1579 { P_AUDITWR, "P_AUDITWR" },
1580 { P_TSHAR, "P_TSHAR" },
1581 { P_PLOCK, "P_PLOCK" },
1582 { P_CORE, "P_CORE" },
1583 { P_LOADMOD, "P_LOADMOD" },
1584 { P_BIND, "P_BIND" },
1585 { P_ALLPRIVS, "P_ALLPRIVS" },
1586 { 0, NULL },
1587 };
1588
1589
1590 static const struct xlat procpriv_type [] = {
1591 { PS_FIX, "PS_FIX" },
1592 { PS_INH, "PS_INH" },
1593 { PS_MAX, "PS_MAX" },
1594 { PS_WKG, "PS_WKG" },
1595 { 0, NULL },
1596 };
1597
1598
1599 static void
printpriv(tcp,addr,len,opt)1600 printpriv(tcp, addr, len, opt)
1601 struct tcb *tcp;
1602 long addr;
1603 int len;
1604 const struct xlat *opt;
1605 {
1606 priv_t buf [128];
1607 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1608 int dots = len > max;
1609 int i;
1610
1611 if (len > max) len = max;
1612
1613 if (len <= 0 ||
1614 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1615 {
1616 tprintf ("%#lx", addr);
1617 return;
1618 }
1619
1620 tprintf ("[");
1621
1622 for (i = 0; i < len; ++i) {
1623 char *t, *p;
1624
1625 if (i) tprintf (", ");
1626
1627 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1628 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1629 {
1630 tprintf ("%s|%s", t, p);
1631 }
1632 else {
1633 tprintf ("%#lx", buf [i]);
1634 }
1635 }
1636
1637 if (dots) tprintf (" ...");
1638
1639 tprintf ("]");
1640 }
1641
1642
1643 int
sys_procpriv(tcp)1644 sys_procpriv(tcp)
1645 struct tcb *tcp;
1646 {
1647 if (entering(tcp)) {
1648 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1649 switch (tcp->u_arg[0]) {
1650 case CNTPRV:
1651 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1652 break;
1653
1654 case GETPRV:
1655 break;
1656
1657 default:
1658 tprintf (", ");
1659 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1660 tprintf (", %ld", tcp->u_arg[2]);
1661 }
1662 }
1663 else if (tcp->u_arg[0] == GETPRV) {
1664 if (syserror (tcp)) {
1665 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1666 }
1667 else {
1668 tprintf (", ");
1669 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1670 tprintf (", %ld", tcp->u_arg[2]);
1671 }
1672 }
1673
1674 return 0;
1675 }
1676
1677 #endif
1678
1679
1680 static void
printargv(tcp,addr)1681 printargv(tcp, addr)
1682 struct tcb *tcp;
1683 long addr;
1684 {
1685 char *cp;
1686 char *sep;
1687 int max = max_strlen / 2;
1688
1689 for (sep = ""; --max >= 0; sep = ", ") {
1690 if (!abbrev(tcp))
1691 max++;
1692 if (umove(tcp, addr, &cp) < 0) {
1693 tprintf("%#lx", addr);
1694 return;
1695 }
1696 if (cp == 0)
1697 break;
1698 tprintf(sep);
1699 printstr(tcp, (long) cp, -1);
1700 addr += sizeof(char *);
1701 }
1702 if (cp)
1703 tprintf(", ...");
1704 }
1705
1706 static void
printargc(fmt,tcp,addr)1707 printargc(fmt, tcp, addr)
1708 char *fmt;
1709 struct tcb *tcp;
1710 long addr;
1711 {
1712 int count;
1713 char *cp;
1714
1715 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1716 addr += sizeof(char *);
1717 }
1718 tprintf(fmt, count, count == 1 ? "" : "s");
1719 }
1720
1721 int
sys_execv(tcp)1722 sys_execv(tcp)
1723 struct tcb *tcp;
1724 {
1725 if (entering(tcp)) {
1726 printpath(tcp, tcp->u_arg[0]);
1727 if (!verbose(tcp))
1728 tprintf(", %#lx", tcp->u_arg[1]);
1729 #if 0
1730 else if (abbrev(tcp))
1731 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1732 #endif
1733 else {
1734 tprintf(", [");
1735 printargv(tcp, tcp->u_arg[1]);
1736 tprintf("]");
1737 }
1738 }
1739 return 0;
1740 }
1741
1742 int
sys_execve(tcp)1743 sys_execve(tcp)
1744 struct tcb *tcp;
1745 {
1746 if (entering(tcp)) {
1747 printpath(tcp, tcp->u_arg[0]);
1748 if (!verbose(tcp))
1749 tprintf(", %#lx", tcp->u_arg[1]);
1750 #if 0
1751 else if (abbrev(tcp))
1752 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1753 #endif
1754 else {
1755 tprintf(", [");
1756 printargv(tcp, tcp->u_arg[1]);
1757 tprintf("]");
1758 }
1759 if (!verbose(tcp))
1760 tprintf(", %#lx", tcp->u_arg[2]);
1761 else if (abbrev(tcp))
1762 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1763 else {
1764 tprintf(", [");
1765 printargv(tcp, tcp->u_arg[2]);
1766 tprintf("]");
1767 }
1768 }
1769 return 0;
1770 }
1771
1772 #if UNIXWARE > 2
1773
sys_rexecve(tcp)1774 int sys_rexecve(tcp)
1775 struct tcb *tcp;
1776 {
1777 if (entering (tcp)) {
1778 sys_execve (tcp);
1779 tprintf (", %ld", tcp->u_arg[3]);
1780 }
1781 return 0;
1782 }
1783
1784 #endif
1785
1786 int
internal_exec(tcp)1787 internal_exec(tcp)
1788 struct tcb *tcp;
1789 {
1790 #ifdef SUNOS4
1791 if (exiting(tcp) && !syserror(tcp) && followfork)
1792 fixvfork(tcp);
1793 #endif /* SUNOS4 */
1794 #if defined LINUX && defined TCB_WAITEXECVE
1795 if (exiting(tcp) && syserror(tcp))
1796 tcp->flags &= ~TCB_WAITEXECVE;
1797 else
1798 tcp->flags |= TCB_WAITEXECVE;
1799 #endif /* LINUX && TCB_WAITEXECVE */
1800 return 0;
1801 }
1802
1803 #ifdef LINUX
1804 #ifndef __WNOTHREAD
1805 #define __WNOTHREAD 0x20000000
1806 #endif
1807 #ifndef __WALL
1808 #define __WALL 0x40000000
1809 #endif
1810 #ifndef __WCLONE
1811 #define __WCLONE 0x80000000
1812 #endif
1813 #endif /* LINUX */
1814
1815 static const struct xlat wait4_options[] = {
1816 { WNOHANG, "WNOHANG" },
1817 #ifndef WSTOPPED
1818 { WUNTRACED, "WUNTRACED" },
1819 #endif
1820 #ifdef WEXITED
1821 { WEXITED, "WEXITED" },
1822 #endif
1823 #ifdef WTRAPPED
1824 { WTRAPPED, "WTRAPPED" },
1825 #endif
1826 #ifdef WSTOPPED
1827 { WSTOPPED, "WSTOPPED" },
1828 #endif
1829 #ifdef WCONTINUED
1830 { WCONTINUED, "WCONTINUED" },
1831 #endif
1832 #ifdef WNOWAIT
1833 { WNOWAIT, "WNOWAIT" },
1834 #endif
1835 #ifdef __WCLONE
1836 { __WCLONE, "__WCLONE" },
1837 #endif
1838 #ifdef __WALL
1839 { __WALL, "__WALL" },
1840 #endif
1841 #ifdef __WNOTHREAD
1842 { __WNOTHREAD, "__WNOTHREAD" },
1843 #endif
1844 { 0, NULL },
1845 };
1846
1847 #if !defined WCOREFLAG && defined WCOREFLG
1848 # define WCOREFLAG WCOREFLG
1849 #endif
1850 #ifndef WCOREFLAG
1851 #define WCOREFLAG 0x80
1852 #endif
1853
1854 #ifndef W_STOPCODE
1855 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1856 #endif
1857 #ifndef W_EXITCODE
1858 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1859 #endif
1860
1861 static int
printstatus(status)1862 printstatus(status)
1863 int status;
1864 {
1865 int exited = 0;
1866
1867 /*
1868 * Here is a tricky presentation problem. This solution
1869 * is still not entirely satisfactory but since there
1870 * are no wait status constructors it will have to do.
1871 */
1872 if (WIFSTOPPED(status)) {
1873 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1874 signame(WSTOPSIG(status)));
1875 status &= ~W_STOPCODE(WSTOPSIG(status));
1876 }
1877 else if (WIFSIGNALED(status)) {
1878 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1879 signame(WTERMSIG(status)),
1880 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1881 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1882 }
1883 else if (WIFEXITED(status)) {
1884 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1885 WEXITSTATUS(status));
1886 exited = 1;
1887 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1888 }
1889 else {
1890 tprintf("[%#x]", status);
1891 return 0;
1892 }
1893
1894 if (status == 0)
1895 tprintf("]");
1896 else
1897 tprintf(" | %#x]", status);
1898
1899 return exited;
1900 }
1901
1902 static int
printwaitn(tcp,n,bitness)1903 printwaitn(tcp, n, bitness)
1904 struct tcb *tcp;
1905 int n;
1906 int bitness;
1907 {
1908 int status;
1909 int exited = 0;
1910
1911 if (entering(tcp)) {
1912 tprintf("%ld, ", tcp->u_arg[0]);
1913 } else {
1914 /* status */
1915 if (!tcp->u_arg[1])
1916 tprintf("NULL");
1917 else if (syserror(tcp) || tcp->u_rval == 0)
1918 tprintf("%#lx", tcp->u_arg[1]);
1919 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1920 tprintf("[?]");
1921 else
1922 exited = printstatus(status);
1923 /* options */
1924 tprintf(", ");
1925 printflags(wait4_options, tcp->u_arg[2], "W???");
1926 if (n == 4) {
1927 tprintf(", ");
1928 /* usage */
1929 if (!tcp->u_arg[3])
1930 tprintf("NULL");
1931 #ifdef LINUX
1932 else if (tcp->u_rval > 0) {
1933 #ifdef LINUX_64BIT
1934 if (bitness)
1935 printrusage32(tcp, tcp->u_arg[3]);
1936 else
1937 #endif
1938 printrusage(tcp, tcp->u_arg[3]);
1939 }
1940 #endif /* LINUX */
1941 #ifdef SUNOS4
1942 else if (tcp->u_rval > 0 && exited)
1943 printrusage(tcp, tcp->u_arg[3]);
1944 #endif /* SUNOS4 */
1945 else
1946 tprintf("%#lx", tcp->u_arg[3]);
1947 }
1948 }
1949 return 0;
1950 }
1951
1952 int
internal_wait(tcp,flagarg)1953 internal_wait(tcp, flagarg)
1954 struct tcb *tcp;
1955 int flagarg;
1956 {
1957 int got_kids;
1958
1959 #ifdef TCB_CLONE_THREAD
1960 if (tcp->flags & TCB_CLONE_THREAD)
1961 /* The children we wait for are our parent's children. */
1962 got_kids = (tcp->parent->nchildren
1963 > tcp->parent->nclone_detached);
1964 else
1965 got_kids = (tcp->nchildren > tcp->nclone_detached);
1966 #else
1967 got_kids = tcp->nchildren > 0;
1968 #endif
1969
1970 if (entering(tcp) && got_kids) {
1971 /* There are children that this parent should block for.
1972 But ptrace made us the parent of the traced children
1973 and the real parent will get ECHILD from the wait call.
1974
1975 XXX If we attached with strace -f -p PID, then there
1976 may be untraced dead children the parent could be reaping
1977 now, but we make him block. */
1978
1979 /* ??? WTA: fix bug with hanging children */
1980
1981 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1982 /*
1983 * There are traced children. We'll make the parent
1984 * block to avoid a false ECHILD error due to our
1985 * ptrace having stolen the children. However,
1986 * we shouldn't block if there are zombies to reap.
1987 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1988 */
1989 struct tcb *child = NULL;
1990 if (tcp->nzombies > 0 &&
1991 (tcp->u_arg[0] == -1 ||
1992 (child = pid2tcb(tcp->u_arg[0])) == NULL))
1993 return 0;
1994 if (tcp->u_arg[0] > 0) {
1995 /*
1996 * If the parent waits for a specified child
1997 * PID, then it must get ECHILD right away
1998 * if that PID is not one of its children.
1999 * Make sure that the requested PID matches
2000 * one of the parent's children that we are
2001 * tracing, and don't suspend it otherwise.
2002 */
2003 if (child == NULL)
2004 child = pid2tcb(tcp->u_arg[0]);
2005 if (child == NULL || child->parent != (
2006 #ifdef TCB_CLONE_THREAD
2007 (tcp->flags & TCB_CLONE_THREAD)
2008 ? tcp->parent :
2009 #endif
2010 tcp))
2011 return 0;
2012 }
2013 tcp->flags |= TCB_SUSPENDED;
2014 tcp->waitpid = tcp->u_arg[0];
2015 #ifdef TCB_CLONE_THREAD
2016 if (tcp->flags & TCB_CLONE_THREAD)
2017 tcp->parent->nclone_waiting++;
2018 #endif
2019 }
2020 }
2021 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2022 if (tcp->u_arg[flagarg] & WNOHANG) {
2023 /* We must force a fake result of 0 instead of
2024 the ECHILD error. */
2025 extern int force_result();
2026 return force_result(tcp, 0, 0);
2027 }
2028 }
2029 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2030 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2031 /*
2032 * We just reaped a child we don't know about,
2033 * presumably a zombie we already droptcb'd.
2034 */
2035 tcp->nzombies--;
2036 }
2037 return 0;
2038 }
2039
2040 #ifdef SVR4
2041
2042 int
sys_wait(tcp)2043 sys_wait(tcp)
2044 struct tcb *tcp;
2045 {
2046 if (exiting(tcp)) {
2047 /* The library wrapper stuffs this into the user variable. */
2048 if (!syserror(tcp))
2049 printstatus(getrval2(tcp));
2050 }
2051 return 0;
2052 }
2053
2054 #endif /* SVR4 */
2055
2056 #ifdef FREEBSD
2057 int
sys_wait(tcp)2058 sys_wait(tcp)
2059 struct tcb *tcp;
2060 {
2061 int status;
2062
2063 if (exiting(tcp)) {
2064 if (!syserror(tcp)) {
2065 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2066 tprintf("%#lx", tcp->u_arg[0]);
2067 else
2068 printstatus(status);
2069 }
2070 }
2071 return 0;
2072 }
2073 #endif
2074
2075 int
sys_waitpid(tcp)2076 sys_waitpid(tcp)
2077 struct tcb *tcp;
2078 {
2079 return printwaitn(tcp, 3, 0);
2080 }
2081
2082 int
sys_wait4(tcp)2083 sys_wait4(tcp)
2084 struct tcb *tcp;
2085 {
2086 return printwaitn(tcp, 4, 0);
2087 }
2088
2089 #ifdef ALPHA
2090 int
sys_osf_wait4(tcp)2091 sys_osf_wait4(tcp)
2092 struct tcb *tcp;
2093 {
2094 return printwaitn(tcp, 4, 1);
2095 }
2096 #endif
2097
2098 #if defined SVR4 || defined LINUX
2099
2100 static const struct xlat waitid_types[] = {
2101 { P_PID, "P_PID" },
2102 #ifdef P_PPID
2103 { P_PPID, "P_PPID" },
2104 #endif
2105 { P_PGID, "P_PGID" },
2106 #ifdef P_SID
2107 { P_SID, "P_SID" },
2108 #endif
2109 #ifdef P_CID
2110 { P_CID, "P_CID" },
2111 #endif
2112 #ifdef P_UID
2113 { P_UID, "P_UID" },
2114 #endif
2115 #ifdef P_GID
2116 { P_GID, "P_GID" },
2117 #endif
2118 { P_ALL, "P_ALL" },
2119 #ifdef P_LWPID
2120 { P_LWPID, "P_LWPID" },
2121 #endif
2122 { 0, NULL },
2123 };
2124
2125 int
sys_waitid(tcp)2126 sys_waitid(tcp)
2127 struct tcb *tcp;
2128 {
2129 siginfo_t si;
2130 int exited;
2131
2132 if (entering(tcp)) {
2133 printxval(waitid_types, tcp->u_arg[0], "P_???");
2134 tprintf(", %ld, ", tcp->u_arg[1]);
2135 }
2136 else {
2137 /* siginfo */
2138 exited = 0;
2139 if (!tcp->u_arg[2])
2140 tprintf("NULL");
2141 else if (syserror(tcp))
2142 tprintf("%#lx", tcp->u_arg[2]);
2143 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2144 tprintf("{???}");
2145 else
2146 printsiginfo(&si, verbose (tcp));
2147 /* options */
2148 tprintf(", ");
2149 printflags(wait4_options, tcp->u_arg[3], "W???");
2150 if (tcp->u_nargs > 4) {
2151 /* usage */
2152 tprintf(", ");
2153 if (!tcp->u_arg[4])
2154 tprintf("NULL");
2155 else if (tcp->u_error)
2156 tprintf("%#lx", tcp->u_arg[4]);
2157 else
2158 printrusage(tcp, tcp->u_arg[4]);
2159 }
2160 }
2161 return 0;
2162 }
2163
2164 #endif /* SVR4 or LINUX */
2165
2166 int
sys_alarm(tcp)2167 sys_alarm(tcp)
2168 struct tcb *tcp;
2169 {
2170 if (entering(tcp))
2171 tprintf("%lu", tcp->u_arg[0]);
2172 return 0;
2173 }
2174
2175 int
sys_uname(tcp)2176 sys_uname(tcp)
2177 struct tcb *tcp;
2178 {
2179 struct utsname uname;
2180
2181 if (exiting(tcp)) {
2182 if (syserror(tcp) || !verbose(tcp))
2183 tprintf("%#lx", tcp->u_arg[0]);
2184 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2185 tprintf("{...}");
2186 else if (!abbrev(tcp)) {
2187
2188 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2189 uname.sysname, uname.nodename);
2190 tprintf("release=\"%s\", version=\"%s\", ",
2191 uname.release, uname.version);
2192 tprintf("machine=\"%s\"", uname.machine);
2193 #ifdef LINUX
2194 #ifndef __GLIBC__
2195 tprintf(", domainname=\"%s\"", uname.domainname);
2196 #endif /* __GLIBC__ */
2197 #endif /* LINUX */
2198 tprintf("}");
2199 }
2200 else
2201 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2202 uname.sysname, uname.nodename);
2203 }
2204 return 0;
2205 }
2206
2207 #ifndef SVR4
2208
2209 static const struct xlat ptrace_cmds[] = {
2210 #ifndef FREEBSD
2211 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2212 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2213 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2214 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2215 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2216 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2217 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2218 { PTRACE_CONT, "PTRACE_CONT" },
2219 { PTRACE_KILL, "PTRACE_KILL" },
2220 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2221 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2222 { PTRACE_DETACH, "PTRACE_DETACH" },
2223 #ifdef PTRACE_GETREGS
2224 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2225 #endif
2226 #ifdef PTRACE_SETREGS
2227 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2228 #endif
2229 #ifdef PTRACE_GETFPREGS
2230 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2231 #endif
2232 #ifdef PTRACE_SETFPREGS
2233 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2234 #endif
2235 #ifdef PTRACE_GETFPXREGS
2236 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2237 #endif
2238 #ifdef PTRACE_SETFPXREGS
2239 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2240 #endif
2241 #ifdef PTRACE_GETVRREGS
2242 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2243 #endif
2244 #ifdef PTRACE_SETVRREGS
2245 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2246 #endif
2247 #ifdef SUNOS4
2248 { PTRACE_READDATA, "PTRACE_READDATA" },
2249 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2250 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2251 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2252 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2253 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2254 #ifdef SPARC
2255 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2256 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2257 #else /* !SPARC */
2258 { PTRACE_22, "PTRACE_PTRACE_22" },
2259 { PTRACE_23, "PTRACE_PTRACE_23" },
2260 #endif /* !SPARC */
2261 #endif /* SUNOS4 */
2262 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2263 #ifdef SUNOS4
2264 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2265 #ifdef I386
2266 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2267 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2268 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2269 #else /* !I386 */
2270 { PTRACE_26, "PTRACE_26" },
2271 { PTRACE_27, "PTRACE_27" },
2272 { PTRACE_28, "PTRACE_28" },
2273 #endif /* !I386 */
2274 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2275 #endif /* SUNOS4 */
2276 #else /* FREEBSD */
2277 { PT_TRACE_ME, "PT_TRACE_ME" },
2278 { PT_READ_I, "PT_READ_I" },
2279 { PT_READ_D, "PT_READ_D" },
2280 { PT_WRITE_I, "PT_WRITE_I" },
2281 { PT_WRITE_D, "PT_WRITE_D" },
2282 #ifdef PT_READ_U
2283 { PT_READ_U, "PT_READ_U" },
2284 #endif
2285 { PT_CONTINUE, "PT_CONTINUE" },
2286 { PT_KILL, "PT_KILL" },
2287 { PT_STEP, "PT_STEP" },
2288 { PT_ATTACH, "PT_ATTACH" },
2289 { PT_DETACH, "PT_DETACH" },
2290 { PT_GETREGS, "PT_GETREGS" },
2291 { PT_SETREGS, "PT_SETREGS" },
2292 { PT_GETFPREGS, "PT_GETFPREGS" },
2293 { PT_SETFPREGS, "PT_SETFPREGS" },
2294 { PT_GETDBREGS, "PT_GETDBREGS" },
2295 { PT_SETDBREGS, "PT_SETDBREGS" },
2296 #endif /* FREEBSD */
2297 { 0, NULL },
2298 };
2299
2300 #ifndef FREEBSD
2301 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2302 static
2303 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2304 const struct xlat struct_user_offsets[] = {
2305 #ifdef LINUX
2306 #if defined(S390) || defined(S390X)
2307 { PT_PSWMASK, "psw_mask" },
2308 { PT_PSWADDR, "psw_addr" },
2309 { PT_GPR0, "gpr0" },
2310 { PT_GPR1, "gpr1" },
2311 { PT_GPR2, "gpr2" },
2312 { PT_GPR3, "gpr3" },
2313 { PT_GPR4, "gpr4" },
2314 { PT_GPR5, "gpr5" },
2315 { PT_GPR6, "gpr6" },
2316 { PT_GPR7, "gpr7" },
2317 { PT_GPR8, "gpr8" },
2318 { PT_GPR9, "gpr9" },
2319 { PT_GPR10, "gpr10" },
2320 { PT_GPR11, "gpr11" },
2321 { PT_GPR12, "gpr12" },
2322 { PT_GPR13, "gpr13" },
2323 { PT_GPR14, "gpr14" },
2324 { PT_GPR15, "gpr15" },
2325 { PT_ACR0, "acr0" },
2326 { PT_ACR1, "acr1" },
2327 { PT_ACR2, "acr2" },
2328 { PT_ACR3, "acr3" },
2329 { PT_ACR4, "acr4" },
2330 { PT_ACR5, "acr5" },
2331 { PT_ACR6, "acr6" },
2332 { PT_ACR7, "acr7" },
2333 { PT_ACR8, "acr8" },
2334 { PT_ACR9, "acr9" },
2335 { PT_ACR10, "acr10" },
2336 { PT_ACR11, "acr11" },
2337 { PT_ACR12, "acr12" },
2338 { PT_ACR13, "acr13" },
2339 { PT_ACR14, "acr14" },
2340 { PT_ACR15, "acr15" },
2341 { PT_ORIGGPR2, "orig_gpr2" },
2342 { PT_FPC, "fpc" },
2343 #if defined(S390)
2344 { PT_FPR0_HI, "fpr0.hi" },
2345 { PT_FPR0_LO, "fpr0.lo" },
2346 { PT_FPR1_HI, "fpr1.hi" },
2347 { PT_FPR1_LO, "fpr1.lo" },
2348 { PT_FPR2_HI, "fpr2.hi" },
2349 { PT_FPR2_LO, "fpr2.lo" },
2350 { PT_FPR3_HI, "fpr3.hi" },
2351 { PT_FPR3_LO, "fpr3.lo" },
2352 { PT_FPR4_HI, "fpr4.hi" },
2353 { PT_FPR4_LO, "fpr4.lo" },
2354 { PT_FPR5_HI, "fpr5.hi" },
2355 { PT_FPR5_LO, "fpr5.lo" },
2356 { PT_FPR6_HI, "fpr6.hi" },
2357 { PT_FPR6_LO, "fpr6.lo" },
2358 { PT_FPR7_HI, "fpr7.hi" },
2359 { PT_FPR7_LO, "fpr7.lo" },
2360 { PT_FPR8_HI, "fpr8.hi" },
2361 { PT_FPR8_LO, "fpr8.lo" },
2362 { PT_FPR9_HI, "fpr9.hi" },
2363 { PT_FPR9_LO, "fpr9.lo" },
2364 { PT_FPR10_HI, "fpr10.hi" },
2365 { PT_FPR10_LO, "fpr10.lo" },
2366 { PT_FPR11_HI, "fpr11.hi" },
2367 { PT_FPR11_LO, "fpr11.lo" },
2368 { PT_FPR12_HI, "fpr12.hi" },
2369 { PT_FPR12_LO, "fpr12.lo" },
2370 { PT_FPR13_HI, "fpr13.hi" },
2371 { PT_FPR13_LO, "fpr13.lo" },
2372 { PT_FPR14_HI, "fpr14.hi" },
2373 { PT_FPR14_LO, "fpr14.lo" },
2374 { PT_FPR15_HI, "fpr15.hi" },
2375 { PT_FPR15_LO, "fpr15.lo" },
2376 #endif
2377 #if defined(S390X)
2378 { PT_FPR0, "fpr0" },
2379 { PT_FPR1, "fpr1" },
2380 { PT_FPR2, "fpr2" },
2381 { PT_FPR3, "fpr3" },
2382 { PT_FPR4, "fpr4" },
2383 { PT_FPR5, "fpr5" },
2384 { PT_FPR6, "fpr6" },
2385 { PT_FPR7, "fpr7" },
2386 { PT_FPR8, "fpr8" },
2387 { PT_FPR9, "fpr9" },
2388 { PT_FPR10, "fpr10" },
2389 { PT_FPR11, "fpr11" },
2390 { PT_FPR12, "fpr12" },
2391 { PT_FPR13, "fpr13" },
2392 { PT_FPR14, "fpr14" },
2393 { PT_FPR15, "fpr15" },
2394 #endif
2395 { PT_CR_9, "cr9" },
2396 { PT_CR_10, "cr10" },
2397 { PT_CR_11, "cr11" },
2398 { PT_IEEE_IP, "ieee_exception_ip" },
2399 #endif
2400 #if defined(SPARC)
2401 /* XXX No support for these offsets yet. */
2402 #elif defined(HPPA)
2403 /* XXX No support for these offsets yet. */
2404 #elif defined(POWERPC)
2405 #ifndef PT_ORIG_R3
2406 #define PT_ORIG_R3 34
2407 #endif
2408 #define REGSIZE (sizeof(unsigned long))
2409 { REGSIZE*PT_R0, "r0" },
2410 { REGSIZE*PT_R1, "r1" },
2411 { REGSIZE*PT_R2, "r2" },
2412 { REGSIZE*PT_R3, "r3" },
2413 { REGSIZE*PT_R4, "r4" },
2414 { REGSIZE*PT_R5, "r5" },
2415 { REGSIZE*PT_R6, "r6" },
2416 { REGSIZE*PT_R7, "r7" },
2417 { REGSIZE*PT_R8, "r8" },
2418 { REGSIZE*PT_R9, "r9" },
2419 { REGSIZE*PT_R10, "r10" },
2420 { REGSIZE*PT_R11, "r11" },
2421 { REGSIZE*PT_R12, "r12" },
2422 { REGSIZE*PT_R13, "r13" },
2423 { REGSIZE*PT_R14, "r14" },
2424 { REGSIZE*PT_R15, "r15" },
2425 { REGSIZE*PT_R16, "r16" },
2426 { REGSIZE*PT_R17, "r17" },
2427 { REGSIZE*PT_R18, "r18" },
2428 { REGSIZE*PT_R19, "r19" },
2429 { REGSIZE*PT_R20, "r20" },
2430 { REGSIZE*PT_R21, "r21" },
2431 { REGSIZE*PT_R22, "r22" },
2432 { REGSIZE*PT_R23, "r23" },
2433 { REGSIZE*PT_R24, "r24" },
2434 { REGSIZE*PT_R25, "r25" },
2435 { REGSIZE*PT_R26, "r26" },
2436 { REGSIZE*PT_R27, "r27" },
2437 { REGSIZE*PT_R28, "r28" },
2438 { REGSIZE*PT_R29, "r29" },
2439 { REGSIZE*PT_R30, "r30" },
2440 { REGSIZE*PT_R31, "r31" },
2441 { REGSIZE*PT_NIP, "NIP" },
2442 { REGSIZE*PT_MSR, "MSR" },
2443 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2444 { REGSIZE*PT_CTR, "CTR" },
2445 { REGSIZE*PT_LNK, "LNK" },
2446 { REGSIZE*PT_XER, "XER" },
2447 { REGSIZE*PT_CCR, "CCR" },
2448 { REGSIZE*PT_FPR0, "FPR0" },
2449 #undef REGSIZE
2450 #else
2451 #ifdef ALPHA
2452 { 0, "r0" },
2453 { 1, "r1" },
2454 { 2, "r2" },
2455 { 3, "r3" },
2456 { 4, "r4" },
2457 { 5, "r5" },
2458 { 6, "r6" },
2459 { 7, "r7" },
2460 { 8, "r8" },
2461 { 9, "r9" },
2462 { 10, "r10" },
2463 { 11, "r11" },
2464 { 12, "r12" },
2465 { 13, "r13" },
2466 { 14, "r14" },
2467 { 15, "r15" },
2468 { 16, "r16" },
2469 { 17, "r17" },
2470 { 18, "r18" },
2471 { 19, "r19" },
2472 { 20, "r20" },
2473 { 21, "r21" },
2474 { 22, "r22" },
2475 { 23, "r23" },
2476 { 24, "r24" },
2477 { 25, "r25" },
2478 { 26, "r26" },
2479 { 27, "r27" },
2480 { 28, "r28" },
2481 { 29, "gp" },
2482 { 30, "fp" },
2483 { 31, "zero" },
2484 { 32, "fp0" },
2485 { 33, "fp" },
2486 { 34, "fp2" },
2487 { 35, "fp3" },
2488 { 36, "fp4" },
2489 { 37, "fp5" },
2490 { 38, "fp6" },
2491 { 39, "fp7" },
2492 { 40, "fp8" },
2493 { 41, "fp9" },
2494 { 42, "fp10" },
2495 { 43, "fp11" },
2496 { 44, "fp12" },
2497 { 45, "fp13" },
2498 { 46, "fp14" },
2499 { 47, "fp15" },
2500 { 48, "fp16" },
2501 { 49, "fp17" },
2502 { 50, "fp18" },
2503 { 51, "fp19" },
2504 { 52, "fp20" },
2505 { 53, "fp21" },
2506 { 54, "fp22" },
2507 { 55, "fp23" },
2508 { 56, "fp24" },
2509 { 57, "fp25" },
2510 { 58, "fp26" },
2511 { 59, "fp27" },
2512 { 60, "fp28" },
2513 { 61, "fp29" },
2514 { 62, "fp30" },
2515 { 63, "fp31" },
2516 { 64, "pc" },
2517 #else /* !ALPHA */
2518 #ifdef IA64
2519 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2520 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2521 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2522 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2523 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2524 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2525 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2526 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2527 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2528 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2529 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2530 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2531 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2532 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2533 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2534 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2535 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2536 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2537 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2538 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2539 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2540 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2541 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2542 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2543 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2544 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2545 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2546 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2547 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2548 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2549 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2550 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2551 /* switch stack: */
2552 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2553 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2554 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2555 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2556 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2557 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2558 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2559 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2560 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2561 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2562 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2563 { PT_B4, "b4" }, { PT_B5, "b5" },
2564 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2565 /* pt_regs */
2566 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2567 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2568 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2569 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2570 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2571 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2572 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2573 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2574 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2575 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2576 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2577 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2578 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2579 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2580 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2581 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2582 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2583 # ifdef PT_AR_CSD
2584 { PT_AR_CSD, "ar.csd" },
2585 # endif
2586 # ifdef PT_AR_SSD
2587 { PT_AR_SSD, "ar.ssd" },
2588 # endif
2589 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2590 #else /* !IA64 */
2591 #ifdef I386
2592 { 4*EBX, "4*EBX" },
2593 { 4*ECX, "4*ECX" },
2594 { 4*EDX, "4*EDX" },
2595 { 4*ESI, "4*ESI" },
2596 { 4*EDI, "4*EDI" },
2597 { 4*EBP, "4*EBP" },
2598 { 4*EAX, "4*EAX" },
2599 { 4*DS, "4*DS" },
2600 { 4*ES, "4*ES" },
2601 { 4*FS, "4*FS" },
2602 { 4*GS, "4*GS" },
2603 { 4*ORIG_EAX, "4*ORIG_EAX" },
2604 { 4*EIP, "4*EIP" },
2605 { 4*CS, "4*CS" },
2606 { 4*EFL, "4*EFL" },
2607 { 4*UESP, "4*UESP" },
2608 { 4*SS, "4*SS" },
2609 #else /* !I386 */
2610 #ifdef X86_64
2611 { 8*R15, "8*R15" },
2612 { 8*R14, "8*R14" },
2613 { 8*R13, "8*R13" },
2614 { 8*R12, "8*R12" },
2615 { 8*RBP, "8*RBP" },
2616 { 8*RBX, "8*RBX" },
2617 { 8*R11, "8*R11" },
2618 { 8*R10, "8*R10" },
2619 { 8*R9, "8*R9" },
2620 { 8*R8, "8*R8" },
2621 { 8*RAX, "8*RAX" },
2622 { 8*RCX, "8*RCX" },
2623 { 8*RDX, "8*RDX" },
2624 { 8*RSI, "8*RSI" },
2625 { 8*RDI, "8*RDI" },
2626 #if 0
2627 { DS, "DS" },
2628 { ES, "ES" },
2629 { FS, "FS" },
2630 { GS, "GS" },
2631 #endif
2632 { 8*ORIG_RAX, "8*ORIG_RAX" },
2633 { 8*RIP, "8*RIP" },
2634 { 8*CS, "8*CS" },
2635 { 8*EFLAGS, "8*EFL" },
2636 { 8*RSP, "8*RSP" },
2637 { 8*SS, "8*SS" },
2638 #endif
2639 #ifdef M68K
2640 { 4*PT_D1, "4*PT_D1" },
2641 { 4*PT_D2, "4*PT_D2" },
2642 { 4*PT_D3, "4*PT_D3" },
2643 { 4*PT_D4, "4*PT_D4" },
2644 { 4*PT_D5, "4*PT_D5" },
2645 { 4*PT_D6, "4*PT_D6" },
2646 { 4*PT_D7, "4*PT_D7" },
2647 { 4*PT_A0, "4*PT_A0" },
2648 { 4*PT_A1, "4*PT_A1" },
2649 { 4*PT_A2, "4*PT_A2" },
2650 { 4*PT_A3, "4*PT_A3" },
2651 { 4*PT_A4, "4*PT_A4" },
2652 { 4*PT_A5, "4*PT_A5" },
2653 { 4*PT_A6, "4*PT_A6" },
2654 { 4*PT_D0, "4*PT_D0" },
2655 { 4*PT_USP, "4*PT_USP" },
2656 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2657 { 4*PT_SR, "4*PT_SR" },
2658 { 4*PT_PC, "4*PT_PC" },
2659 #endif /* M68K */
2660 #endif /* !I386 */
2661 #ifdef SH
2662 { 4*REG_REG0, "4*REG_REG0" },
2663 { 4*(REG_REG0+1), "4*REG_REG1" },
2664 { 4*(REG_REG0+2), "4*REG_REG2" },
2665 { 4*(REG_REG0+3), "4*REG_REG3" },
2666 { 4*(REG_REG0+4), "4*REG_REG4" },
2667 { 4*(REG_REG0+5), "4*REG_REG5" },
2668 { 4*(REG_REG0+6), "4*REG_REG6" },
2669 { 4*(REG_REG0+7), "4*REG_REG7" },
2670 { 4*(REG_REG0+8), "4*REG_REG8" },
2671 { 4*(REG_REG0+9), "4*REG_REG9" },
2672 { 4*(REG_REG0+10), "4*REG_REG10" },
2673 { 4*(REG_REG0+11), "4*REG_REG11" },
2674 { 4*(REG_REG0+12), "4*REG_REG12" },
2675 { 4*(REG_REG0+13), "4*REG_REG13" },
2676 { 4*(REG_REG0+14), "4*REG_REG14" },
2677 { 4*REG_REG15, "4*REG_REG15" },
2678 { 4*REG_PC, "4*REG_PC" },
2679 { 4*REG_PR, "4*REG_PR" },
2680 { 4*REG_SR, "4*REG_SR" },
2681 { 4*REG_GBR, "4*REG_GBR" },
2682 { 4*REG_MACH, "4*REG_MACH" },
2683 { 4*REG_MACL, "4*REG_MACL" },
2684 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2685 { 4*REG_FPUL, "4*REG_FPUL" },
2686 { 4*REG_FPREG0, "4*REG_FPREG0" },
2687 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2688 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2689 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2690 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2691 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2692 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2693 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2694 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2695 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2696 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2697 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2698 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2699 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2700 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2701 { 4*REG_FPREG15, "4*REG_FPREG15" },
2702 #ifdef REG_XDREG0
2703 { 4*REG_XDREG0, "4*REG_XDREG0" },
2704 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2705 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2706 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2707 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2708 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2709 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2710 { 4*REG_XDREG14, "4*REG_XDREG14" },
2711 #endif
2712 { 4*REG_FPSCR, "4*REG_FPSCR" },
2713 #endif /* SH */
2714 #ifdef SH64
2715 { 0, "PC(L)" },
2716 { 4, "PC(U)" },
2717 { 8, "SR(L)" },
2718 { 12, "SR(U)" },
2719 { 16, "syscall no.(L)" },
2720 { 20, "syscall_no.(U)" },
2721 { 24, "R0(L)" },
2722 { 28, "R0(U)" },
2723 { 32, "R1(L)" },
2724 { 36, "R1(U)" },
2725 { 40, "R2(L)" },
2726 { 44, "R2(U)" },
2727 { 48, "R3(L)" },
2728 { 52, "R3(U)" },
2729 { 56, "R4(L)" },
2730 { 60, "R4(U)" },
2731 { 64, "R5(L)" },
2732 { 68, "R5(U)" },
2733 { 72, "R6(L)" },
2734 { 76, "R6(U)" },
2735 { 80, "R7(L)" },
2736 { 84, "R7(U)" },
2737 { 88, "R8(L)" },
2738 { 92, "R8(U)" },
2739 { 96, "R9(L)" },
2740 { 100, "R9(U)" },
2741 { 104, "R10(L)" },
2742 { 108, "R10(U)" },
2743 { 112, "R11(L)" },
2744 { 116, "R11(U)" },
2745 { 120, "R12(L)" },
2746 { 124, "R12(U)" },
2747 { 128, "R13(L)" },
2748 { 132, "R13(U)" },
2749 { 136, "R14(L)" },
2750 { 140, "R14(U)" },
2751 { 144, "R15(L)" },
2752 { 148, "R15(U)" },
2753 { 152, "R16(L)" },
2754 { 156, "R16(U)" },
2755 { 160, "R17(L)" },
2756 { 164, "R17(U)" },
2757 { 168, "R18(L)" },
2758 { 172, "R18(U)" },
2759 { 176, "R19(L)" },
2760 { 180, "R19(U)" },
2761 { 184, "R20(L)" },
2762 { 188, "R20(U)" },
2763 { 192, "R21(L)" },
2764 { 196, "R21(U)" },
2765 { 200, "R22(L)" },
2766 { 204, "R22(U)" },
2767 { 208, "R23(L)" },
2768 { 212, "R23(U)" },
2769 { 216, "R24(L)" },
2770 { 220, "R24(U)" },
2771 { 224, "R25(L)" },
2772 { 228, "R25(U)" },
2773 { 232, "R26(L)" },
2774 { 236, "R26(U)" },
2775 { 240, "R27(L)" },
2776 { 244, "R27(U)" },
2777 { 248, "R28(L)" },
2778 { 252, "R28(U)" },
2779 { 256, "R29(L)" },
2780 { 260, "R29(U)" },
2781 { 264, "R30(L)" },
2782 { 268, "R30(U)" },
2783 { 272, "R31(L)" },
2784 { 276, "R31(U)" },
2785 { 280, "R32(L)" },
2786 { 284, "R32(U)" },
2787 { 288, "R33(L)" },
2788 { 292, "R33(U)" },
2789 { 296, "R34(L)" },
2790 { 300, "R34(U)" },
2791 { 304, "R35(L)" },
2792 { 308, "R35(U)" },
2793 { 312, "R36(L)" },
2794 { 316, "R36(U)" },
2795 { 320, "R37(L)" },
2796 { 324, "R37(U)" },
2797 { 328, "R38(L)" },
2798 { 332, "R38(U)" },
2799 { 336, "R39(L)" },
2800 { 340, "R39(U)" },
2801 { 344, "R40(L)" },
2802 { 348, "R40(U)" },
2803 { 352, "R41(L)" },
2804 { 356, "R41(U)" },
2805 { 360, "R42(L)" },
2806 { 364, "R42(U)" },
2807 { 368, "R43(L)" },
2808 { 372, "R43(U)" },
2809 { 376, "R44(L)" },
2810 { 380, "R44(U)" },
2811 { 384, "R45(L)" },
2812 { 388, "R45(U)" },
2813 { 392, "R46(L)" },
2814 { 396, "R46(U)" },
2815 { 400, "R47(L)" },
2816 { 404, "R47(U)" },
2817 { 408, "R48(L)" },
2818 { 412, "R48(U)" },
2819 { 416, "R49(L)" },
2820 { 420, "R49(U)" },
2821 { 424, "R50(L)" },
2822 { 428, "R50(U)" },
2823 { 432, "R51(L)" },
2824 { 436, "R51(U)" },
2825 { 440, "R52(L)" },
2826 { 444, "R52(U)" },
2827 { 448, "R53(L)" },
2828 { 452, "R53(U)" },
2829 { 456, "R54(L)" },
2830 { 460, "R54(U)" },
2831 { 464, "R55(L)" },
2832 { 468, "R55(U)" },
2833 { 472, "R56(L)" },
2834 { 476, "R56(U)" },
2835 { 480, "R57(L)" },
2836 { 484, "R57(U)" },
2837 { 488, "R58(L)" },
2838 { 492, "R58(U)" },
2839 { 496, "R59(L)" },
2840 { 500, "R59(U)" },
2841 { 504, "R60(L)" },
2842 { 508, "R60(U)" },
2843 { 512, "R61(L)" },
2844 { 516, "R61(U)" },
2845 { 520, "R62(L)" },
2846 { 524, "R62(U)" },
2847 { 528, "TR0(L)" },
2848 { 532, "TR0(U)" },
2849 { 536, "TR1(L)" },
2850 { 540, "TR1(U)" },
2851 { 544, "TR2(L)" },
2852 { 548, "TR2(U)" },
2853 { 552, "TR3(L)" },
2854 { 556, "TR3(U)" },
2855 { 560, "TR4(L)" },
2856 { 564, "TR4(U)" },
2857 { 568, "TR5(L)" },
2858 { 572, "TR5(U)" },
2859 { 576, "TR6(L)" },
2860 { 580, "TR6(U)" },
2861 { 584, "TR7(L)" },
2862 { 588, "TR7(U)" },
2863 /* This entry is in case pt_regs contains dregs (depends on
2864 the kernel build options). */
2865 { uoff(regs), "offsetof(struct user, regs)" },
2866 { uoff(fpu), "offsetof(struct user, fpu)" },
2867 #endif
2868 #ifdef ARM
2869 { uoff(regs.ARM_r0), "r0" },
2870 { uoff(regs.ARM_r1), "r1" },
2871 { uoff(regs.ARM_r2), "r2" },
2872 { uoff(regs.ARM_r3), "r3" },
2873 { uoff(regs.ARM_r4), "r4" },
2874 { uoff(regs.ARM_r5), "r5" },
2875 { uoff(regs.ARM_r6), "r6" },
2876 { uoff(regs.ARM_r7), "r7" },
2877 { uoff(regs.ARM_r8), "r8" },
2878 { uoff(regs.ARM_r9), "r9" },
2879 { uoff(regs.ARM_r10), "r10" },
2880 { uoff(regs.ARM_fp), "fp" },
2881 { uoff(regs.ARM_ip), "ip" },
2882 { uoff(regs.ARM_sp), "sp" },
2883 { uoff(regs.ARM_lr), "lr" },
2884 { uoff(regs.ARM_pc), "pc" },
2885 { uoff(regs.ARM_cpsr), "cpsr" },
2886 #endif
2887
2888 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64)
2889 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
2890 #endif
2891 #if defined(I386) || defined(X86_64)
2892 { uoff(i387), "offsetof(struct user, i387)" },
2893 #else /* !I386 */
2894 #ifdef M68K
2895 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2896 #endif /* M68K */
2897 #endif /* !I386 */
2898 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2899 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2900 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2901 #if !defined(SPARC64)
2902 { uoff(start_code), "offsetof(struct user, start_code)" },
2903 #endif
2904 #ifdef SH64
2905 { uoff(start_data), "offsetof(struct user, start_data)" },
2906 #endif
2907 #if !defined(SPARC64)
2908 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2909 #endif
2910 { uoff(signal), "offsetof(struct user, signal)" },
2911 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
2912 { uoff(reserved), "offsetof(struct user, reserved)" },
2913 #endif
2914 #if !defined(SPARC64)
2915 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2916 #endif
2917 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64)
2918 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2919 #endif
2920 { uoff(magic), "offsetof(struct user, magic)" },
2921 { uoff(u_comm), "offsetof(struct user, u_comm)" },
2922 #if defined(I386) || defined(X86_64)
2923 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2924 #endif /* I386 */
2925 #endif /* !IA64 */
2926 #endif /* !ALPHA */
2927 #endif /* !POWERPC/!SPARC */
2928 #endif /* LINUX */
2929 #ifdef SUNOS4
2930 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2931 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2932 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2933 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2934 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2935 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2936 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2937 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2938 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2939 { uoff(u_error), "offsetof(struct user, u_error)" },
2940 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2941 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2942 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2943 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2944 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2945 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2946 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2947 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2948 { uoff(u_code), "offsetof(struct user, u_code)" },
2949 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2950 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2951 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2952 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2953 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2954 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2955 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2956 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2957 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2958 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2959 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2960 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2961 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2962 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2963 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2964 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2965 { uoff(u_start), "offsetof(struct user, u_start)" },
2966 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2967 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2968 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2969 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2970 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2971 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2972 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2973 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2974 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2975 #endif /* SUNOS4 */
2976 #ifndef HPPA
2977 { sizeof(struct user), "sizeof(struct user)" },
2978 #endif
2979 { 0, NULL },
2980 };
2981 #endif
2982
2983 int
sys_ptrace(tcp)2984 sys_ptrace(tcp)
2985 struct tcb *tcp;
2986 {
2987 const struct xlat *x;
2988 long addr;
2989
2990 if (entering(tcp)) {
2991 printxval(ptrace_cmds, tcp->u_arg[0],
2992 #ifndef FREEBSD
2993 "PTRACE_???"
2994 #else
2995 "PT_???"
2996 #endif
2997 );
2998 tprintf(", %lu, ", tcp->u_arg[1]);
2999 addr = tcp->u_arg[2];
3000 #ifndef FREEBSD
3001 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3002 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3003 for (x = struct_user_offsets; x->str; x++) {
3004 if (x->val >= addr)
3005 break;
3006 }
3007 if (!x->str)
3008 tprintf("%#lx, ", addr);
3009 else if (x->val > addr && x != struct_user_offsets) {
3010 x--;
3011 tprintf("%s + %ld, ", x->str, addr - x->val);
3012 }
3013 else
3014 tprintf("%s, ", x->str);
3015 }
3016 else
3017 #endif
3018 tprintf("%#lx, ", tcp->u_arg[2]);
3019 #ifdef LINUX
3020 switch (tcp->u_arg[0]) {
3021 case PTRACE_PEEKDATA:
3022 case PTRACE_PEEKTEXT:
3023 case PTRACE_PEEKUSER:
3024 break;
3025 case PTRACE_CONT:
3026 case PTRACE_SINGLESTEP:
3027 case PTRACE_SYSCALL:
3028 case PTRACE_DETACH:
3029 printsignal(tcp->u_arg[3]);
3030 break;
3031 default:
3032 tprintf("%#lx", tcp->u_arg[3]);
3033 break;
3034 }
3035 } else {
3036 switch (tcp->u_arg[0]) {
3037 case PTRACE_PEEKDATA:
3038 case PTRACE_PEEKTEXT:
3039 case PTRACE_PEEKUSER:
3040 printnum(tcp, tcp->u_arg[3], "%#lx");
3041 break;
3042 }
3043 }
3044 #endif /* LINUX */
3045 #ifdef SUNOS4
3046 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3047 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3048 tprintf("%lu, ", tcp->u_arg[3]);
3049 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3050 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3051 tcp->u_arg[0] != PTRACE_READTEXT) {
3052 tprintf("%#lx", tcp->u_arg[3]);
3053 }
3054 } else {
3055 if (tcp->u_arg[0] == PTRACE_READDATA ||
3056 tcp->u_arg[0] == PTRACE_READTEXT) {
3057 tprintf("%lu, ", tcp->u_arg[3]);
3058 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3059 }
3060 }
3061 #endif /* SUNOS4 */
3062 #ifdef FREEBSD
3063 tprintf("%lu", tcp->u_arg[3]);
3064 }
3065 #endif /* FREEBSD */
3066 return 0;
3067 }
3068
3069 #endif /* !SVR4 */
3070
3071 #ifdef LINUX
3072 static const struct xlat futexops[] = {
3073 { FUTEX_WAIT, "FUTEX_WAIT" },
3074 { FUTEX_WAKE, "FUTEX_WAKE" },
3075 { FUTEX_FD, "FUTEX_FD" },
3076 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
3077 { 0, NULL }
3078 };
3079
3080 int
3081 sys_futex(tcp)
3082 struct tcb *tcp;
3083 {
3084 if (entering(tcp)) {
3085 tprintf("%p, ", (void *) tcp->u_arg[0]);
3086 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3087 tprintf(", %ld", tcp->u_arg[2]);
3088 if (tcp->u_arg[1] == FUTEX_WAIT) {
3089 tprintf(", ");
3090 printtv(tcp, tcp->u_arg[3]);
3091 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
3092 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3093 }
3094 return 0;
3095 }
3096
3097 static void
3098 print_affinitylist(tcp, list, len)
3099 struct tcb *tcp;
3100 long list;
3101 unsigned int len;
3102 {
3103 int first = 1;
3104 tprintf(" {");
3105 while (len >= sizeof (unsigned long)) {
3106 unsigned long w;
3107 umove(tcp, list, &w);
3108 tprintf("%s %lx", first ? "" : ",", w);
3109 first = 0;
3110 len -= sizeof (unsigned long);
3111 list += sizeof(unsigned long);
3112 }
3113 tprintf(" }");
3114 }
3115
3116 int
3117 sys_sched_setaffinity(tcp)
3118 struct tcb *tcp;
3119 {
3120 if (entering(tcp)) {
3121 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3122 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3123 }
3124 return 0;
3125 }
3126
3127 int
3128 sys_sched_getaffinity(tcp)
3129 struct tcb *tcp;
3130 {
3131 if (entering(tcp)) {
3132 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3133 } else {
3134 if (tcp->u_rval == -1)
3135 tprintf("%#lx", tcp->u_arg[2]);
3136 else
3137 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3138 }
3139 return 0;
3140 }
3141
3142 static const struct xlat schedulers[] = {
3143 { SCHED_OTHER, "SCHED_OTHER" },
3144 { SCHED_RR, "SCHED_RR" },
3145 { SCHED_FIFO, "SCHED_FIFO" },
3146 { 0, NULL }
3147 };
3148
3149 int
3150 sys_sched_getscheduler(tcp)
3151 struct tcb *tcp;
3152 {
3153 if (entering(tcp)) {
3154 tprintf("%d", (int) tcp->u_arg[0]);
3155 } else if (! syserror(tcp)) {
3156 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3157 if (tcp->auxstr != NULL)
3158 return RVAL_STR;
3159 }
3160 return 0;
3161 }
3162
3163 int
3164 sys_sched_setscheduler(tcp)
3165 struct tcb *tcp;
3166 {
3167 if (entering(tcp)) {
3168 struct sched_param p;
3169 tprintf("%d, ", (int) tcp->u_arg[0]);
3170 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3171 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3172 tprintf(", %#lx", tcp->u_arg[2]);
3173 else
3174 tprintf(", { %d }", p.__sched_priority);
3175 }
3176 return 0;
3177 }
3178
3179 int
3180 sys_sched_getparam(tcp)
3181 struct tcb *tcp;
3182 {
3183 if (entering(tcp)) {
3184 tprintf("%d, ", (int) tcp->u_arg[0]);
3185 } else {
3186 struct sched_param p;
3187 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3188 tprintf("%#lx", tcp->u_arg[1]);
3189 else
3190 tprintf("{ %d }", p.__sched_priority);
3191 }
3192 return 0;
3193 }
3194
3195 int
3196 sys_sched_setparam(tcp)
3197 struct tcb *tcp;
3198 {
3199 if (entering(tcp)) {
3200 struct sched_param p;
3201 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3202 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3203 else
3204 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3205 }
3206 return 0;
3207 }
3208
3209 int
3210 sys_sched_get_priority_min(tcp)
3211 struct tcb *tcp;
3212 {
3213 if (entering(tcp)) {
3214 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3215 }
3216 return 0;
3217 }
3218
3219 #ifdef X86_64
3220 #include <asm/prctl.h>
3221
3222 static const struct xlat archvals[] = {
3223 { ARCH_SET_GS, "ARCH_SET_GS" },
3224 { ARCH_SET_FS, "ARCH_SET_FS" },
3225 { ARCH_GET_FS, "ARCH_GET_FS" },
3226 { ARCH_GET_GS, "ARCH_GET_GS" },
3227 { 0, NULL },
3228 };
3229
3230 int
3231 sys_arch_prctl(tcp)
3232 struct tcb *tcp;
3233 {
3234 if (entering(tcp)) {
3235 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3236 if (tcp->u_arg[0] == ARCH_SET_GS
3237 || tcp->u_arg[0] == ARCH_SET_FS)
3238 tprintf(", %#lx", tcp->u_arg[1]);
3239 } else {
3240 if (tcp->u_arg[0] == ARCH_GET_GS
3241 || tcp->u_arg[0] == ARCH_GET_FS) {
3242 long int v;
3243 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3244 tprintf(", [%#lx]", v);
3245 else
3246 tprintf(", %#lx", tcp->u_arg[1]);
3247 }
3248 }
3249 return 0;
3250 }
3251 #endif
3252
3253 #endif
3254