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