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