syscall.c revision 2ce12ed31c2b46260b8fd140bfe8d6c30bc0eb29
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 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $Id$ 34 */ 35 36#include "defs.h" 37 38#include <signal.h> 39#include <time.h> 40#include <errno.h> 41#include <sys/user.h> 42#include <sys/syscall.h> 43#include <sys/param.h> 44 45#ifdef HAVE_SYS_REG_H 46#include <sys/reg.h> 47#ifndef PTRACE_PEEKUSR 48# define PTRACE_PEEKUSR PTRACE_PEEKUSER 49#endif 50#elif defined(HAVE_LINUX_PTRACE_H) 51#undef PTRACE_SYSCALL 52# ifdef HAVE_STRUCT_IA64_FPREG 53# define ia64_fpreg XXX_ia64_fpreg 54# endif 55# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 56# define pt_all_user_regs XXX_pt_all_user_regs 57# endif 58#include <linux/ptrace.h> 59# undef ia64_fpreg 60# undef pt_all_user_regs 61#endif 62 63#if defined (LINUX) && defined (SPARC64) 64# undef PTRACE_GETREGS 65# define PTRACE_GETREGS PTRACE_GETREGS64 66# undef PTRACE_SETREGS 67# define PTRACE_SETREGS PTRACE_SETREGS64 68#endif /* LINUX && SPARC64 */ 69 70#if defined(LINUX) && defined(IA64) 71# include <asm/ptrace_offsets.h> 72# include <asm/rse.h> 73#endif 74 75#define NR_SYSCALL_BASE 0 76#ifdef LINUX 77#ifndef ERESTARTSYS 78#define ERESTARTSYS 512 79#endif 80#ifndef ERESTARTNOINTR 81#define ERESTARTNOINTR 513 82#endif 83#ifndef ERESTARTNOHAND 84#define ERESTARTNOHAND 514 /* restart if no handler.. */ 85#endif 86#ifndef ENOIOCTLCMD 87#define ENOIOCTLCMD 515 /* No ioctl command */ 88#endif 89#ifndef ERESTART_RESTARTBLOCK 90#define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */ 91#endif 92#ifndef NSIG 93#warning: NSIG is not defined, using 32 94#define NSIG 32 95#endif 96#ifdef ARM 97/* Ugh. Is this really correct? ARM has no RT signals?! */ 98#undef NSIG 99#define NSIG 32 100#undef NR_SYSCALL_BASE 101#define NR_SYSCALL_BASE __NR_SYSCALL_BASE 102#endif 103#endif /* LINUX */ 104 105#include "syscall.h" 106 107/* Define these shorthand notations to simplify the syscallent files. */ 108#define TD TRACE_DESC 109#define TF TRACE_FILE 110#define TI TRACE_IPC 111#define TN TRACE_NETWORK 112#define TP TRACE_PROCESS 113#define TS TRACE_SIGNAL 114#define NF SYSCALL_NEVER_FAILS 115#define MA MAX_ARGS 116 117static const struct sysent sysent0[] = { 118#include "syscallent.h" 119}; 120 121#if SUPPORTED_PERSONALITIES >= 2 122static const struct sysent sysent1[] = { 123#include "syscallent1.h" 124}; 125#endif 126 127#if SUPPORTED_PERSONALITIES >= 3 128static const struct sysent sysent2[] = { 129#include "syscallent2.h" 130}; 131#endif 132 133/* Now undef them since short defines cause wicked namespace pollution. */ 134#undef TD 135#undef TF 136#undef TI 137#undef TN 138#undef TP 139#undef TS 140#undef NF 141#undef MA 142 143 144/* 145 * `ioctlent.h' may be generated from `ioctlent.raw' by the auxiliary 146 * program `ioctlsort', such that the list is sorted by the `code' field. 147 * This has the side-effect of resolving the _IO.. macros into 148 * plain integers, eliminating the need to include here everything 149 * in "/usr/include". 150 */ 151 152 153static const char *const errnoent0[] = { 154#include "errnoent.h" 155}; 156static const char *const signalent0[] = { 157#include "signalent.h" 158}; 159static const struct ioctlent ioctlent0[] = { 160#include "ioctlent.h" 161}; 162enum { nsyscalls0 = ARRAY_SIZE(sysent0) }; 163enum { nerrnos0 = ARRAY_SIZE(errnoent0) }; 164enum { nsignals0 = ARRAY_SIZE(signalent0) }; 165enum { nioctlents0 = ARRAY_SIZE(ioctlent0) }; 166int qual_flags0[MAX_QUALS]; 167 168#if SUPPORTED_PERSONALITIES >= 2 169static const char *const errnoent1[] = { 170#include "errnoent1.h" 171}; 172static const char *const signalent1[] = { 173#include "signalent1.h" 174}; 175static const struct ioctlent ioctlent1[] = { 176#include "ioctlent1.h" 177}; 178enum { nsyscalls1 = ARRAY_SIZE(sysent1) }; 179enum { nerrnos1 = ARRAY_SIZE(errnoent1) }; 180enum { nsignals1 = ARRAY_SIZE(signalent1) }; 181enum { nioctlents1 = ARRAY_SIZE(ioctlent1) }; 182int qual_flags1[MAX_QUALS]; 183#endif 184 185#if SUPPORTED_PERSONALITIES >= 3 186static const char *const errnoent2[] = { 187#include "errnoent2.h" 188}; 189static const char *const signalent2[] = { 190#include "signalent2.h" 191}; 192static const struct ioctlent ioctlent2[] = { 193#include "ioctlent2.h" 194}; 195enum { nsyscalls2 = ARRAY_SIZE(sysent2) }; 196enum { nerrnos2 = ARRAY_SIZE(errnoent2) }; 197enum { nsignals2 = ARRAY_SIZE(signalent2) }; 198enum { nioctlents2 = ARRAY_SIZE(ioctlent2) }; 199int qual_flags2[MAX_QUALS]; 200#endif 201 202 203const struct sysent *sysent; 204const char *const *errnoent; 205const char *const *signalent; 206const struct ioctlent *ioctlent; 207unsigned nsyscalls; 208unsigned nerrnos; 209unsigned nsignals; 210unsigned nioctlents; 211int *qual_flags; 212 213int current_personality; 214 215#ifndef PERSONALITY0_WORDSIZE 216# define PERSONALITY0_WORDSIZE sizeof(long) 217#endif 218const int personality_wordsize[SUPPORTED_PERSONALITIES] = { 219 PERSONALITY0_WORDSIZE, 220#if SUPPORTED_PERSONALITIES > 1 221 PERSONALITY1_WORDSIZE, 222#endif 223#if SUPPORTED_PERSONALITIES > 2 224 PERSONALITY2_WORDSIZE, 225#endif 226}; 227 228void 229set_personality(int personality) 230{ 231 switch (personality) { 232 case 0: 233 errnoent = errnoent0; 234 nerrnos = nerrnos0; 235 sysent = sysent0; 236 nsyscalls = nsyscalls0; 237 ioctlent = ioctlent0; 238 nioctlents = nioctlents0; 239 signalent = signalent0; 240 nsignals = nsignals0; 241 qual_flags = qual_flags0; 242 break; 243 244#if SUPPORTED_PERSONALITIES >= 2 245 case 1: 246 errnoent = errnoent1; 247 nerrnos = nerrnos1; 248 sysent = sysent1; 249 nsyscalls = nsyscalls1; 250 ioctlent = ioctlent1; 251 nioctlents = nioctlents1; 252 signalent = signalent1; 253 nsignals = nsignals1; 254 qual_flags = qual_flags1; 255 break; 256#endif 257 258#if SUPPORTED_PERSONALITIES >= 3 259 case 2: 260 errnoent = errnoent2; 261 nerrnos = nerrnos2; 262 sysent = sysent2; 263 nsyscalls = nsyscalls2; 264 ioctlent = ioctlent2; 265 nioctlents = nioctlents2; 266 signalent = signalent2; 267 nsignals = nsignals2; 268 qual_flags = qual_flags2; 269 break; 270#endif 271 } 272 273 current_personality = personality; 274} 275 276 277static int qual_syscall(), qual_signal(), qual_fault(), qual_desc(); 278 279static const struct qual_options { 280 int bitflag; 281 const char *option_name; 282 int (*qualify)(const char *, int, int); 283 const char *argument_name; 284} qual_options[] = { 285 { QUAL_TRACE, "trace", qual_syscall, "system call" }, 286 { QUAL_TRACE, "t", qual_syscall, "system call" }, 287 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" }, 288 { QUAL_ABBREV, "a", qual_syscall, "system call" }, 289 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" }, 290 { QUAL_VERBOSE, "v", qual_syscall, "system call" }, 291 { QUAL_RAW, "raw", qual_syscall, "system call" }, 292 { QUAL_RAW, "x", qual_syscall, "system call" }, 293 { QUAL_SIGNAL, "signal", qual_signal, "signal" }, 294 { QUAL_SIGNAL, "signals", qual_signal, "signal" }, 295 { QUAL_SIGNAL, "s", qual_signal, "signal" }, 296 { QUAL_FAULT, "fault", qual_fault, "fault" }, 297 { QUAL_FAULT, "faults", qual_fault, "fault" }, 298 { QUAL_FAULT, "m", qual_fault, "fault" }, 299 { QUAL_READ, "read", qual_desc, "descriptor" }, 300 { QUAL_READ, "reads", qual_desc, "descriptor" }, 301 { QUAL_READ, "r", qual_desc, "descriptor" }, 302 { QUAL_WRITE, "write", qual_desc, "descriptor" }, 303 { QUAL_WRITE, "writes", qual_desc, "descriptor" }, 304 { QUAL_WRITE, "w", qual_desc, "descriptor" }, 305 { 0, NULL, NULL, NULL }, 306}; 307 308static void 309qualify_one(int n, int bitflag, int not, int pers) 310{ 311 if (pers == 0 || pers < 0) { 312 if (not) 313 qual_flags0[n] &= ~bitflag; 314 else 315 qual_flags0[n] |= bitflag; 316 } 317 318#if SUPPORTED_PERSONALITIES >= 2 319 if (pers == 1 || pers < 0) { 320 if (not) 321 qual_flags1[n] &= ~bitflag; 322 else 323 qual_flags1[n] |= bitflag; 324 } 325#endif /* SUPPORTED_PERSONALITIES >= 2 */ 326 327#if SUPPORTED_PERSONALITIES >= 3 328 if (pers == 2 || pers < 0) { 329 if (not) 330 qual_flags2[n] &= ~bitflag; 331 else 332 qual_flags2[n] |= bitflag; 333 } 334#endif /* SUPPORTED_PERSONALITIES >= 3 */ 335} 336 337static int 338qual_syscall(const char *s, int bitflag, int not) 339{ 340 int i; 341 int rc = -1; 342 343 if (isdigit((unsigned char)*s)) { 344 int i = atoi(s); 345 if (i < 0 || i >= MAX_QUALS) 346 return -1; 347 qualify_one(i, bitflag, not, -1); 348 return 0; 349 } 350 for (i = 0; i < nsyscalls0; i++) 351 if (strcmp(s, sysent0[i].sys_name) == 0) { 352 qualify_one(i, bitflag, not, 0); 353 rc = 0; 354 } 355 356#if SUPPORTED_PERSONALITIES >= 2 357 for (i = 0; i < nsyscalls1; i++) 358 if (strcmp(s, sysent1[i].sys_name) == 0) { 359 qualify_one(i, bitflag, not, 1); 360 rc = 0; 361 } 362#endif /* SUPPORTED_PERSONALITIES >= 2 */ 363 364#if SUPPORTED_PERSONALITIES >= 3 365 for (i = 0; i < nsyscalls2; i++) 366 if (strcmp(s, sysent2[i].sys_name) == 0) { 367 qualify_one(i, bitflag, not, 2); 368 rc = 0; 369 } 370#endif /* SUPPORTED_PERSONALITIES >= 3 */ 371 372 return rc; 373} 374 375static int 376qual_signal(const char *s, int bitflag, int not) 377{ 378 int i; 379 char buf[32]; 380 381 if (isdigit((unsigned char)*s)) { 382 int signo = atoi(s); 383 if (signo < 0 || signo >= MAX_QUALS) 384 return -1; 385 qualify_one(signo, bitflag, not, -1); 386 return 0; 387 } 388 if (strlen(s) >= sizeof buf) 389 return -1; 390 strcpy(buf, s); 391 s = buf; 392 if (strncasecmp(s, "SIG", 3) == 0) 393 s += 3; 394 for (i = 0; i <= NSIG; i++) 395 if (strcasecmp(s, signame(i) + 3) == 0) { 396 qualify_one(i, bitflag, not, -1); 397 return 0; 398 } 399 return -1; 400} 401 402static int 403qual_fault(const char *s, int bitflag, int not) 404{ 405 return -1; 406} 407 408static int 409qual_desc(const char *s, int bitflag, int not) 410{ 411 if (isdigit((unsigned char)*s)) { 412 int desc = atoi(s); 413 if (desc < 0 || desc >= MAX_QUALS) 414 return -1; 415 qualify_one(desc, bitflag, not, -1); 416 return 0; 417 } 418 return -1; 419} 420 421static int 422lookup_class(const char *s) 423{ 424 if (strcmp(s, "file") == 0) 425 return TRACE_FILE; 426 if (strcmp(s, "ipc") == 0) 427 return TRACE_IPC; 428 if (strcmp(s, "network") == 0) 429 return TRACE_NETWORK; 430 if (strcmp(s, "process") == 0) 431 return TRACE_PROCESS; 432 if (strcmp(s, "signal") == 0) 433 return TRACE_SIGNAL; 434 if (strcmp(s, "desc") == 0) 435 return TRACE_DESC; 436 return -1; 437} 438 439void 440qualify(const char *s) 441{ 442 const struct qual_options *opt; 443 int not; 444 char *copy; 445 const char *p; 446 int i, n; 447 448 opt = &qual_options[0]; 449 for (i = 0; (p = qual_options[i].option_name); i++) { 450 n = strlen(p); 451 if (strncmp(s, p, n) == 0 && s[n] == '=') { 452 opt = &qual_options[i]; 453 s += n + 1; 454 break; 455 } 456 } 457 not = 0; 458 if (*s == '!') { 459 not = 1; 460 s++; 461 } 462 if (strcmp(s, "none") == 0) { 463 not = 1 - not; 464 s = "all"; 465 } 466 if (strcmp(s, "all") == 0) { 467 for (i = 0; i < MAX_QUALS; i++) { 468 qualify_one(i, opt->bitflag, not, -1); 469 } 470 return; 471 } 472 for (i = 0; i < MAX_QUALS; i++) { 473 qualify_one(i, opt->bitflag, !not, -1); 474 } 475 copy = strdup(s); 476 if (!copy) { 477 fprintf(stderr, "out of memory\n"); 478 exit(1); 479 } 480 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) { 481 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) { 482 for (i = 0; i < nsyscalls0; i++) 483 if (sysent0[i].sys_flags & n) 484 qualify_one(i, opt->bitflag, not, 0); 485 486#if SUPPORTED_PERSONALITIES >= 2 487 for (i = 0; i < nsyscalls1; i++) 488 if (sysent1[i].sys_flags & n) 489 qualify_one(i, opt->bitflag, not, 1); 490#endif /* SUPPORTED_PERSONALITIES >= 2 */ 491 492#if SUPPORTED_PERSONALITIES >= 3 493 for (i = 0; i < nsyscalls2; i++) 494 if (sysent2[i].sys_flags & n) 495 qualify_one(i, opt->bitflag, not, 2); 496#endif /* SUPPORTED_PERSONALITIES >= 3 */ 497 498 continue; 499 } 500 if (opt->qualify(p, opt->bitflag, not)) { 501 fprintf(stderr, "strace: invalid %s `%s'\n", 502 opt->argument_name, p); 503 exit(1); 504 } 505 } 506 free(copy); 507 return; 508} 509 510static void 511dumpio(struct tcb *tcp) 512{ 513 if (syserror(tcp)) 514 return; 515 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS) 516 return; 517 if (tcp->scno < 0 || tcp->scno >= nsyscalls) 518 return; 519 if (sysent[tcp->scno].sys_func == printargs) 520 return; 521 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) { 522 if (sysent[tcp->scno].sys_func == sys_read || 523 sysent[tcp->scno].sys_func == sys_pread || 524 sysent[tcp->scno].sys_func == sys_pread64 || 525 sysent[tcp->scno].sys_func == sys_recv || 526 sysent[tcp->scno].sys_func == sys_recvfrom) 527 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval); 528 else if (sysent[tcp->scno].sys_func == sys_readv) 529 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 530 return; 531 } 532 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) { 533 if (sysent[tcp->scno].sys_func == sys_write || 534 sysent[tcp->scno].sys_func == sys_pwrite || 535 sysent[tcp->scno].sys_func == sys_pwrite64 || 536 sysent[tcp->scno].sys_func == sys_send || 537 sysent[tcp->scno].sys_func == sys_sendto) 538 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 539 else if (sysent[tcp->scno].sys_func == sys_writev) 540 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 541 return; 542 } 543} 544 545#ifndef FREEBSD 546enum subcall_style { shift_style, deref_style, mask_style, door_style }; 547#else /* FREEBSD */ 548enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style }; 549 550struct subcall { 551 int call; 552 int nsubcalls; 553 int subcalls[5]; 554}; 555 556static const struct subcall subcalls_table[] = { 557 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } }, 558#ifdef SYS_semconfig 559 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } }, 560#else 561 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } }, 562#endif 563 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } }, 564}; 565#endif /* FREEBSD */ 566 567#if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) )) 568 569static void 570decode_subcall(struct tcb *tcp, int subcall, int nsubcalls, enum subcall_style style) 571{ 572 unsigned long addr, mask; 573 int i, n; 574 int size = personality_wordsize[current_personality]; 575 576 switch (style) { 577 case shift_style: 578 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls) 579 return; 580 tcp->scno = subcall + tcp->u_arg[0]; 581 tcp->u_nargs = n = sysent[tcp->scno].nargs; 582 for (i = 0; i < n; i++) 583 tcp->u_arg[i] = tcp->u_arg[i + 1]; 584 break; 585 case deref_style: 586 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls) 587 return; 588 tcp->scno = subcall + tcp->u_arg[0]; 589 addr = tcp->u_arg[1]; 590 tcp->u_nargs = n = sysent[tcp->scno].nargs; 591 for (i = 0; i < n; i++) { 592 if (size == sizeof(int)) { 593 unsigned int arg; 594 if (umove(tcp, addr, &arg) < 0) 595 arg = 0; 596 tcp->u_arg[i] = arg; 597 } 598 else if (size == sizeof(long)) { 599 unsigned long arg; 600 if (umove(tcp, addr, &arg) < 0) 601 arg = 0; 602 tcp->u_arg[i] = arg; 603 } 604 else 605 abort(); 606 addr += size; 607 } 608 break; 609 case mask_style: 610 mask = (tcp->u_arg[0] >> 8) & 0xff; 611 for (i = 0; mask; i++) 612 mask >>= 1; 613 if (i >= nsubcalls) 614 return; 615 tcp->u_arg[0] &= 0xff; 616 tcp->scno = subcall + i; 617 tcp->u_nargs = sysent[tcp->scno].nargs; 618 break; 619 case door_style: 620 /* 621 * Oh, yuck. The call code is the *sixth* argument. 622 * (don't you mean the *last* argument? - JH) 623 */ 624 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls) 625 return; 626 tcp->scno = subcall + tcp->u_arg[5]; 627 tcp->u_nargs = sysent[tcp->scno].nargs; 628 break; 629#ifdef FREEBSD 630 case table_style: 631 for (i = 0; i < ARRAY_SIZE(subcalls_table); i++) 632 if (subcalls_table[i].call == tcp->scno) break; 633 if (i < ARRAY_SIZE(subcalls_table) && 634 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) { 635 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]]; 636 for (i = 0; i < tcp->u_nargs; i++) 637 tcp->u_arg[i] = tcp->u_arg[i + 1]; 638 } 639 break; 640#endif /* FREEBSD */ 641 } 642} 643#endif 644 645struct tcb *tcp_last = NULL; 646 647static int 648internal_syscall(struct tcb *tcp) 649{ 650 /* 651 * We must always trace a few critical system calls in order to 652 * correctly support following forks in the presence of tracing 653 * qualifiers. 654 */ 655 int (*func)(); 656 657 if (tcp->scno < 0 || tcp->scno >= nsyscalls) 658 return 0; 659 660 func = sysent[tcp->scno].sys_func; 661 662 if ( sys_fork == func 663#if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4) 664 || sys_vfork == func 665#endif 666#ifdef LINUX 667 || sys_clone == func 668#endif 669#if UNIXWARE > 2 670 || sys_rfork == func 671#endif 672 ) 673 return internal_fork(tcp); 674 675#if defined SUNOS4 || (defined LINUX && defined TCB_WAITEXECVE) 676 if ( sys_execve == func 677# if defined(SPARC) || defined(SPARC64) || defined(SUNOS4) 678 || sys_execv == func 679# endif 680# if UNIXWARE > 2 681 || sys_rexecve == func 682# endif 683 ) 684 return internal_exec(tcp); 685#endif 686 687 return 0; 688} 689 690 691#ifdef LINUX 692# if defined (I386) 693static long eax; 694# elif defined (IA64) 695long r8, r10, psr; /* TODO: make static? */ 696long ia32 = 0; /* not static */ 697# elif defined (POWERPC) 698static long result, flags; 699# elif defined (M68K) 700static long d0; 701# elif defined(BFIN) 702static long r0; 703# elif defined (ARM) 704static struct pt_regs regs; 705# elif defined (ALPHA) 706static long r0; 707static long a3; 708# elif defined(AVR32) 709static struct pt_regs regs; 710# elif defined (SPARC) || defined (SPARC64) 711static struct pt_regs regs; 712static unsigned long trap; 713# elif defined(LINUX_MIPSN32) 714static long long a3; 715static long long r2; 716# elif defined(MIPS) 717static long a3; 718static long r2; 719# elif defined(S390) || defined(S390X) 720static long gpr2; 721static long pc; 722static long syscall_mode; 723# elif defined(HPPA) 724static long r28; 725# elif defined(SH) 726static long r0; 727# elif defined(SH64) 728static long r9; 729# elif defined(X86_64) 730static long rax; 731# elif defined(CRISV10) || defined(CRISV32) 732static long r10; 733# elif defined(MICROBLAZE) 734static long r3; 735# endif 736#endif /* LINUX */ 737#ifdef FREEBSD 738struct reg regs; /* TODO: make static? */ 739#endif /* FREEBSD */ 740 741/* Returns: 742 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 743 * 1: ok, continue in trace_syscall(). 744 * other: error, trace_syscall() should print error indicator 745 * ("????" etc) and bail out. 746 */ 747#ifndef USE_PROCFS 748static 749#endif 750int 751get_scno_on_sysenter(struct tcb *tcp) 752{ 753 long scno = 0; 754 755#ifdef LINUX 756# if defined(S390) || defined(S390X) 757 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0) 758 return -1; 759 760 if (syscall_mode != -ENOSYS) { 761 /* 762 * Since kernel version 2.5.44 the scno gets passed in gpr2. 763 */ 764 scno = syscall_mode; 765 } else { 766 /* 767 * Old style of "passing" the scno via the SVC instruction. 768 */ 769 long opcode, offset_reg, tmp; 770 void *svc_addr; 771 static const int gpr_offset[16] = { 772 PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3, 773 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7, 774 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11, 775 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15 776 }; 777 778 if (upeek(tcp, PT_PSWADDR, &pc) < 0) 779 return -1; 780 errno = 0; 781 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0); 782 if (errno) { 783 perror("peektext(pc-oneword)"); 784 return -1; 785 } 786 787 /* 788 * We have to check if the SVC got executed directly or via an 789 * EXECUTE instruction. In case of EXECUTE it is necessary to do 790 * instruction decoding to derive the system call number. 791 * Unfortunately the opcode sizes of EXECUTE and SVC are differently, 792 * so that this doesn't work if a SVC opcode is part of an EXECUTE 793 * opcode. Since there is no way to find out the opcode size this 794 * is the best we can do... 795 */ 796 if ((opcode & 0xff00) == 0x0a00) { 797 /* SVC opcode */ 798 scno = opcode & 0xff; 799 } 800 else { 801 /* SVC got executed by EXECUTE instruction */ 802 803 /* 804 * Do instruction decoding of EXECUTE. If you really want to 805 * understand this, read the Principles of Operations. 806 */ 807 svc_addr = (void *) (opcode & 0xfff); 808 809 tmp = 0; 810 offset_reg = (opcode & 0x000f0000) >> 16; 811 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 812 return -1; 813 svc_addr += tmp; 814 815 tmp = 0; 816 offset_reg = (opcode & 0x0000f000) >> 12; 817 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 818 return -1; 819 svc_addr += tmp; 820 821 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0); 822 if (errno) 823 return -1; 824# if defined(S390X) 825 scno >>= 48; 826# else 827 scno >>= 16; 828# endif 829 tmp = 0; 830 offset_reg = (opcode & 0x00f00000) >> 20; 831 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 832 return -1; 833 834 scno = (scno | tmp) & 0xff; 835 } 836 } 837# elif defined (POWERPC) 838 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0) 839 return -1; 840# ifdef POWERPC64 841 /* TODO: speed up strace by not doing this at every syscall. 842 * We only need to do it after execve. 843 */ 844 int currpers; 845 long val; 846 int pid = tcp->pid; 847 848 /* Check for 64/32 bit mode. */ 849 if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0) 850 return -1; 851 /* SF is bit 0 of MSR */ 852 if (val < 0) 853 currpers = 0; 854 else 855 currpers = 1; 856 if (currpers != current_personality) { 857 static const char *const names[] = {"64 bit", "32 bit"}; 858 set_personality(currpers); 859 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 860 pid, names[current_personality]); 861 } 862# endif 863# elif defined(AVR32) 864 /* Read complete register set in one go. */ 865 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0) 866 return -1; 867 scno = regs.r8; 868# elif defined(BFIN) 869 if (upeek(tcp, PT_ORIG_P0, &scno)) 870 return -1; 871# elif defined (I386) 872 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0) 873 return -1; 874# elif defined (X86_64) 875 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0) 876 return -1; 877 878 /* TODO: speed up strace by not doing this at every syscall. 879 * We only need to do it after execve. 880 */ 881 int currpers; 882 long val; 883 int pid = tcp->pid; 884 885 /* Check CS register value. On x86-64 linux it is: 886 * 0x33 for long mode (64 bit) 887 * 0x23 for compatibility mode (32 bit) 888 * It takes only one ptrace and thus doesn't need 889 * to be cached. 890 */ 891 if (upeek(tcp, 8*CS, &val) < 0) 892 return -1; 893 switch (val) { 894 case 0x23: currpers = 1; break; 895 case 0x33: currpers = 0; break; 896 default: 897 fprintf(stderr, "Unknown value CS=0x%02X while " 898 "detecting personality of process " 899 "PID=%d\n", (int)val, pid); 900 currpers = current_personality; 901 break; 902 } 903# if 0 904 /* This version analyzes the opcode of a syscall instruction. 905 * (int 0x80 on i386 vs. syscall on x86-64) 906 * It works, but is too complicated. 907 */ 908 unsigned long val, rip, i; 909 910 if (upeek(tcp, 8*RIP, &rip) < 0) 911 perror("upeek(RIP)"); 912 913 /* sizeof(syscall) == sizeof(int 0x80) == 2 */ 914 rip -= 2; 915 errno = 0; 916 917 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0); 918 if (errno) 919 fprintf(stderr, "ptrace_peektext failed: %s\n", 920 strerror(errno)); 921 switch (call & 0xffff) { 922 /* x86-64: syscall = 0x0f 0x05 */ 923 case 0x050f: currpers = 0; break; 924 /* i386: int 0x80 = 0xcd 0x80 */ 925 case 0x80cd: currpers = 1; break; 926 default: 927 currpers = current_personality; 928 fprintf(stderr, 929 "Unknown syscall opcode (0x%04X) while " 930 "detecting personality of process " 931 "PID=%d\n", (int)call, pid); 932 break; 933 } 934# endif 935 if (currpers != current_personality) { 936 static const char *const names[] = {"64 bit", "32 bit"}; 937 set_personality(currpers); 938 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 939 pid, names[current_personality]); 940 } 941# elif defined(IA64) 942# define IA64_PSR_IS ((long)1 << 34) 943 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) 944 ia32 = (psr & IA64_PSR_IS) != 0; 945 if (ia32) { 946 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */ 947 return -1; 948 } else { 949 if (upeek(tcp, PT_R15, &scno) < 0) 950 return -1; 951 } 952# elif defined (ARM) 953 /* Read complete register set in one go. */ 954 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1) 955 return -1; 956 957 /* 958 * We only need to grab the syscall number on syscall entry. 959 */ 960 if (regs.ARM_ip == 0) { 961 /* 962 * Note: we only deal with only 32-bit CPUs here. 963 */ 964 if (regs.ARM_cpsr & 0x20) { 965 /* 966 * Get the Thumb-mode system call number 967 */ 968 scno = regs.ARM_r7; 969 } else { 970 /* 971 * Get the ARM-mode system call number 972 */ 973 errno = 0; 974 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL); 975 if (errno) 976 return -1; 977 978 /* Handle the EABI syscall convention. We do not 979 bother converting structures between the two 980 ABIs, but basic functionality should work even 981 if strace and the traced program have different 982 ABIs. */ 983 if (scno == 0xef000000) { 984 scno = regs.ARM_r7; 985 } else { 986 if ((scno & 0x0ff00000) != 0x0f900000) { 987 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n", 988 scno); 989 return -1; 990 } 991 992 /* 993 * Fixup the syscall number 994 */ 995 scno &= 0x000fffff; 996 } 997 } 998 if (scno & 0x0f0000) { 999 /* 1000 * Handle ARM specific syscall 1001 */ 1002 set_personality(1); 1003 scno &= 0x0000ffff; 1004 } else 1005 set_personality(0); 1006 1007 } else { 1008 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid); 1009 tcp->flags |= TCB_INSYSCALL; 1010 } 1011# elif defined (M68K) 1012 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0) 1013 return -1; 1014# elif defined (LINUX_MIPSN32) 1015 unsigned long long regs[38]; 1016 1017 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1018 return -1; 1019 a3 = regs[REG_A3]; 1020 r2 = regs[REG_V0]; 1021 1022 scno = r2; 1023 if (scno < 0 || scno > nsyscalls) { 1024 if (a3 == 0 || a3 == -1) { 1025 if (debug) 1026 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno); 1027 return 0; 1028 } 1029 } 1030# elif defined (MIPS) 1031 if (upeek(tcp, REG_A3, &a3) < 0) 1032 return -1; 1033 if (upeek(tcp, REG_V0, &scno) < 0) 1034 return -1; 1035 1036 if (scno < 0 || scno > nsyscalls) { 1037 if (a3 == 0 || a3 == -1) { 1038 if (debug) 1039 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno); 1040 return 0; 1041 } 1042 } 1043# elif defined (ALPHA) 1044 if (upeek(tcp, REG_A3, &a3) < 0) 1045 return -1; 1046 if (upeek(tcp, REG_R0, &scno) < 0) 1047 return -1; 1048 1049 /* 1050 * Do some sanity checks to figure out if it's 1051 * really a syscall entry 1052 */ 1053 if (scno < 0 || scno > nsyscalls) { 1054 if (a3 == 0 || a3 == -1) { 1055 if (debug) 1056 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno); 1057 return 0; 1058 } 1059 } 1060# elif defined (SPARC) || defined (SPARC64) 1061 /* Everything we need is in the current register set. */ 1062 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 1063 return -1; 1064 1065 /* Disassemble the syscall trap. */ 1066 /* Retrieve the syscall trap instruction. */ 1067 errno = 0; 1068# if defined(SPARC64) 1069 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0); 1070 trap >>= 32; 1071# else 1072 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0); 1073# endif 1074 if (errno) 1075 return -1; 1076 1077 /* Disassemble the trap to see what personality to use. */ 1078 switch (trap) { 1079 case 0x91d02010: 1080 /* Linux/SPARC syscall trap. */ 1081 set_personality(0); 1082 break; 1083 case 0x91d0206d: 1084 /* Linux/SPARC64 syscall trap. */ 1085 set_personality(2); 1086 break; 1087 case 0x91d02000: 1088 /* SunOS syscall trap. (pers 1) */ 1089 fprintf(stderr, "syscall: SunOS no support\n"); 1090 return -1; 1091 case 0x91d02008: 1092 /* Solaris 2.x syscall trap. (per 2) */ 1093 set_personality(1); 1094 break; 1095 case 0x91d02009: 1096 /* NetBSD/FreeBSD syscall trap. */ 1097 fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n"); 1098 return -1; 1099 case 0x91d02027: 1100 /* Solaris 2.x gettimeofday */ 1101 set_personality(1); 1102 break; 1103 default: 1104# if defined (SPARC64) 1105 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc); 1106# else 1107 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc); 1108# endif 1109 return -1; 1110 } 1111 1112 /* Extract the system call number from the registers. */ 1113 if (trap == 0x91d02027) 1114 scno = 156; 1115 else 1116 scno = regs.u_regs[U_REG_G1]; 1117 if (scno == 0) { 1118 scno = regs.u_regs[U_REG_O0]; 1119 memmove(®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0])); 1120 } 1121# elif defined(HPPA) 1122 if (upeek(tcp, PT_GR20, &scno) < 0) 1123 return -1; 1124# elif defined(SH) 1125 /* 1126 * In the new syscall ABI, the system call number is in R3. 1127 */ 1128 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0) 1129 return -1; 1130 1131 if (scno < 0) { 1132 /* Odd as it may seem, a glibc bug has been known to cause 1133 glibc to issue bogus negative syscall numbers. So for 1134 our purposes, make strace print what it *should* have been */ 1135 long correct_scno = (scno & 0xff); 1136 if (debug) 1137 fprintf(stderr, 1138 "Detected glibc bug: bogus system call" 1139 " number = %ld, correcting to %ld\n", 1140 scno, 1141 correct_scno); 1142 scno = correct_scno; 1143 } 1144# elif defined(SH64) 1145 if (upeek(tcp, REG_SYSCALL, &scno) < 0) 1146 return -1; 1147 scno &= 0xFFFF; 1148# elif defined(CRISV10) || defined(CRISV32) 1149 if (upeek(tcp, 4*PT_R9, &scno) < 0) 1150 return -1; 1151# elif defined(TILE) 1152 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0) 1153 return -1; 1154# elif defined(MICROBLAZE) 1155 if (upeek(tcp, 0, &scno) < 0) 1156 return -1; 1157# endif 1158#endif /* LINUX */ 1159 1160#ifdef SUNOS4 1161 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0) 1162 return -1; 1163#elif defined(SH) 1164 /* new syscall ABI returns result in R0 */ 1165 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0) 1166 return -1; 1167#elif defined(SH64) 1168 /* ABI defines result returned in r9 */ 1169 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) 1170 return -1; 1171#endif 1172 1173#ifdef USE_PROCFS 1174# ifdef HAVE_PR_SYSCALL 1175 scno = tcp->status.PR_SYSCALL; 1176# else 1177# ifndef FREEBSD 1178 scno = tcp->status.PR_WHAT; 1179# else 1180 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1181 perror("pread"); 1182 return -1; 1183 } 1184 switch (regs.r_eax) { 1185 case SYS_syscall: 1186 case SYS___syscall: 1187 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int)); 1188 break; 1189 default: 1190 scno = regs.r_eax; 1191 break; 1192 } 1193# endif /* FREEBSD */ 1194# endif /* !HAVE_PR_SYSCALL */ 1195#endif /* USE_PROCFS */ 1196 1197 tcp->scno = scno; 1198 return 1; 1199} 1200 1201/* Returns: 1202 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 1203 * 1: ok, continue in trace_syscall(). 1204 * other: error, trace_syscall() should print error indicator 1205 * ("????" etc) and bail out. 1206 */ 1207static int 1208get_scno_on_sysexit(struct tcb *tcp) 1209{ 1210#ifdef LINUX 1211# if defined(S390) || defined(S390X) 1212# elif defined (POWERPC) 1213# elif defined(AVR32) 1214 /* Read complete register set in one go. */ 1215 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0) 1216 return -1; 1217# elif defined(BFIN) 1218# elif defined (I386) 1219 if (upeek(tcp, 4*EAX, &eax) < 0) 1220 return -1; 1221# elif defined (X86_64) 1222 if (upeek(tcp, 8*RAX, &rax) < 0) 1223 return -1; 1224# elif defined(IA64) 1225# define IA64_PSR_IS ((long)1 << 34) 1226 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) 1227 ia32 = (psr & IA64_PSR_IS) != 0; 1228 if (upeek(tcp, PT_R8, &r8) < 0) 1229 return -1; 1230 if (upeek(tcp, PT_R10, &r10) < 0) 1231 return -1; 1232# elif defined (ARM) 1233 /* Read complete register set in one go. */ 1234 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1) 1235 return -1; 1236# elif defined (M68K) 1237# elif defined (LINUX_MIPSN32) 1238 unsigned long long regs[38]; 1239 1240 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1241 return -1; 1242 a3 = regs[REG_A3]; 1243 r2 = regs[REG_V0]; 1244# elif defined (MIPS) 1245 if (upeek(tcp, REG_A3, &a3) < 0) 1246 return -1; 1247 if (upeek(tcp, REG_V0, &r2) < 0) 1248 return -1; 1249# elif defined (ALPHA) 1250 if (upeek(tcp, REG_A3, &a3) < 0) 1251 return -1; 1252 if (upeek(tcp, REG_R0, &r0) < 0) 1253 return -1; 1254# elif defined (SPARC) || defined (SPARC64) 1255 /* Everything we need is in the current register set. */ 1256 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 1257 return -1; 1258# elif defined(HPPA) 1259# elif defined(SH) 1260# elif defined(SH64) 1261# elif defined(CRISV10) || defined(CRISV32) 1262# elif defined(TILE) 1263# elif defined(MICROBLAZE) 1264# endif 1265#endif /* LINUX */ 1266 1267#ifdef SUNOS4 1268#elif defined(SH) 1269 /* new syscall ABI returns result in R0 */ 1270 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0) 1271 return -1; 1272#elif defined(SH64) 1273 /* ABI defines result returned in r9 */ 1274 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) 1275 return -1; 1276#endif 1277 1278#ifdef USE_PROCFS 1279# ifndef HAVE_PR_SYSCALL 1280# ifdef FREEBSD 1281 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1282 perror("pread"); 1283 return -1; 1284 } 1285# endif /* FREEBSD */ 1286# endif /* !HAVE_PR_SYSCALL */ 1287#endif /* USE_PROCFS */ 1288 1289 return 1; 1290} 1291 1292long 1293known_scno(struct tcb *tcp) 1294{ 1295 long scno = tcp->scno; 1296#if SUPPORTED_PERSONALITIES > 1 1297 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0) 1298 scno = sysent[scno].native_scno; 1299 else 1300#endif 1301 scno += NR_SYSCALL_BASE; 1302 return scno; 1303} 1304 1305/* Called in trace_syscall() at each syscall entry and exit. 1306 * Returns: 1307 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 1308 * 1: ok, continue in trace_syscall(). 1309 * other: error, trace_syscall() should print error indicator 1310 * ("????" etc) and bail out. 1311 */ 1312static int 1313syscall_fixup(struct tcb *tcp) 1314{ 1315#ifdef USE_PROCFS 1316 int scno = known_scno(tcp); 1317 1318 if (entering(tcp)) { 1319 if (tcp->status.PR_WHY != PR_SYSENTRY) { 1320 if ( 1321 scno == SYS_fork 1322#ifdef SYS_vfork 1323 || scno == SYS_vfork 1324#endif /* SYS_vfork */ 1325#ifdef SYS_fork1 1326 || scno == SYS_fork1 1327#endif /* SYS_fork1 */ 1328#ifdef SYS_forkall 1329 || scno == SYS_forkall 1330#endif /* SYS_forkall */ 1331#ifdef SYS_rfork1 1332 || scno == SYS_rfork1 1333#endif /* SYS_fork1 */ 1334#ifdef SYS_rforkall 1335 || scno == SYS_rforkall 1336#endif /* SYS_rforkall */ 1337 ) { 1338 /* We are returning in the child, fake it. */ 1339 tcp->status.PR_WHY = PR_SYSENTRY; 1340 trace_syscall(tcp); 1341 tcp->status.PR_WHY = PR_SYSEXIT; 1342 } 1343 else { 1344 fprintf(stderr, "syscall: missing entry\n"); 1345 tcp->flags |= TCB_INSYSCALL; 1346 } 1347 } 1348 } 1349 else { 1350 if (tcp->status.PR_WHY != PR_SYSEXIT) { 1351 fprintf(stderr, "syscall: missing exit\n"); 1352 tcp->flags &= ~TCB_INSYSCALL; 1353 } 1354 } 1355#endif /* USE_PROCFS */ 1356 1357#ifdef SUNOS4 1358 if (entering(tcp)) { 1359 if (scno == 0) { 1360 fprintf(stderr, "syscall: missing entry\n"); 1361 tcp->flags |= TCB_INSYSCALL; 1362 } 1363 } 1364 else { 1365 if (scno != 0) { 1366 if (debug) { 1367 /* 1368 * This happens when a signal handler 1369 * for a signal which interrupted a 1370 * a system call makes another system call. 1371 */ 1372 fprintf(stderr, "syscall: missing exit\n"); 1373 } 1374 tcp->flags &= ~TCB_INSYSCALL; 1375 } 1376 } 1377#endif /* SUNOS4 */ 1378 1379#ifdef LINUX 1380 /* A common case of "not a syscall entry" is post-execve SIGTRAP */ 1381#if defined (I386) 1382 /* With PTRACE_O_TRACEEXEC, post-execve SIGTRAP is disabled. 1383 * Every extra ptrace call is expensive, so check EAX 1384 * on syscall entry only if PTRACE_O_TRACEEXEC is not enabled: 1385 */ 1386 if (entering(tcp) && !(ptrace_setoptions & PTRACE_O_TRACEEXEC)) { 1387 if (upeek(tcp, 4*EAX, &eax) < 0) 1388 return -1; 1389 if (eax != -ENOSYS) { 1390 if (debug) 1391 fprintf(stderr, "not a syscall entry (eax = %ld)\n", eax); 1392 return 0; 1393 } 1394 } 1395#elif defined (X86_64) 1396 if (entering(tcp) && !(ptrace_setoptions & PTRACE_O_TRACEEXEC)) { 1397 if (upeek(tcp, 8*RAX, &rax) < 0) 1398 return -1; 1399 if (current_personality == 1) 1400 rax = (long int)(int)rax; /* sign extend from 32 bits */ 1401 if (rax != -ENOSYS && entering(tcp)) { 1402 if (debug) 1403 fprintf(stderr, "not a syscall entry (rax = %ld)\n", rax); 1404 return 0; 1405 } 1406 } 1407#elif defined (S390) || defined (S390X) 1408 if (upeek(tcp, PT_GPR2, &gpr2) < 0) 1409 return -1; 1410 if (syscall_mode != -ENOSYS) 1411 syscall_mode = tcp->scno; 1412 if (gpr2 != syscall_mode && entering(tcp)) { 1413 if (debug) 1414 fprintf(stderr, "not a syscall entry (gpr2 = %ld)\n", gpr2); 1415 return 0; 1416 } 1417 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE)) 1418 == (TCB_INSYSCALL|TCB_WAITEXECVE)) 1419 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) { 1420 /* 1421 * Return from execve. 1422 * Fake a return value of zero. We leave the TCB_WAITEXECVE 1423 * flag set for the post-execve SIGTRAP to see and reset. 1424 */ 1425 gpr2 = 0; 1426 } 1427#elif defined (POWERPC) 1428# define SO_MASK 0x10000000 1429 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) 1430 return -1; 1431 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0) 1432 return -1; 1433 if (flags & SO_MASK) 1434 result = -result; 1435#elif defined (M68K) 1436 if (upeek(tcp, 4*PT_D0, &d0) < 0) 1437 return -1; 1438 if (d0 != -ENOSYS && entering(tcp)) { 1439 if (debug) 1440 fprintf(stderr, "not a syscall entry (d0 = %ld)\n", d0); 1441 return 0; 1442 } 1443#elif defined (ARM) 1444 /* 1445 * Nothing required 1446 */ 1447#elif defined(BFIN) 1448 if (upeek(tcp, PT_R0, &r0) < 0) 1449 return -1; 1450#elif defined (HPPA) 1451 if (upeek(tcp, PT_GR28, &r28) < 0) 1452 return -1; 1453#elif defined(IA64) 1454 if (upeek(tcp, PT_R10, &r10) < 0) 1455 return -1; 1456 if (upeek(tcp, PT_R8, &r8) < 0) 1457 return -1; 1458 if (ia32 && r8 != -ENOSYS && entering(tcp)) { 1459 if (debug) 1460 fprintf(stderr, "not a syscall entry (r8 = %ld)\n", r8); 1461 return 0; 1462 } 1463#elif defined(CRISV10) || defined(CRISV32) 1464 if (upeek(tcp, 4*PT_R10, &r10) < 0) 1465 return -1; 1466 if (r10 != -ENOSYS && entering(tcp)) { 1467 if (debug) 1468 fprintf(stderr, "not a syscall entry (r10 = %ld)\n", r10); 1469 return 0; 1470 } 1471#elif defined(MICROBLAZE) 1472 if (upeek(tcp, 3 * 4, &r3) < 0) 1473 return -1; 1474 if (r3 != -ENOSYS && entering(tcp)) { 1475 if (debug) 1476 fprintf(stderr, "not a syscall entry (r3 = %ld)\n", r3); 1477 return 0; 1478 } 1479#endif 1480#endif /* LINUX */ 1481 return 1; 1482} 1483 1484#ifdef LINUX 1485/* 1486 * Check the syscall return value register value for whether it is 1487 * a negated errno code indicating an error, or a success return value. 1488 */ 1489static inline int 1490is_negated_errno(unsigned long int val) 1491{ 1492 unsigned long int max = -(long int) nerrnos; 1493# if SUPPORTED_PERSONALITIES > 1 1494 if (personality_wordsize[current_personality] < sizeof(val)) { 1495 val = (unsigned int) val; 1496 max = (unsigned int) max; 1497 } 1498# endif 1499 return val > max; 1500} 1501#endif 1502 1503static int 1504get_error(struct tcb *tcp) 1505{ 1506 int u_error = 0; 1507#ifdef LINUX 1508 int check_errno = 1; 1509 if (tcp->scno >= 0 && tcp->scno < nsyscalls && 1510 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) { 1511 check_errno = 0; 1512 } 1513# if defined(S390) || defined(S390X) 1514 if (check_errno && is_negated_errno(gpr2)) { 1515 tcp->u_rval = -1; 1516 u_error = -gpr2; 1517 } 1518 else { 1519 tcp->u_rval = gpr2; 1520 u_error = 0; 1521 } 1522# elif defined(I386) 1523 if (check_errno && is_negated_errno(eax)) { 1524 tcp->u_rval = -1; 1525 u_error = -eax; 1526 } 1527 else { 1528 tcp->u_rval = eax; 1529 u_error = 0; 1530 } 1531# elif defined(X86_64) 1532 if (check_errno && is_negated_errno(rax)) { 1533 tcp->u_rval = -1; 1534 u_error = -rax; 1535 } 1536 else { 1537 tcp->u_rval = rax; 1538 u_error = 0; 1539 } 1540# elif defined(IA64) 1541 if (ia32) { 1542 int err; 1543 1544 err = (int)r8; 1545 if (check_errno && is_negated_errno(err)) { 1546 tcp->u_rval = -1; 1547 u_error = -err; 1548 } 1549 else { 1550 tcp->u_rval = err; 1551 u_error = 0; 1552 } 1553 } else { 1554 if (check_errno && r10) { 1555 tcp->u_rval = -1; 1556 u_error = r8; 1557 } else { 1558 tcp->u_rval = r8; 1559 u_error = 0; 1560 } 1561 } 1562# elif defined(MIPS) 1563 if (check_errno && a3) { 1564 tcp->u_rval = -1; 1565 u_error = r2; 1566 } else { 1567 tcp->u_rval = r2; 1568 u_error = 0; 1569 } 1570# elif defined(POWERPC) 1571 if (check_errno && is_negated_errno(result)) { 1572 tcp->u_rval = -1; 1573 u_error = -result; 1574 } 1575 else { 1576 tcp->u_rval = result; 1577 u_error = 0; 1578 } 1579# elif defined(M68K) 1580 if (check_errno && is_negated_errno(d0)) { 1581 tcp->u_rval = -1; 1582 u_error = -d0; 1583 } 1584 else { 1585 tcp->u_rval = d0; 1586 u_error = 0; 1587 } 1588# elif defined(ARM) 1589 if (check_errno && is_negated_errno(regs.ARM_r0)) { 1590 tcp->u_rval = -1; 1591 u_error = -regs.ARM_r0; 1592 } 1593 else { 1594 tcp->u_rval = regs.ARM_r0; 1595 u_error = 0; 1596 } 1597# elif defined(AVR32) 1598 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) { 1599 tcp->u_rval = -1; 1600 u_error = -regs.r12; 1601 } 1602 else { 1603 tcp->u_rval = regs.r12; 1604 u_error = 0; 1605 } 1606# elif defined(BFIN) 1607 if (check_errno && is_negated_errno(r0)) { 1608 tcp->u_rval = -1; 1609 u_error = -r0; 1610 } else { 1611 tcp->u_rval = r0; 1612 u_error = 0; 1613 } 1614# elif defined(ALPHA) 1615 if (check_errno && a3) { 1616 tcp->u_rval = -1; 1617 u_error = r0; 1618 } 1619 else { 1620 tcp->u_rval = r0; 1621 u_error = 0; 1622 } 1623# elif defined(SPARC) 1624 if (check_errno && regs.psr & PSR_C) { 1625 tcp->u_rval = -1; 1626 u_error = regs.u_regs[U_REG_O0]; 1627 } 1628 else { 1629 tcp->u_rval = regs.u_regs[U_REG_O0]; 1630 u_error = 0; 1631 } 1632# elif defined(SPARC64) 1633 if (check_errno && regs.tstate & 0x1100000000UL) { 1634 tcp->u_rval = -1; 1635 u_error = regs.u_regs[U_REG_O0]; 1636 } 1637 else { 1638 tcp->u_rval = regs.u_regs[U_REG_O0]; 1639 u_error = 0; 1640 } 1641# elif defined(HPPA) 1642 if (check_errno && is_negated_errno(r28)) { 1643 tcp->u_rval = -1; 1644 u_error = -r28; 1645 } 1646 else { 1647 tcp->u_rval = r28; 1648 u_error = 0; 1649 } 1650# elif defined(SH) 1651 /* interpret R0 as return value or error number */ 1652 if (check_errno && is_negated_errno(r0)) { 1653 tcp->u_rval = -1; 1654 u_error = -r0; 1655 } 1656 else { 1657 tcp->u_rval = r0; 1658 u_error = 0; 1659 } 1660# elif defined(SH64) 1661 /* interpret result as return value or error number */ 1662 if (check_errno && is_negated_errno(r9)) { 1663 tcp->u_rval = -1; 1664 u_error = -r9; 1665 } 1666 else { 1667 tcp->u_rval = r9; 1668 u_error = 0; 1669 } 1670# elif defined(CRISV10) || defined(CRISV32) 1671 if (check_errno && r10 && (unsigned) -r10 < nerrnos) { 1672 tcp->u_rval = -1; 1673 u_error = -r10; 1674 } 1675 else { 1676 tcp->u_rval = r10; 1677 u_error = 0; 1678 } 1679# elif defined(TILE) 1680 long rval; 1681 /* interpret result as return value or error number */ 1682 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0) 1683 return -1; 1684 if (check_errno && rval < 0 && rval > -nerrnos) { 1685 tcp->u_rval = -1; 1686 u_error = -rval; 1687 } 1688 else { 1689 tcp->u_rval = rval; 1690 u_error = 0; 1691 } 1692# elif defined(MICROBLAZE) 1693 /* interpret result as return value or error number */ 1694 if (check_errno && is_negated_errno(r3)) { 1695 tcp->u_rval = -1; 1696 u_error = -r3; 1697 } 1698 else { 1699 tcp->u_rval = r3; 1700 u_error = 0; 1701 } 1702# endif 1703#endif /* LINUX */ 1704#ifdef SUNOS4 1705 /* get error code from user struct */ 1706 if (upeek(tcp, uoff(u_error), &u_error) < 0) 1707 return -1; 1708 u_error >>= 24; /* u_error is a char */ 1709 1710 /* get system call return value */ 1711 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0) 1712 return -1; 1713#endif /* SUNOS4 */ 1714#ifdef SVR4 1715# ifdef SPARC 1716 /* Judicious guessing goes a long way. */ 1717 if (tcp->status.pr_reg[R_PSR] & 0x100000) { 1718 tcp->u_rval = -1; 1719 u_error = tcp->status.pr_reg[R_O0]; 1720 } 1721 else { 1722 tcp->u_rval = tcp->status.pr_reg[R_O0]; 1723 u_error = 0; 1724 } 1725# endif /* SPARC */ 1726# ifdef I386 1727 /* Wanna know how to kill an hour single-stepping? */ 1728 if (tcp->status.PR_REG[EFL] & 0x1) { 1729 tcp->u_rval = -1; 1730 u_error = tcp->status.PR_REG[EAX]; 1731 } 1732 else { 1733 tcp->u_rval = tcp->status.PR_REG[EAX]; 1734# ifdef HAVE_LONG_LONG 1735 tcp->u_lrval = 1736 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) + 1737 tcp->status.PR_REG[EAX]; 1738# endif 1739 u_error = 0; 1740 } 1741# endif /* I386 */ 1742# ifdef X86_64 1743 /* Wanna know how to kill an hour single-stepping? */ 1744 if (tcp->status.PR_REG[EFLAGS] & 0x1) { 1745 tcp->u_rval = -1; 1746 u_error = tcp->status.PR_REG[RAX]; 1747 } 1748 else { 1749 tcp->u_rval = tcp->status.PR_REG[RAX]; 1750 u_error = 0; 1751 } 1752# endif /* X86_64 */ 1753# ifdef MIPS 1754 if (tcp->status.pr_reg[CTX_A3]) { 1755 tcp->u_rval = -1; 1756 u_error = tcp->status.pr_reg[CTX_V0]; 1757 } 1758 else { 1759 tcp->u_rval = tcp->status.pr_reg[CTX_V0]; 1760 u_error = 0; 1761 } 1762# endif /* MIPS */ 1763#endif /* SVR4 */ 1764#ifdef FREEBSD 1765 if (regs.r_eflags & PSL_C) { 1766 tcp->u_rval = -1; 1767 u_error = regs.r_eax; 1768 } else { 1769 tcp->u_rval = regs.r_eax; 1770 tcp->u_lrval = 1771 ((unsigned long long) regs.r_edx << 32) + regs.r_eax; 1772 u_error = 0; 1773 } 1774#endif /* FREEBSD */ 1775 tcp->u_error = u_error; 1776 return 1; 1777} 1778 1779int 1780force_result(struct tcb *tcp, int error, long rval) 1781{ 1782#ifdef LINUX 1783# if defined(S390) || defined(S390X) 1784 gpr2 = error ? -error : rval; 1785 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0) 1786 return -1; 1787# elif defined(I386) 1788 eax = error ? -error : rval; 1789 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0) 1790 return -1; 1791# elif defined(X86_64) 1792 rax = error ? -error : rval; 1793 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0) 1794 return -1; 1795# elif defined(IA64) 1796 if (ia32) { 1797 r8 = error ? -error : rval; 1798 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0) 1799 return -1; 1800 } 1801 else { 1802 if (error) { 1803 r8 = error; 1804 r10 = -1; 1805 } 1806 else { 1807 r8 = rval; 1808 r10 = 0; 1809 } 1810 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 || 1811 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0) 1812 return -1; 1813 } 1814# elif defined(BFIN) 1815 r0 = error ? -error : rval; 1816 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0) 1817 return -1; 1818# elif defined(MIPS) 1819 if (error) { 1820 r2 = error; 1821 a3 = -1; 1822 } 1823 else { 1824 r2 = rval; 1825 a3 = 0; 1826 } 1827 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */ 1828 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || 1829 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0) 1830 return -1; 1831# elif defined(POWERPC) 1832 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) 1833 return -1; 1834 if (error) { 1835 flags |= SO_MASK; 1836 result = error; 1837 } 1838 else { 1839 flags &= ~SO_MASK; 1840 result = rval; 1841 } 1842 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 || 1843 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0) 1844 return -1; 1845# elif defined(M68K) 1846 d0 = error ? -error : rval; 1847 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0) 1848 return -1; 1849# elif defined(ARM) 1850 regs.ARM_r0 = error ? -error : rval; 1851 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0) 1852 return -1; 1853# elif defined(AVR32) 1854 regs.r12 = error ? -error : rval; 1855 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0) 1856 return -1; 1857# elif defined(ALPHA) 1858 if (error) { 1859 a3 = -1; 1860 r0 = error; 1861 } 1862 else { 1863 a3 = 0; 1864 r0 = rval; 1865 } 1866 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || 1867 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0) 1868 return -1; 1869# elif defined(SPARC) 1870 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 1871 return -1; 1872 if (error) { 1873 regs.psr |= PSR_C; 1874 regs.u_regs[U_REG_O0] = error; 1875 } 1876 else { 1877 regs.psr &= ~PSR_C; 1878 regs.u_regs[U_REG_O0] = rval; 1879 } 1880 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) 1881 return -1; 1882# elif defined(SPARC64) 1883 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 1884 return -1; 1885 if (error) { 1886 regs.tstate |= 0x1100000000UL; 1887 regs.u_regs[U_REG_O0] = error; 1888 } 1889 else { 1890 regs.tstate &= ~0x1100000000UL; 1891 regs.u_regs[U_REG_O0] = rval; 1892 } 1893 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) 1894 return -1; 1895# elif defined(HPPA) 1896 r28 = error ? -error : rval; 1897 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0) 1898 return -1; 1899# elif defined(SH) 1900 r0 = error ? -error : rval; 1901 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0) 1902 return -1; 1903# elif defined(SH64) 1904 r9 = error ? -error : rval; 1905 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0) 1906 return -1; 1907# endif 1908#endif /* LINUX */ 1909 1910#ifdef SUNOS4 1911 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error), 1912 error << 24) < 0 || 1913 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0) 1914 return -1; 1915#endif /* SUNOS4 */ 1916 1917#ifdef SVR4 1918 /* XXX no clue */ 1919 return -1; 1920#endif /* SVR4 */ 1921 1922#ifdef FREEBSD 1923 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1924 perror("pread"); 1925 return -1; 1926 } 1927 if (error) { 1928 regs.r_eflags |= PSL_C; 1929 regs.r_eax = error; 1930 } 1931 else { 1932 regs.r_eflags &= ~PSL_C; 1933 regs.r_eax = rval; 1934 } 1935 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1936 perror("pwrite"); 1937 return -1; 1938 } 1939#endif /* FREEBSD */ 1940 1941 /* All branches reach here on success (only). */ 1942 tcp->u_error = error; 1943 tcp->u_rval = rval; 1944 return 0; 1945} 1946 1947static int 1948syscall_enter(struct tcb *tcp) 1949{ 1950#ifdef LINUX 1951 int i, nargs; 1952 1953 if (tcp->scno >= 0 && tcp->scno < nsyscalls) 1954 nargs = tcp->u_nargs = sysent[tcp->scno].nargs; 1955 else 1956 nargs = tcp->u_nargs = MAX_ARGS; 1957 1958# if defined(S390) || defined(S390X) 1959 for (i = 0; i < nargs; ++i) 1960 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2 + i*sizeof(long), &tcp->u_arg[i]) < 0) 1961 return -1; 1962# elif defined(ALPHA) 1963 for (i = 0; i < nargs; ++i) 1964 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0) 1965 return -1; 1966# elif defined(IA64) 1967 if (!ia32) { 1968 unsigned long *out0, cfm, sof, sol; 1969 long rbs_end; 1970 /* be backwards compatible with kernel < 2.4.4... */ 1971# ifndef PT_RBS_END 1972# define PT_RBS_END PT_AR_BSP 1973# endif 1974 1975 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0) 1976 return -1; 1977 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1978 return -1; 1979 1980 sof = (cfm >> 0) & 0x7f; 1981 sol = (cfm >> 7) & 0x7f; 1982 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol); 1983 1984 for (i = 0; i < nargs; ++i) { 1985 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i), 1986 sizeof(long), (char *) &tcp->u_arg[i]) < 0) 1987 return -1; 1988 } 1989 } else { 1990 static const int argreg[MAX_ARGS] = { PT_R11 /* EBX = out0 */, 1991 PT_R9 /* ECX = out1 */, 1992 PT_R10 /* EDX = out2 */, 1993 PT_R14 /* ESI = out3 */, 1994 PT_R15 /* EDI = out4 */, 1995 PT_R13 /* EBP = out5 */}; 1996 1997 for (i = 0; i < nargs; ++i) { 1998 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0) 1999 return -1; 2000 /* truncate away IVE sign-extension */ 2001 tcp->u_arg[i] &= 0xffffffff; 2002 } 2003 } 2004# elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64) 2005 /* N32 and N64 both use up to six registers. */ 2006 unsigned long long regs[38]; 2007 2008 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 2009 return -1; 2010 2011 for (i = 0; i < nargs; ++i) { 2012 tcp->u_arg[i] = regs[REG_A0 + i]; 2013# if defined(LINUX_MIPSN32) 2014 tcp->ext_arg[i] = regs[REG_A0 + i]; 2015# endif 2016 } 2017# elif defined(MIPS) 2018 if (nargs > 4) { 2019 long sp; 2020 2021 if (upeek(tcp, REG_SP, &sp) < 0) 2022 return -1; 2023 for (i = 0; i < 4; ++i) 2024 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0) 2025 return -1; 2026 umoven(tcp, sp + 16, (nargs - 4) * sizeof(tcp->u_arg[0]), 2027 (char *)(tcp->u_arg + 4)); 2028 } else { 2029 for (i = 0; i < nargs; ++i) 2030 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0) 2031 return -1; 2032 } 2033# elif defined(POWERPC) 2034# ifndef PT_ORIG_R3 2035# define PT_ORIG_R3 34 2036# endif 2037 for (i = 0; i < nargs; ++i) { 2038 if (upeek(tcp, (i==0) ? 2039 (sizeof(unsigned long) * PT_ORIG_R3) : 2040 ((i+PT_R3) * sizeof(unsigned long)), 2041 &tcp->u_arg[i]) < 0) 2042 return -1; 2043 } 2044# elif defined(SPARC) || defined(SPARC64) 2045 for (i = 0; i < nargs; ++i) 2046 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i]; 2047# elif defined(HPPA) 2048 for (i = 0; i < nargs; ++i) 2049 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0) 2050 return -1; 2051# elif defined(ARM) 2052 for (i = 0; i < nargs; ++i) 2053 tcp->u_arg[i] = regs.uregs[i]; 2054# elif defined(AVR32) 2055 static const unsigned long *argregp[MAX_ARGS] = { ®s.r12, 2056 ®s.r11, 2057 ®s.r10, 2058 ®s.r9, 2059 ®s.r5, 2060 ®s.r3 }; 2061 for (i = 0; i < nargs; ++i) 2062 tcp->u_arg[i] = *argregp[i]; 2063# elif defined(BFIN) 2064 static const int argreg[MAX_ARGS] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 }; 2065 2066 for (i = 0; i < nargs; ++i) 2067 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0) 2068 return -1; 2069# elif defined(SH) 2070 static const int syscall_regs[MAX_ARGS] = { 2071 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6), 2072 4 * (REG_REG0+7), 4 * (REG_REG0 ), 4 * (REG_REG0+1) 2073 }; 2074 2075 for (i = 0; i < nargs; ++i) 2076 if (upeek(tcp, syscall_regs[i], &tcp->u_arg[i]) < 0) 2077 return -1; 2078# elif defined(SH64) 2079 int i; 2080 /* Registers used by SH5 Linux system calls for parameters */ 2081 static const int syscall_regs[MAX_ARGS] = { 2, 3, 4, 5, 6, 7 }; 2082 2083 for (i = 0; i < nargs; ++i) 2084 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0) 2085 return -1; 2086# elif defined(X86_64) 2087 static const int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = { 2088 { 8 * RDI, 8 * RSI, 8 * RDX, 8 * R10, 8 * R8 , 8 * R9 }, /* x86-64 ABI */ 2089 { 8 * RBX, 8 * RCX, 8 * RDX, 8 * RSI, 8 * RDI, 8 * RBP } /* i386 ABI */ 2090 }; 2091 2092 for (i = 0; i < nargs; ++i) 2093 if (upeek(tcp, argreg[current_personality][i], &tcp->u_arg[i]) < 0) 2094 return -1; 2095# elif defined(MICROBLAZE) 2096 for (i = 0; i < nargs; ++i) 2097 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0) 2098 return -1; 2099# elif defined(CRISV10) || defined(CRISV32) 2100 static const int crisregs[MAX_ARGS] = { 2101 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12, 2102 4*PT_R13 , 4*PT_MOF, 4*PT_SRP 2103 }; 2104 2105 for (i = 0; i < nargs; ++i) 2106 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0) 2107 return -1; 2108# elif defined(TILE) 2109 for (i = 0; i < nargs; ++i) 2110 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0) 2111 return -1; 2112# elif defined(M68K) 2113 for (i = 0; i < nargs; ++i) 2114 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0) 2115 return -1; 2116# else /* Other architecture (like i386) (32bits specific) */ 2117 for (i = 0; i < nargs; ++i) 2118 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0) 2119 return -1; 2120# endif 2121#endif /* LINUX */ 2122#ifdef SUNOS4 2123 int i, nargs; 2124 if (tcp->scno >= 0 && tcp->scno < nsyscalls) 2125 nargs = tcp->u_nargs = sysent[tcp->scno].nargs; 2126 else 2127 nargs = tcp->u_nargs = MAX_ARGS; 2128 for (i = 0; i < nargs; i++) { 2129 struct user *u; 2130 2131 if (upeek(tcp, uoff(u_arg[0]) + 2132 (i * sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0) 2133 return -1; 2134 } 2135#endif /* SUNOS4 */ 2136#ifdef SVR4 2137# ifdef MIPS 2138 /* 2139 * SGI is broken: even though it has pr_sysarg, it doesn't 2140 * set them on system call entry. Get a clue. 2141 */ 2142 if (tcp->scno >= 0 && tcp->scno < nsyscalls) 2143 tcp->u_nargs = sysent[tcp->scno].nargs; 2144 else 2145 tcp->u_nargs = tcp->status.pr_nsysarg; 2146 if (tcp->u_nargs > 4) { 2147 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0], 2148 4 * sizeof(tcp->u_arg[0])); 2149 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16, 2150 (tcp->u_nargs - 4) * sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4)); 2151 } 2152 else { 2153 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0], 2154 tcp->u_nargs * sizeof(tcp->u_arg[0])); 2155 } 2156# elif UNIXWARE >= 2 2157 /* 2158 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit 2159 */ 2160 if (tcp->scno >= 0 && tcp->scno < nsyscalls) 2161 tcp->u_nargs = sysent[tcp->scno].nargs; 2162 else 2163 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg; 2164 umoven(tcp, tcp->status.PR_REG[UESP] + 4, 2165 tcp->u_nargs * sizeof(tcp->u_arg[0]), (char *) tcp->u_arg); 2166# elif defined(HAVE_PR_SYSCALL) 2167 int i; 2168 if (tcp->scno >= 0 && tcp->scno < nsyscalls) 2169 tcp->u_nargs = sysent[tcp->scno].nargs; 2170 else 2171 tcp->u_nargs = tcp->status.pr_nsysarg; 2172 for (i = 0; i < tcp->u_nargs; i++) 2173 tcp->u_arg[i] = tcp->status.pr_sysarg[i]; 2174# elif defined(I386) 2175 if (tcp->scno >= 0 && tcp->scno < nsyscalls) 2176 tcp->u_nargs = sysent[tcp->scno].nargs; 2177 else 2178 tcp->u_nargs = 5; 2179 if (tcp->u_nargs > 0) 2180 umoven(tcp, tcp->status.PR_REG[UESP] + 4, 2181 tcp->u_nargs * sizeof(tcp->u_arg[0]), (char *) tcp->u_arg); 2182# else 2183 I DONT KNOW WHAT TO DO 2184# endif 2185#endif /* SVR4 */ 2186#ifdef FREEBSD 2187 if (tcp->scno >= 0 && tcp->scno < nsyscalls && 2188 sysent[tcp->scno].nargs > tcp->status.val) 2189 tcp->u_nargs = sysent[tcp->scno].nargs; 2190 else 2191 tcp->u_nargs = tcp->status.val; 2192 if (tcp->u_nargs < 0) 2193 tcp->u_nargs = 0; 2194 if (tcp->u_nargs > MAX_ARGS) 2195 tcp->u_nargs = MAX_ARGS; 2196 switch (regs.r_eax) { 2197 case SYS___syscall: 2198 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long), 2199 regs.r_esp + sizeof(int) + sizeof(quad_t)); 2200 break; 2201 case SYS_syscall: 2202 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long), 2203 regs.r_esp + 2 * sizeof(int)); 2204 break; 2205 default: 2206 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long), 2207 regs.r_esp + sizeof(int)); 2208 break; 2209 } 2210#endif /* FREEBSD */ 2211 return 1; 2212} 2213 2214static int 2215trace_syscall_entering(struct tcb *tcp) 2216{ 2217 int res, scno_good; 2218 2219#if defined TCB_WAITEXECVE 2220 if (tcp->flags & TCB_WAITEXECVE) { 2221 /* This is the post-execve SIGTRAP. */ 2222 tcp->flags &= ~TCB_WAITEXECVE; 2223 return 0; 2224 } 2225#endif 2226 2227 scno_good = res = get_scno_on_sysenter(tcp); 2228 if (res == 0) 2229 return res; 2230 if (res == 1) 2231 res = syscall_fixup(tcp); 2232 if (res == 0) 2233 return res; 2234 if (res == 1) 2235 res = syscall_enter(tcp); 2236 if (res == 0) 2237 return res; 2238 2239 if (res != 1) { 2240 printleader(tcp); 2241 tcp->flags &= ~TCB_REPRINT; 2242 tcp_last = tcp; 2243 if (scno_good != 1) 2244 tprintf("????" /* anti-trigraph gap */ "("); 2245 else if (tcp->scno >= nsyscalls || tcp->scno < 0) 2246 tprintf("syscall_%lu(", tcp->scno); 2247 else 2248 tprintf("%s(", sysent[tcp->scno].sys_name); 2249 /* 2250 * " <unavailable>" will be added later by the code which 2251 * detects ptrace errors. 2252 */ 2253 goto ret; 2254 } 2255 2256 switch (known_scno(tcp)) { 2257#ifdef SYS_socket_subcall 2258 case SYS_socketcall: 2259 decode_subcall(tcp, SYS_socket_subcall, 2260 SYS_socket_nsubcalls, deref_style); 2261 break; 2262#endif 2263#ifdef SYS_ipc_subcall 2264 case SYS_ipc: 2265 decode_subcall(tcp, SYS_ipc_subcall, 2266 SYS_ipc_nsubcalls, shift_style); 2267 break; 2268#endif 2269#ifdef SVR4 2270#ifdef SYS_pgrpsys_subcall 2271 case SYS_pgrpsys: 2272 decode_subcall(tcp, SYS_pgrpsys_subcall, 2273 SYS_pgrpsys_nsubcalls, shift_style); 2274 break; 2275#endif /* SYS_pgrpsys_subcall */ 2276#ifdef SYS_sigcall_subcall 2277 case SYS_sigcall: 2278 decode_subcall(tcp, SYS_sigcall_subcall, 2279 SYS_sigcall_nsubcalls, mask_style); 2280 break; 2281#endif /* SYS_sigcall_subcall */ 2282 case SYS_msgsys: 2283 decode_subcall(tcp, SYS_msgsys_subcall, 2284 SYS_msgsys_nsubcalls, shift_style); 2285 break; 2286 case SYS_shmsys: 2287 decode_subcall(tcp, SYS_shmsys_subcall, 2288 SYS_shmsys_nsubcalls, shift_style); 2289 break; 2290 case SYS_semsys: 2291 decode_subcall(tcp, SYS_semsys_subcall, 2292 SYS_semsys_nsubcalls, shift_style); 2293 break; 2294 case SYS_sysfs: 2295 decode_subcall(tcp, SYS_sysfs_subcall, 2296 SYS_sysfs_nsubcalls, shift_style); 2297 break; 2298 case SYS_spcall: 2299 decode_subcall(tcp, SYS_spcall_subcall, 2300 SYS_spcall_nsubcalls, shift_style); 2301 break; 2302#ifdef SYS_context_subcall 2303 case SYS_context: 2304 decode_subcall(tcp, SYS_context_subcall, 2305 SYS_context_nsubcalls, shift_style); 2306 break; 2307#endif /* SYS_context_subcall */ 2308#ifdef SYS_door_subcall 2309 case SYS_door: 2310 decode_subcall(tcp, SYS_door_subcall, 2311 SYS_door_nsubcalls, door_style); 2312 break; 2313#endif /* SYS_door_subcall */ 2314#ifdef SYS_kaio_subcall 2315 case SYS_kaio: 2316 decode_subcall(tcp, SYS_kaio_subcall, 2317 SYS_kaio_nsubcalls, shift_style); 2318 break; 2319#endif 2320#endif /* SVR4 */ 2321#ifdef FREEBSD 2322 case SYS_msgsys: 2323 case SYS_shmsys: 2324 case SYS_semsys: 2325 decode_subcall(tcp, 0, 0, table_style); 2326 break; 2327#endif 2328#ifdef SUNOS4 2329 case SYS_semsys: 2330 decode_subcall(tcp, SYS_semsys_subcall, 2331 SYS_semsys_nsubcalls, shift_style); 2332 break; 2333 case SYS_msgsys: 2334 decode_subcall(tcp, SYS_msgsys_subcall, 2335 SYS_msgsys_nsubcalls, shift_style); 2336 break; 2337 case SYS_shmsys: 2338 decode_subcall(tcp, SYS_shmsys_subcall, 2339 SYS_shmsys_nsubcalls, shift_style); 2340 break; 2341#endif 2342 } 2343 2344 internal_syscall(tcp); 2345 2346 if ((tcp->scno >= 0 && tcp->scno < nsyscalls && 2347 !(qual_flags[tcp->scno] & QUAL_TRACE)) || 2348 (tracing_paths && !pathtrace_match(tcp))) { 2349 tcp->flags |= TCB_INSYSCALL | TCB_FILTERED; 2350 return 0; 2351 } 2352 2353 tcp->flags &= ~TCB_FILTERED; 2354 2355 if (cflag == CFLAG_ONLY_STATS) { 2356 res = 0; 2357 goto ret; 2358 } 2359 2360 printleader(tcp); 2361 tcp->flags &= ~TCB_REPRINT; 2362 tcp_last = tcp; 2363 if (tcp->scno >= nsyscalls || tcp->scno < 0) 2364 tprintf("syscall_%lu(", tcp->scno); 2365 else 2366 tprintf("%s(", sysent[tcp->scno].sys_name); 2367 if (tcp->scno >= nsyscalls || tcp->scno < 0 || 2368 ((qual_flags[tcp->scno] & QUAL_RAW) && 2369 sysent[tcp->scno].sys_func != sys_exit)) 2370 res = printargs(tcp); 2371 else 2372 res = (*sysent[tcp->scno].sys_func)(tcp); 2373 2374 if (fflush(tcp->outf) == EOF) 2375 return -1; 2376 ret: 2377 tcp->flags |= TCB_INSYSCALL; 2378 /* Measure the entrance time as late as possible to avoid errors. */ 2379 if (dtime || cflag) 2380 gettimeofday(&tcp->etime, NULL); 2381 return res; 2382} 2383 2384static int 2385trace_syscall_exiting(struct tcb *tcp) 2386{ 2387 int sys_res; 2388 struct timeval tv; 2389 int res, scno_good; 2390 long u_error; 2391 2392 /* Measure the exit time as early as possible to avoid errors. */ 2393 if (dtime || cflag) 2394 gettimeofday(&tv, NULL); 2395 2396 scno_good = res = get_scno_on_sysexit(tcp); 2397 if (res == 0) 2398 return res; 2399 if (res == 1) 2400 res = syscall_fixup(tcp); 2401 if (res == 0) 2402 return res; 2403 if (res == 1) 2404 res = get_error(tcp); 2405 if (res == 0) 2406 return res; 2407 if (res == 1) 2408 internal_syscall(tcp); 2409 2410 if (res == 1 && filtered(tcp)) { 2411 goto ret; 2412 } 2413 2414 if (tcp->flags & TCB_REPRINT) { 2415 printleader(tcp); 2416 tprintf("<... "); 2417 if (scno_good != 1) 2418 tprintf("????"); 2419 else if (tcp->scno >= nsyscalls || tcp->scno < 0) 2420 tprintf("syscall_%lu", tcp->scno); 2421 else 2422 tprintf("%s", sysent[tcp->scno].sys_name); 2423 tprintf(" resumed> "); 2424 } 2425 2426 if (cflag) { 2427 struct timeval t = tv; 2428 count_syscall(tcp, &t); 2429 if (cflag == CFLAG_ONLY_STATS) { 2430 goto ret; 2431 } 2432 } 2433 2434 if (res != 1) { 2435 tprintf(") "); 2436 tabto(acolumn); 2437 tprintf("= ? <unavailable>"); 2438 printtrailer(); 2439 tcp->flags &= ~TCB_INSYSCALL; 2440 return res; 2441 } 2442 2443 if (tcp->scno >= nsyscalls || tcp->scno < 0 2444 || (qual_flags[tcp->scno] & QUAL_RAW)) 2445 sys_res = printargs(tcp); 2446 else { 2447 /* FIXME: not_failing_only (IOW, option -z) is broken: 2448 * failure of syscall is known only after syscall return. 2449 * Thus we end up with something like this on, say, ENOENT: 2450 * open("doesnt_exist", O_RDONLY <unfinished ...> 2451 * {next syscall decode} 2452 * whereas the intended result is that open(...) line 2453 * is not shown at all. 2454 */ 2455 if (not_failing_only && tcp->u_error) 2456 goto ret; /* ignore failed syscalls */ 2457 sys_res = (*sysent[tcp->scno].sys_func)(tcp); 2458 } 2459 2460 tprintf(") "); 2461 tabto(acolumn); 2462 u_error = tcp->u_error; 2463 if (tcp->scno >= nsyscalls || tcp->scno < 0 || 2464 qual_flags[tcp->scno] & QUAL_RAW) { 2465 if (u_error) 2466 tprintf("= -1 (errno %ld)", u_error); 2467 else 2468 tprintf("= %#lx", tcp->u_rval); 2469 } 2470 else if (!(sys_res & RVAL_NONE) && u_error) { 2471 switch (u_error) { 2472#ifdef LINUX 2473 case ERESTARTSYS: 2474 tprintf("= ? ERESTARTSYS (To be restarted)"); 2475 break; 2476 case ERESTARTNOINTR: 2477 tprintf("= ? ERESTARTNOINTR (To be restarted)"); 2478 break; 2479 case ERESTARTNOHAND: 2480 tprintf("= ? ERESTARTNOHAND (To be restarted)"); 2481 break; 2482 case ERESTART_RESTARTBLOCK: 2483 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)"); 2484 break; 2485#endif /* LINUX */ 2486 default: 2487 if (u_error < 0) 2488 tprintf("= -1 E??? (errno %ld)", u_error); 2489 else if (u_error < nerrnos) 2490 tprintf("= -1 %s (%s)", errnoent[u_error], 2491 strerror(u_error)); 2492 else 2493 tprintf("= -1 ERRNO_%ld (%s)", u_error, 2494 strerror(u_error)); 2495 break; 2496 } 2497 if ((sys_res & RVAL_STR) && tcp->auxstr) 2498 tprintf(" (%s)", tcp->auxstr); 2499 } 2500 else { 2501 if (sys_res & RVAL_NONE) 2502 tprintf("= ?"); 2503 else { 2504 switch (sys_res & RVAL_MASK) { 2505 case RVAL_HEX: 2506 tprintf("= %#lx", tcp->u_rval); 2507 break; 2508 case RVAL_OCTAL: 2509 tprintf("= %#lo", tcp->u_rval); 2510 break; 2511 case RVAL_UDECIMAL: 2512 tprintf("= %lu", tcp->u_rval); 2513 break; 2514 case RVAL_DECIMAL: 2515 tprintf("= %ld", tcp->u_rval); 2516 break; 2517#ifdef HAVE_LONG_LONG 2518 case RVAL_LHEX: 2519 tprintf("= %#llx", tcp->u_lrval); 2520 break; 2521 case RVAL_LOCTAL: 2522 tprintf("= %#llo", tcp->u_lrval); 2523 break; 2524 case RVAL_LUDECIMAL: 2525 tprintf("= %llu", tcp->u_lrval); 2526 break; 2527 case RVAL_LDECIMAL: 2528 tprintf("= %lld", tcp->u_lrval); 2529 break; 2530#endif 2531 default: 2532 fprintf(stderr, 2533 "invalid rval format\n"); 2534 break; 2535 } 2536 } 2537 if ((sys_res & RVAL_STR) && tcp->auxstr) 2538 tprintf(" (%s)", tcp->auxstr); 2539 } 2540 if (dtime) { 2541 tv_sub(&tv, &tv, &tcp->etime); 2542 tprintf(" <%ld.%06ld>", 2543 (long) tv.tv_sec, (long) tv.tv_usec); 2544 } 2545 printtrailer(); 2546 2547 dumpio(tcp); 2548 if (fflush(tcp->outf) == EOF) 2549 return -1; 2550 ret: 2551 tcp->flags &= ~TCB_INSYSCALL; 2552 return 0; 2553} 2554 2555int 2556trace_syscall(struct tcb *tcp) 2557{ 2558 return exiting(tcp) ? 2559 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp); 2560} 2561 2562int 2563printargs(struct tcb *tcp) 2564{ 2565 if (entering(tcp)) { 2566 int i; 2567 2568 for (i = 0; i < tcp->u_nargs; i++) 2569 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]); 2570 } 2571 return 0; 2572} 2573 2574long 2575getrval2(struct tcb *tcp) 2576{ 2577 long val = -1; 2578 2579#ifdef LINUX 2580#if defined (SPARC) || defined (SPARC64) 2581 struct pt_regs regs; 2582 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 2583 return -1; 2584 val = regs.u_regs[U_REG_O1]; 2585#elif defined(SH) 2586 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0) 2587 return -1; 2588#elif defined(IA64) 2589 if (upeek(tcp, PT_R9, &val) < 0) 2590 return -1; 2591#endif 2592#endif /* LINUX */ 2593 2594#ifdef SUNOS4 2595 if (upeek(tcp, uoff(u_rval2), &val) < 0) 2596 return -1; 2597#endif /* SUNOS4 */ 2598 2599#ifdef SVR4 2600#ifdef SPARC 2601 val = tcp->status.PR_REG[R_O1]; 2602#endif /* SPARC */ 2603#ifdef I386 2604 val = tcp->status.PR_REG[EDX]; 2605#endif /* I386 */ 2606#ifdef X86_64 2607 val = tcp->status.PR_REG[RDX]; 2608#endif /* X86_64 */ 2609#ifdef MIPS 2610 val = tcp->status.PR_REG[CTX_V1]; 2611#endif /* MIPS */ 2612#endif /* SVR4 */ 2613 2614#ifdef FREEBSD 2615 struct reg regs; 2616 pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 2617 val = regs.r_edx; 2618#endif 2619 return val; 2620} 2621 2622#ifdef SUNOS4 2623/* 2624 * Apparently, indirect system calls have already be converted by ptrace(2), 2625 * so if you see "indir" this program has gone astray. 2626 */ 2627int 2628sys_indir(struct tcb *tcp) 2629{ 2630 int i, scno, nargs; 2631 2632 if (entering(tcp)) { 2633 scno = tcp->u_arg[0]; 2634 if (scno > nsyscalls) { 2635 fprintf(stderr, "Bogus syscall: %u\n", scno); 2636 return 0; 2637 } 2638 nargs = sysent[scno].nargs; 2639 tprintf("%s", sysent[scno].sys_name); 2640 for (i = 0; i < nargs; i++) 2641 tprintf(", %#lx", tcp->u_arg[i+1]); 2642 } 2643 return 0; 2644} 2645#endif /* SUNOS4 */ 2646 2647int 2648is_restart_error(struct tcb *tcp) 2649{ 2650#ifdef LINUX 2651 if (!syserror(tcp)) 2652 return 0; 2653 switch (tcp->u_error) { 2654 case ERESTARTSYS: 2655 case ERESTARTNOINTR: 2656 case ERESTARTNOHAND: 2657 case ERESTART_RESTARTBLOCK: 2658 return 1; 2659 default: 2660 break; 2661 } 2662#endif /* LINUX */ 2663 return 0; 2664} 2665