syscall.c revision eb285359906700f46b22cf4f9911695034313736
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#ifdef __NR_exit_group 674 case __NR_exit_group: 675#endif 676 internal_exit(tcp); 677 break; 678 } 679 return 0; 680} 681 682 683#ifdef LINUX 684#if defined (I386) 685 static long eax; 686#elif defined (IA64) 687 long r8, r10, psr; 688 long ia32 = 0; 689#elif defined (POWERPC) 690 static long result,flags; 691#elif defined (M68K) 692 static int d0; 693#elif defined (ARM) 694 static int r0; 695#elif defined (ALPHA) 696 static long r0; 697 static long a3; 698#elif defined (SPARC) 699 static struct regs regs; 700 static unsigned long trap; 701#elif defined(MIPS) 702 static long a3; 703 static long r2; 704#elif defined(S390) || defined(S390X) 705 static long gpr2; 706 static long pc; 707 static long syscall_mode; 708#elif defined(HPPA) 709 static long r28; 710#elif defined(SH) 711 static long r0; 712#elif defined(X86_64) 713 static long rax; 714#endif 715#endif /* LINUX */ 716#ifdef FREEBSD 717 struct reg regs; 718#endif /* FREEBSD */ 719 720int 721get_scno(tcp) 722struct tcb *tcp; 723{ 724 long scno = 0; 725#ifndef USE_PROCFS 726 int pid = tcp->pid; 727#endif /* !PROCFS */ 728 729#ifdef LINUX 730#if defined(S390) || defined(S390X) 731 if (upeek(pid, PT_GPR2, &syscall_mode) < 0) 732 return -1; 733 if (syscall_mode != -ENOSYS){ 734 /* 735 * Since kernel version 2.5.44 the scno gets passed in gpr2. 736 */ 737 scno = syscall_mode; 738 } 739 else { 740 /* 741 * Old style of "passing" the scno via the SVC instruction. 742 */ 743 744 long opcode, offset_reg, tmp; 745 void * svc_addr; 746 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3, 747 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7, 748 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11, 749 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15}; 750 751 if (upeek(pid, PT_PSWADDR, &pc) < 0) 752 return -1; 753 opcode = ptrace(PTRACE_PEEKTEXT, pid, (char *)(pc-sizeof(long)), 0); 754 if (errno) 755 return -1; 756 757 /* 758 * We have to check if the SVC got executed directly or via an 759 * EXECUTE instruction. In case of EXECUTE it is necessary to do 760 * instruction decoding to derive the system call number. 761 * Unfortunately the opcode sizes of EXECUTE and SVC are differently, 762 * so that this doesn't work if a SVC opcode is part of an EXECUTE 763 * opcode. Since there is no way to find out the opcode size this 764 * is the best we can do... 765 */ 766 767 if ((opcode & 0xff00) == 0x0a00) { 768 /* SVC opcode */ 769 scno = opcode & 0xff; 770 } 771 else { 772 /* SVC got executed by EXECUTE instruction */ 773 774 /* 775 * Do instruction decoding of EXECUTE. If you really want to 776 * understand this, read the Principles of Operations. 777 */ 778 svc_addr = (void *) (opcode & 0xfff); 779 780 tmp = 0; 781 offset_reg = (opcode & 0x000f0000) >> 16; 782 if (offset_reg && (upeek(pid, gpr_offset[offset_reg], &tmp) < 0)) 783 return -1; 784 svc_addr += tmp; 785 786 tmp = 0; 787 offset_reg = (opcode & 0x0000f000) >> 12; 788 if (offset_reg && (upeek(pid, gpr_offset[offset_reg], &tmp) < 0)) 789 return -1; 790 svc_addr += tmp; 791 792 scno = ptrace(PTRACE_PEEKTEXT, pid, svc_addr, 0); 793 if (errno) 794 return -1; 795#if defined(S390X) 796 scno >>= 48; 797#else 798 scno >>= 16; 799#endif 800 tmp = 0; 801 offset_reg = (opcode & 0x00f00000) >> 20; 802 if (offset_reg && (upeek(pid, gpr_offset[offset_reg], &tmp) < 0)) 803 return -1; 804 805 scno = (scno | tmp) & 0xff; 806 } 807 } 808#elif defined (POWERPC) 809 if (upeek(pid, sizeof(unsigned long)*PT_R0, &scno) < 0) 810 return -1; 811 if (!(tcp->flags & TCB_INSYSCALL)) { 812 /* Check if we return from execve. */ 813 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) { 814 tcp->flags &= ~TCB_WAITEXECVE; 815 return 0; 816 } 817 } 818#elif defined (I386) 819 if (upeek(pid, 4*ORIG_EAX, &scno) < 0) 820 return -1; 821#elif defined (X86_64) 822 if (upeek(pid, 8*ORIG_RAX, &scno) < 0) 823 return -1; 824 825 if (!(tcp->flags & TCB_INSYSCALL)) { 826 static int currpers=-1; 827 long val; 828 829 /* Check CS register value. On x86-64 linux it is: 830 * 0x33 for long mode (64 bit) 831 * 0x23 for compatibility mode (32 bit) 832 * It takes only one ptrace and thus doesn't need 833 * to be cached. 834 */ 835 if (upeek(pid, 8*CS, &val) < 0) 836 return -1; 837 switch(val) 838 { 839 case 0x23: currpers = 1; break; 840 case 0x33: currpers = 0; break; 841 default: 842 fprintf(stderr, "Unknown value CS=0x%02X while " 843 "detecting personality of process " 844 "PID=%d\n", (int)val, pid); 845 currpers = current_personality; 846 break; 847 } 848#if 0 849 /* This version analyzes the opcode of a syscall instruction. 850 * (int 0x80 on i386 vs. syscall on x86-64) 851 * It works, but is too complicated. 852 */ 853 unsigned long val, rip, i; 854 855 if(upeek(pid, 8*RIP, &rip)<0) 856 perror("upeek(RIP)"); 857 858 /* sizeof(syscall) == sizeof(int 0x80) == 2 */ 859 rip-=2; 860 errno = 0; 861 862 call = ptrace(PTRACE_PEEKTEXT,pid,(char *)rip,0); 863 if (errno) 864 printf("ptrace_peektext failed: %s\n", 865 strerror(errno)); 866 switch (call & 0xffff) 867 { 868 /* x86-64: syscall = 0x0f 0x05 */ 869 case 0x050f: currpers = 0; break; 870 /* i386: int 0x80 = 0xcd 0x80 */ 871 case 0x80cd: currpers = 1; break; 872 default: 873 currpers = current_personality; 874 fprintf(stderr, 875 "Unknown syscall opcode (0x%04X) while " 876 "detecting personality of process " 877 "PID=%d\n", (int)call, pid); 878 break; 879 } 880#endif 881 if(currpers != current_personality) 882 { 883 char *names[]={"64 bit", "32 bit"}; 884 set_personality(currpers); 885 printf("[ Process PID=%d runs in %s mode. ]\n", 886 pid, names[current_personality]); 887 } 888 } 889#elif defined(IA64) 890# define IA64_PSR_IS ((long)1 << 34) 891 if (upeek (pid, PT_CR_IPSR, &psr) >= 0) 892 ia32 = (psr & IA64_PSR_IS) != 0; 893 if (!(tcp->flags & TCB_INSYSCALL)) { 894 if (ia32) { 895 if (upeek(pid, PT_R1, &scno) < 0) /* orig eax */ 896 return -1; 897 /* Check if we return from execve. */ 898 } else { 899 if (upeek (pid, PT_R15, &scno) < 0) 900 return -1; 901 } 902 } else { 903 /* syscall in progress */ 904 if (upeek (pid, PT_R8, &r8) < 0) 905 return -1; 906 if (upeek (pid, PT_R10, &r10) < 0) 907 return -1; 908 } 909 if (tcp->flags & TCB_WAITEXECVE) { 910 tcp->flags &= ~TCB_WAITEXECVE; 911 return 0; 912 } 913 914#elif defined (ARM) 915 { 916 long pc; 917 upeek(pid, 4*15, &pc); 918 umoven(tcp, pc-4, 4, (char *)&scno); 919 scno &= 0x000fffff; 920 } 921#elif defined (M68K) 922 if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0) 923 return -1; 924#elif defined (MIPS) 925 if (upeek(pid, REG_A3, &a3) < 0) 926 return -1; 927 928 if(!(tcp->flags & TCB_INSYSCALL)) { 929 if (upeek(pid, REG_V0, &scno) < 0) 930 return -1; 931 932 if (scno < 0 || scno > nsyscalls) { 933 if(a3 == 0 || a3 == -1) { 934 if(debug) 935 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno); 936 return 0; 937 } 938 } 939 } else { 940 if (upeek(pid, REG_V0, &r2) < 0) 941 return -1; 942 } 943#elif defined (ALPHA) 944 if (upeek(pid, REG_A3, &a3) < 0) 945 return -1; 946 947 if (!(tcp->flags & TCB_INSYSCALL)) { 948 if (upeek(pid, REG_R0, &scno) < 0) 949 return -1; 950 951 /* Check if we return from execve. */ 952 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) { 953 tcp->flags &= ~TCB_WAITEXECVE; 954 return 0; 955 } 956 957 /* 958 * Do some sanity checks to figure out if it's 959 * really a syscall entry 960 */ 961 if (scno < 0 || scno > nsyscalls) { 962 if (a3 == 0 || a3 == -1) { 963 if (debug) 964 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno); 965 return 0; 966 } 967 } 968 } 969 else { 970 if (upeek(pid, REG_R0, &r0) < 0) 971 return -1; 972 } 973#elif defined (SPARC) 974 /* Everything we need is in the current register set. */ 975 if (ptrace(PTRACE_GETREGS,pid,(char *)®s,0) < 0) 976 return -1; 977 978 /* If we are entering, then disassemble the syscall trap. */ 979 if (!(tcp->flags & TCB_INSYSCALL)) { 980 /* Retrieve the syscall trap instruction. */ 981 errno = 0; 982 trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0); 983 if (errno) 984 return -1; 985 986 /* Disassemble the trap to see what personality to use. */ 987 switch (trap) { 988 case 0x91d02010: 989 /* Linux/SPARC syscall trap. */ 990 set_personality(0); 991 break; 992 case 0x91d0206d: 993 /* Linux/SPARC64 syscall trap. */ 994 fprintf(stderr,"syscall: Linux/SPARC64 not supported yet\n"); 995 return -1; 996 case 0x91d02000: 997 /* SunOS syscall trap. (pers 1) */ 998 fprintf(stderr,"syscall: SunOS no support\n"); 999 return -1; 1000 case 0x91d02008: 1001 /* Solaris 2.x syscall trap. (per 2) */ 1002 set_personality(1); 1003 break; 1004 case 0x91d02009: 1005 /* NetBSD/FreeBSD syscall trap. */ 1006 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n"); 1007 return -1; 1008 case 0x91d02027: 1009 /* Solaris 2.x gettimeofday */ 1010 set_personality(1); 1011 break; 1012 default: 1013 /* Unknown syscall trap. */ 1014 if(tcp->flags & TCB_WAITEXECVE) { 1015 tcp->flags &= ~TCB_WAITEXECVE; 1016 return 0; 1017 } 1018 fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc); 1019 return -1; 1020 } 1021 1022 /* Extract the system call number from the registers. */ 1023 if (trap == 0x91d02027) 1024 scno = 156; 1025 else 1026 scno = regs.r_g1; 1027 if (scno == 0) { 1028 scno = regs.r_o0; 1029 memmove (®s.r_o0, ®s.r_o1, 7*sizeof(regs.r_o0)); 1030 } 1031 } 1032#elif defined(HPPA) 1033 if (upeek(pid, PT_GR20, &scno) < 0) 1034 return -1; 1035 if (!(tcp->flags & TCB_INSYSCALL)) { 1036 /* Check if we return from execve. */ 1037 if ((tcp->flags & TCB_WAITEXECVE)) { 1038 tcp->flags &= ~TCB_WAITEXECVE; 1039 return 0; 1040 } 1041 } 1042#elif defined(SH) 1043 /* 1044 * In the new syscall ABI, the system call number is in R3. 1045 */ 1046 if (upeek(pid, 4*(REG_REG0+3), &scno) < 0) 1047 return -1; 1048 1049 if (scno < 0) { 1050 /* Odd as it may seem, a glibc bug has been known to cause 1051 glibc to issue bogus negative syscall numbers. So for 1052 our purposes, make strace print what it *should* have been */ 1053 long correct_scno = (scno & 0xff); 1054 if (debug) 1055 fprintf(stderr, 1056 "Detected glibc bug: bogus system call number = %ld, " 1057 "correcting to %ld\n", 1058 scno, 1059 correct_scno); 1060 scno = correct_scno; 1061 } 1062 1063 1064 if (!(tcp->flags & TCB_INSYSCALL)) { 1065 /* Check if we return from execve. */ 1066 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) { 1067 tcp->flags &= ~TCB_WAITEXECVE; 1068 return 0; 1069 } 1070 } 1071#endif /* SH */ 1072#endif /* LINUX */ 1073#ifdef SUNOS4 1074 if (upeek(pid, uoff(u_arg[7]), &scno) < 0) 1075 return -1; 1076#elif defined(SH) 1077 /* new syscall ABI returns result in R0 */ 1078 if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0) 1079 return -1; 1080#endif 1081#ifdef USE_PROCFS 1082#ifdef HAVE_PR_SYSCALL 1083 scno = tcp->status.PR_SYSCALL; 1084#else /* !HAVE_PR_SYSCALL */ 1085#ifndef FREEBSD 1086 scno = tcp->status.PR_WHAT; 1087#else /* FREEBSD */ 1088 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1089 perror("pread"); 1090 return -1; 1091 } 1092 switch (regs.r_eax) { 1093 case SYS_syscall: 1094 case SYS___syscall: 1095 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int)); 1096 break; 1097 default: 1098 scno = regs.r_eax; 1099 break; 1100 } 1101#endif /* FREEBSD */ 1102#endif /* !HAVE_PR_SYSCALL */ 1103#endif /* USE_PROCFS */ 1104 if (!(tcp->flags & TCB_INSYSCALL)) 1105 tcp->scno = scno; 1106 return 1; 1107} 1108 1109 1110int 1111syscall_fixup(tcp) 1112struct tcb *tcp; 1113{ 1114#ifndef USE_PROCFS 1115 int pid = tcp->pid; 1116#else /* USE_PROCFS */ 1117 int scno = tcp->scno; 1118 1119 if (!(tcp->flags & TCB_INSYSCALL)) { 1120 if (tcp->status.PR_WHY != PR_SYSENTRY) { 1121 if ( 1122 scno == SYS_fork 1123#ifdef SYS_vfork 1124 || scno == SYS_vfork 1125#endif /* SYS_vfork */ 1126#ifdef SYS_fork1 1127 || scno == SYS_fork1 1128#endif /* SYS_fork1 */ 1129#ifdef SYS_forkall 1130 || scno == SYS_forkall 1131#endif /* SYS_forkall */ 1132#ifdef SYS_rfork1 1133 || scno == SYS_rfork1 1134#endif /* SYS_fork1 */ 1135#ifdef SYS_rforkall 1136 || scno == SYS_rforkall 1137#endif /* SYS_rforkall */ 1138 ) { 1139 /* We are returning in the child, fake it. */ 1140 tcp->status.PR_WHY = PR_SYSENTRY; 1141 trace_syscall(tcp); 1142 tcp->status.PR_WHY = PR_SYSEXIT; 1143 } 1144 else { 1145 fprintf(stderr, "syscall: missing entry\n"); 1146 tcp->flags |= TCB_INSYSCALL; 1147 } 1148 } 1149 } 1150 else { 1151 if (tcp->status.PR_WHY != PR_SYSEXIT) { 1152 fprintf(stderr, "syscall: missing exit\n"); 1153 tcp->flags &= ~TCB_INSYSCALL; 1154 } 1155 } 1156#endif /* USE_PROCFS */ 1157#ifdef SUNOS4 1158 if (!(tcp->flags & TCB_INSYSCALL)) { 1159 if (scno == 0) { 1160 fprintf(stderr, "syscall: missing entry\n"); 1161 tcp->flags |= TCB_INSYSCALL; 1162 } 1163 } 1164 else { 1165 if (scno != 0) { 1166 if (debug) { 1167 /* 1168 * This happens when a signal handler 1169 * for a signal which interrupted a 1170 * a system call makes another system call. 1171 */ 1172 fprintf(stderr, "syscall: missing exit\n"); 1173 } 1174 tcp->flags &= ~TCB_INSYSCALL; 1175 } 1176 } 1177#endif /* SUNOS4 */ 1178#ifdef LINUX 1179#if defined (I386) 1180 if (upeek(pid, 4*EAX, &eax) < 0) 1181 return -1; 1182 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) { 1183 if (debug) 1184 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax); 1185 return 0; 1186 } 1187#elif defined (X86_64) 1188 if (upeek(pid, 8*RAX, &rax) < 0) 1189 return -1; 1190 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) { 1191 if (debug) 1192 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax); 1193 return 0; 1194 } 1195#elif defined (S390) || defined (S390X) 1196 if (upeek(pid, PT_GPR2, &gpr2) < 0) 1197 return -1; 1198 if (syscall_mode != -ENOSYS) 1199 syscall_mode = tcp->scno; 1200 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) { 1201 if (debug) 1202 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2); 1203 return 0; 1204 } 1205#elif defined (POWERPC) 1206# define SO_MASK 0x10000000 1207 if (upeek(pid, sizeof(unsigned long)*PT_CCR, &flags) < 0) 1208 return -1; 1209 if (upeek(pid, sizeof(unsigned long)*PT_R3, &result) < 0) 1210 return -1; 1211 if (flags & SO_MASK) 1212 result = -result; 1213#elif defined (M68K) 1214 if (upeek(pid, 4*PT_D0, &d0) < 0) 1215 return -1; 1216 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) { 1217 if (debug) 1218 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0); 1219 return 0; 1220 } 1221#elif defined (ARM) 1222 if (upeek(pid, 4*0, (long *)&r0) < 0) 1223 return -1; 1224 if ( 0 && r0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) { 1225 if (debug) 1226 fprintf(stderr, "stray syscall exit: d0 = %ld\n", r0); 1227 return 0; 1228 } 1229#elif defined (HPPA) 1230 if (upeek(pid, PT_GR28, &r28) < 0) 1231 return -1; 1232#elif defined(IA64) 1233 if (upeek(pid, PT_R10, &r10) < 0) 1234 return -1; 1235 if (upeek(pid, PT_R8, &r8) < 0) 1236 return -1; 1237 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) { 1238 if (debug) 1239 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8); 1240 return 0; 1241 } 1242#endif 1243#endif /* LINUX */ 1244 return 1; 1245} 1246 1247int 1248get_error(tcp) 1249struct tcb *tcp; 1250{ 1251 int u_error = 0; 1252#ifdef LINUX 1253#if defined(S390) || defined(S390X) 1254 if (gpr2 && (unsigned) -gpr2 < nerrnos) { 1255 tcp->u_rval = -1; 1256 u_error = -gpr2; 1257 } 1258 else { 1259 tcp->u_rval = gpr2; 1260 u_error = 0; 1261 } 1262#else /* !S390 && !S390X */ 1263#ifdef I386 1264 if (eax < 0 && -eax < nerrnos) { 1265 tcp->u_rval = -1; 1266 u_error = -eax; 1267 } 1268 else { 1269 tcp->u_rval = eax; 1270 u_error = 0; 1271 } 1272#else /* !I386 */ 1273#ifdef X86_64 1274 if (rax < 0 && -rax < nerrnos) { 1275 tcp->u_rval = -1; 1276 u_error = -rax; 1277 } 1278 else { 1279 tcp->u_rval = rax; 1280 u_error = 0; 1281 } 1282#else 1283#ifdef IA64 1284 if (ia32) { 1285 int err; 1286 1287 err = (int)r8; 1288 if (err < 0 && -err < nerrnos) { 1289 tcp->u_rval = -1; 1290 u_error = -err; 1291 } 1292 else { 1293 tcp->u_rval = err; 1294 u_error = 0; 1295 } 1296 } else { 1297 if (r10) { 1298 tcp->u_rval = -1; 1299 u_error = r8; 1300 } else { 1301 tcp->u_rval = r8; 1302 u_error = 0; 1303 } 1304 } 1305#else /* !IA64 */ 1306#ifdef MIPS 1307 if (a3) { 1308 tcp->u_rval = -1; 1309 u_error = r2; 1310 } else { 1311 tcp->u_rval = r2; 1312 u_error = 0; 1313 } 1314#else 1315#ifdef POWERPC 1316 if (result && (unsigned) -result < nerrnos) { 1317 tcp->u_rval = -1; 1318 u_error = -result; 1319 } 1320 else { 1321 tcp->u_rval = result; 1322 u_error = 0; 1323 } 1324#else /* !POWERPC */ 1325#ifdef M68K 1326 if (d0 && (unsigned) -d0 < nerrnos) { 1327 tcp->u_rval = -1; 1328 u_error = -d0; 1329 } 1330 else { 1331 tcp->u_rval = d0; 1332 u_error = 0; 1333 } 1334#else /* !M68K */ 1335#ifdef ARM 1336 if (r0 && (unsigned) -r0 < nerrnos) { 1337 tcp->u_rval = -1; 1338 u_error = -r0; 1339 } 1340 else { 1341 tcp->u_rval = r0; 1342 u_error = 0; 1343 } 1344#else /* !ARM */ 1345#ifdef ALPHA 1346 if (a3) { 1347 tcp->u_rval = -1; 1348 u_error = r0; 1349 } 1350 else { 1351 tcp->u_rval = r0; 1352 u_error = 0; 1353 } 1354#else /* !ALPHA */ 1355#ifdef SPARC 1356 if (regs.r_psr & PSR_C) { 1357 tcp->u_rval = -1; 1358 u_error = regs.r_o0; 1359 } 1360 else { 1361 tcp->u_rval = regs.r_o0; 1362 u_error = 0; 1363 } 1364#else /* !SPARC */ 1365#ifdef HPPA 1366 if (r28 && (unsigned) -r28 < nerrnos) { 1367 tcp->u_rval = -1; 1368 u_error = -r28; 1369 } 1370 else { 1371 tcp->u_rval = r28; 1372 u_error = 0; 1373 } 1374#else 1375#ifdef SH 1376 /* interpret R0 as return value or error number */ 1377 if (r0 && (unsigned) -r0 < nerrnos) { 1378 tcp->u_rval = -1; 1379 u_error = -r0; 1380 } 1381 else { 1382 tcp->u_rval = r0; 1383 u_error = 0; 1384 } 1385#endif /* SH */ 1386#endif /* HPPA */ 1387#endif /* SPARC */ 1388#endif /* ALPHA */ 1389#endif /* ARM */ 1390#endif /* M68K */ 1391#endif /* POWERPC */ 1392#endif /* MIPS */ 1393#endif /* IA64 */ 1394#endif /* X86_64 */ 1395#endif /* I386 */ 1396#endif /* S390 || S390X */ 1397#endif /* LINUX */ 1398#ifdef SUNOS4 1399 /* get error code from user struct */ 1400 if (upeek(pid, uoff(u_error), &u_error) < 0) 1401 return -1; 1402 u_error >>= 24; /* u_error is a char */ 1403 1404 /* get system call return value */ 1405 if (upeek(pid, uoff(u_rval1), &tcp->u_rval) < 0) 1406 return -1; 1407#endif /* SUNOS4 */ 1408#ifdef SVR4 1409#ifdef SPARC 1410 /* Judicious guessing goes a long way. */ 1411 if (tcp->status.pr_reg[R_PSR] & 0x100000) { 1412 tcp->u_rval = -1; 1413 u_error = tcp->status.pr_reg[R_O0]; 1414 } 1415 else { 1416 tcp->u_rval = tcp->status.pr_reg[R_O0]; 1417 u_error = 0; 1418 } 1419#endif /* SPARC */ 1420#ifdef I386 1421 /* Wanna know how to kill an hour single-stepping? */ 1422 if (tcp->status.PR_REG[EFL] & 0x1) { 1423 tcp->u_rval = -1; 1424 u_error = tcp->status.PR_REG[EAX]; 1425 } 1426 else { 1427 tcp->u_rval = tcp->status.PR_REG[EAX]; 1428#ifdef HAVE_LONG_LONG 1429 tcp->u_lrval = 1430 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) + 1431 tcp->status.PR_REG[EAX]; 1432#endif 1433 u_error = 0; 1434 } 1435#endif /* I386 */ 1436#ifdef X86_64 1437 /* Wanna know how to kill an hour single-stepping? */ 1438 if (tcp->status.PR_REG[EFLAGS] & 0x1) { 1439 tcp->u_rval = -1; 1440 u_error = tcp->status.PR_REG[RAX]; 1441 } 1442 else { 1443 tcp->u_rval = tcp->status.PR_REG[RAX]; 1444 u_error = 0; 1445 } 1446#endif /* X86_64 */ 1447#ifdef MIPS 1448 if (tcp->status.pr_reg[CTX_A3]) { 1449 tcp->u_rval = -1; 1450 u_error = tcp->status.pr_reg[CTX_V0]; 1451 } 1452 else { 1453 tcp->u_rval = tcp->status.pr_reg[CTX_V0]; 1454 u_error = 0; 1455 } 1456#endif /* MIPS */ 1457#endif /* SVR4 */ 1458#ifdef FREEBSD 1459 if (regs.r_eflags & PSL_C) { 1460 tcp->u_rval = -1; 1461 u_error = regs.r_eax; 1462 } else { 1463 tcp->u_rval = regs.r_eax; 1464 tcp->u_lrval = 1465 ((unsigned long long) regs.r_edx << 32) + regs.r_eax; 1466 u_error = 0; 1467 } 1468#endif /* FREEBSD */ 1469 tcp->u_error = u_error; 1470 return 1; 1471} 1472 1473int 1474force_result(tcp, error, rval) 1475 struct tcb *tcp; 1476 int error; 1477 long rval; 1478{ 1479#ifdef LINUX 1480#if defined(S390) || defined(S390X) 1481 gpr2 = error ? -error : rval; 1482 if (upeek(tcp->pid, PT_GPR2, &gpr2) < 0) 1483 return -1; 1484 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0) 1485 return -1; 1486#else /* !S390 && !S390X */ 1487#ifdef I386 1488 eax = error ? -error : rval; 1489 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0) 1490 return -1; 1491#else /* !I386 */ 1492#ifdef X86_64 1493 rax = error ? -error : rval; 1494 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 4), rax) < 0) 1495 return -1; 1496#else 1497#ifdef IA64 1498 if (ia32) { 1499 r8 = error ? -error : rval; 1500 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0) 1501 return -1; 1502 } 1503 else { 1504 if (error) { 1505 r8 = error; 1506 r10 = -1; 1507 } 1508 else { 1509 r8 = rval; 1510 r10 = 0; 1511 } 1512 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 || 1513 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0) 1514 return -1; 1515 } 1516#else /* !IA64 */ 1517#ifdef MIPS 1518 if (error) { 1519 r2 = error; 1520 a3 = -1; 1521 } 1522 else { 1523 r2 = rval; 1524 a3 = 0; 1525 } 1526 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || 1527 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0) 1528 return -1; 1529#else 1530#ifdef POWERPC 1531 if (upeek(tcp->pid, sizeof(unsigned long)*PT_CCR, &flags) < 0) 1532 return -1; 1533 if (error) { 1534 flags |= SO_MASK; 1535 result = error; 1536 } 1537 else { 1538 flags &= ~SO_MASK; 1539 result = rval; 1540 } 1541 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 || 1542 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0) 1543 return -1; 1544#else /* !POWERPC */ 1545#ifdef M68K 1546 d0 = error ? -error : rval; 1547 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0) 1548 return -1; 1549#else /* !M68K */ 1550#ifdef ARM 1551 r0 = error ? -error : rval; 1552 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), r0) < 0) 1553 return -1; 1554#else /* !ARM */ 1555#ifdef ALPHA 1556 if (error) { 1557 a3 = -1; 1558 r0 = error; 1559 } 1560 else { 1561 a3 = 0; 1562 r0 = rval; 1563 } 1564 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 || 1565 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0) 1566 return -1; 1567#else /* !ALPHA */ 1568#ifdef SPARC 1569 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 1570 return -1; 1571 if (error) { 1572 regs.r_psr |= PSR_C; 1573 regs.r_o0 = error; 1574 } 1575 else { 1576 regs.r_psr &= ~PSR_C; 1577 regs.r_o0 = rval; 1578 } 1579 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0) 1580 return -1; 1581#else /* !SPARC */ 1582#ifdef HPPA 1583 r28 = error ? -error : rval; 1584 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0) 1585 return -1; 1586#else 1587#ifdef SH 1588 r0 = error ? -error : rval; 1589 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0) 1590 return -1; 1591#endif /* SH */ 1592#endif /* HPPA */ 1593#endif /* SPARC */ 1594#endif /* ALPHA */ 1595#endif /* ARM */ 1596#endif /* M68K */ 1597#endif /* POWERPC */ 1598#endif /* MIPS */ 1599#endif /* IA64 */ 1600#endif /* X86_64 */ 1601#endif /* I386 */ 1602#endif /* S390 || S390X */ 1603#endif /* LINUX */ 1604#ifdef SUNOS4 1605 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error), 1606 error << 24) < 0 || 1607 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0) 1608 return -1; 1609#endif /* SUNOS4 */ 1610#ifdef SVR4 1611 /* XXX no clue */ 1612 return -1; 1613#endif /* SVR4 */ 1614#ifdef FREEBSD 1615 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1616 perror("pread"); 1617 return -1; 1618 } 1619 if (error) { 1620 regs.r_eflags |= PSL_C; 1621 regs.r_eax = error; 1622 } 1623 else { 1624 regs.r_eflags &= ~PSL_C; 1625 regs.r_eax = rval; 1626 } 1627 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) { 1628 perror("pwrite"); 1629 return -1; 1630 } 1631#endif /* FREEBSD */ 1632 1633 /* All branches reach here on success (only). */ 1634 tcp->u_error = error; 1635 tcp->u_rval = rval; 1636 return 0; 1637} 1638 1639int syscall_enter(tcp) 1640struct tcb *tcp; 1641{ 1642#ifndef USE_PROCFS 1643 int pid = tcp->pid; 1644#endif /* !USE_PROCFS */ 1645#ifdef LINUX 1646#if defined(S390) || defined(S390X) 1647 { 1648 int i; 1649 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1650 tcp->u_nargs = sysent[tcp->scno].nargs; 1651 else 1652 tcp->u_nargs = MAX_ARGS; 1653 for (i = 0; i < tcp->u_nargs; i++) { 1654 if (upeek(pid,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0) 1655 return -1; 1656 } 1657 } 1658#elif defined (ALPHA) 1659 { 1660 int i; 1661 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1662 tcp->u_nargs = sysent[tcp->scno].nargs; 1663 else 1664 tcp->u_nargs = MAX_ARGS; 1665 for (i = 0; i < tcp->u_nargs; i++) { 1666 /* WTA: if scno is out-of-bounds this will bomb. Add range-check 1667 * for scno somewhere above here! 1668 */ 1669 if (upeek(pid, REG_A0+i, &tcp->u_arg[i]) < 0) 1670 return -1; 1671 } 1672 } 1673#elif defined (IA64) 1674 { 1675 if (!ia32) { 1676 unsigned long *out0, *rbs_end, cfm, sof, sol, i; 1677 /* be backwards compatible with kernel < 2.4.4... */ 1678# ifndef PT_RBS_END 1679# define PT_RBS_END PT_AR_BSP 1680# endif 1681 1682 if (upeek(pid, PT_RBS_END, (long *) &rbs_end) < 0) 1683 return -1; 1684 if (upeek(pid, PT_CFM, (long *) &cfm) < 0) 1685 return -1; 1686 1687 sof = (cfm >> 0) & 0x7f; 1688 sol = (cfm >> 7) & 0x7f; 1689 out0 = ia64_rse_skip_regs(rbs_end, -sof + sol); 1690 1691 if (tcp->scno >= 0 && tcp->scno < nsyscalls 1692 && sysent[tcp->scno].nargs != -1) 1693 tcp->u_nargs = sysent[tcp->scno].nargs; 1694 else 1695 tcp->u_nargs = MAX_ARGS; 1696 for (i = 0; i < tcp->u_nargs; ++i) { 1697 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i), 1698 sizeof(long), (char *) &tcp->u_arg[i]) < 0) 1699 return -1; 1700 } 1701 } else { 1702 int i; 1703 1704 if (/* EBX = out0 */ 1705 upeek(pid, PT_R11, (long *) &tcp->u_arg[0]) < 0 1706 /* ECX = out1 */ 1707 || upeek(pid, PT_R9, (long *) &tcp->u_arg[1]) < 0 1708 /* EDX = out2 */ 1709 || upeek(pid, PT_R10, (long *) &tcp->u_arg[2]) < 0 1710 /* ESI = out3 */ 1711 || upeek(pid, PT_R14, (long *) &tcp->u_arg[3]) < 0 1712 /* EDI = out4 */ 1713 || upeek(pid, PT_R15, (long *) &tcp->u_arg[4]) < 0 1714 /* EBP = out5 */ 1715 || upeek(pid, PT_R13, (long *) &tcp->u_arg[5]) < 0) 1716 return -1; 1717 1718 for (i = 0; i < 6; ++i) 1719 /* truncate away IVE sign-extension */ 1720 tcp->u_arg[i] &= 0xffffffff; 1721 1722 if (tcp->scno >= 0 && tcp->scno < nsyscalls 1723 && sysent[tcp->scno].nargs != -1) 1724 tcp->u_nargs = sysent[tcp->scno].nargs; 1725 else 1726 tcp->u_nargs = 5; 1727 } 1728 } 1729#elif defined (MIPS) 1730 { 1731 long sp; 1732 int i, nargs; 1733 1734 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1735 nargs = tcp->u_nargs = sysent[tcp->scno].nargs; 1736 else 1737 nargs = tcp->u_nargs = MAX_ARGS; 1738 if(nargs > 4) { 1739 if(upeek(pid, REG_SP, &sp) < 0) 1740 return -1; 1741 for(i = 0; i < 4; i++) { 1742 if (upeek(pid, REG_A0 + i, &tcp->u_arg[i])<0) 1743 return -1; 1744 } 1745 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]), 1746 (char *)(tcp->u_arg + 4)); 1747 } else { 1748 for(i = 0; i < nargs; i++) { 1749 if (upeek(pid, REG_A0 + i, &tcp->u_arg[i]) < 0) 1750 return -1; 1751 } 1752 } 1753 } 1754#elif defined (POWERPC) 1755#ifndef PT_ORIG_R3 1756#define PT_ORIG_R3 34 1757#endif 1758 { 1759 int i; 1760 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1761 tcp->u_nargs = sysent[tcp->scno].nargs; 1762 else 1763 tcp->u_nargs = MAX_ARGS; 1764 for (i = 0; i < tcp->u_nargs; i++) { 1765 if (upeek(pid, (i==0) ? 1766 (sizeof(unsigned long)*PT_ORIG_R3) : 1767 ((i+PT_R3)*sizeof(unsigned long)), 1768 &tcp->u_arg[i]) < 0) 1769 return -1; 1770 } 1771 } 1772#elif defined (SPARC) 1773 { 1774 int i; 1775 1776 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1777 tcp->u_nargs = sysent[tcp->scno].nargs; 1778 else 1779 tcp->u_nargs = MAX_ARGS; 1780 for (i = 0; i < tcp->u_nargs; i++) 1781 tcp->u_arg[i] = *((®s.r_o0) + i); 1782 } 1783#elif defined (HPPA) 1784 { 1785 int i; 1786 1787 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1788 tcp->u_nargs = sysent[tcp->scno].nargs; 1789 else 1790 tcp->u_nargs = MAX_ARGS; 1791 for (i = 0; i < tcp->u_nargs; i++) { 1792 if (upeek(pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0) 1793 return -1; 1794 } 1795 } 1796#elif defined(SH) 1797 { 1798 int i; 1799 static int syscall_regs[] = { 1800 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7, 1801 REG_REG0, REG_REG0+1, REG_REG0+2 1802 }; 1803 1804 tcp->u_nargs = sysent[tcp->scno].nargs; 1805 for (i = 0; i < tcp->u_nargs; i++) { 1806 if (upeek(pid, 4*syscall_regs[i], &tcp->u_arg[i]) < 0) 1807 return -1; 1808 } 1809 } 1810#elif defined(X86_64) 1811 { 1812 int i; 1813 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = { 1814 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */ 1815 {RBX,RCX,RDX,RDX,RSI,RDI,RBP} /* i386 ABI */ 1816 }; 1817 1818 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1819 tcp->u_nargs = sysent[tcp->scno].nargs; 1820 else 1821 tcp->u_nargs = MAX_ARGS; 1822 for (i = 0; i < tcp->u_nargs; i++) { 1823 if (upeek(pid, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0) 1824 return -1; 1825 } 1826 } 1827#else /* Other architecture (like i386) (32bits specific) */ 1828 { 1829 int i; 1830 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1831 tcp->u_nargs = sysent[tcp->scno].nargs; 1832 else 1833 tcp->u_nargs = MAX_ARGS; 1834 for (i = 0; i < tcp->u_nargs; i++) { 1835 if (upeek(pid, i*4, &tcp->u_arg[i]) < 0) 1836 return -1; 1837 } 1838 } 1839#endif 1840#endif /* LINUX */ 1841#ifdef SUNOS4 1842 { 1843 int i; 1844 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1845 tcp->u_nargs = sysent[tcp->scno].nargs; 1846 else 1847 tcp->u_nargs = MAX_ARGS; 1848 for (i = 0; i < tcp->u_nargs; i++) { 1849 struct user *u; 1850 1851 if (upeek(pid, uoff(u_arg[0]) + 1852 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0) 1853 return -1; 1854 } 1855 } 1856#endif /* SUNOS4 */ 1857#ifdef SVR4 1858#ifdef MIPS 1859 /* 1860 * SGI is broken: even though it has pr_sysarg, it doesn't 1861 * set them on system call entry. Get a clue. 1862 */ 1863 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1864 tcp->u_nargs = sysent[tcp->scno].nargs; 1865 else 1866 tcp->u_nargs = tcp->status.pr_nsysarg; 1867 if (tcp->u_nargs > 4) { 1868 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0], 1869 4*sizeof(tcp->u_arg[0])); 1870 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16, 1871 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4)); 1872 } 1873 else { 1874 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0], 1875 tcp->u_nargs*sizeof(tcp->u_arg[0])); 1876 } 1877#elif UNIXWARE >= 2 1878 /* 1879 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit 1880 */ 1881 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1882 tcp->u_nargs = sysent[tcp->scno].nargs; 1883 else 1884 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg; 1885 umoven(tcp, tcp->status.PR_REG[UESP] + 4, 1886 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg); 1887#elif defined (HAVE_PR_SYSCALL) 1888 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1889 tcp->u_nargs = sysent[tcp->scno].nargs; 1890 else 1891 tcp->u_nargs = tcp->status.pr_nsysarg; 1892 { 1893 int i; 1894 for (i = 0; i < tcp->u_nargs; i++) 1895 tcp->u_arg[i] = tcp->status.pr_sysarg[i]; 1896 } 1897#elif defined (I386) 1898 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1) 1899 tcp->u_nargs = sysent[tcp->scno].nargs; 1900 else 1901 tcp->u_nargs = 5; 1902 umoven(tcp, tcp->status.PR_REG[UESP] + 4, 1903 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg); 1904#else 1905 I DONT KNOW WHAT TO DO 1906#endif /* !HAVE_PR_SYSCALL */ 1907#endif /* SVR4 */ 1908#ifdef FREEBSD 1909 if (tcp->scno >= 0 && tcp->scno < nsyscalls && 1910 sysent[tcp->scno].nargs > tcp->status.val) 1911 tcp->u_nargs = sysent[tcp->scno].nargs; 1912 else 1913 tcp->u_nargs = tcp->status.val; 1914 if (tcp->u_nargs < 0) 1915 tcp->u_nargs = 0; 1916 if (tcp->u_nargs > MAX_ARGS) 1917 tcp->u_nargs = MAX_ARGS; 1918 switch(regs.r_eax) { 1919 case SYS___syscall: 1920 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long), 1921 regs.r_esp + sizeof(int) + sizeof(quad_t)); 1922 break; 1923 case SYS_syscall: 1924 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long), 1925 regs.r_esp + 2 * sizeof(int)); 1926 break; 1927 default: 1928 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long), 1929 regs.r_esp + sizeof(int)); 1930 break; 1931 } 1932#endif /* FREEBSD */ 1933 return 1; 1934} 1935 1936int 1937trace_syscall(tcp) 1938struct tcb *tcp; 1939{ 1940 int sys_res; 1941 struct timeval tv; 1942 int res; 1943 1944 /* Measure the exit time as early as possible to avoid errors. */ 1945 if (dtime && (tcp->flags & TCB_INSYSCALL)) 1946 gettimeofday(&tv, NULL); 1947 1948 res = get_scno(tcp); 1949 if (res != 1) 1950 return res; 1951 1952 res = syscall_fixup(tcp); 1953 if (res != 1) 1954 return res; 1955 1956 if (tcp->flags & TCB_INSYSCALL) { 1957 long u_error; 1958 res = get_error(tcp); 1959 if (res != 1) 1960 return res; 1961 1962 internal_syscall(tcp); 1963 if (tcp->scno >= 0 && tcp->scno < nsyscalls && 1964 !(qual_flags[tcp->scno] & QUAL_TRACE)) { 1965 tcp->flags &= ~TCB_INSYSCALL; 1966 return 0; 1967 } 1968 1969 if (tcp->flags & TCB_REPRINT) { 1970 printleader(tcp); 1971 tprintf("<... "); 1972 if (tcp->scno >= nsyscalls || tcp->scno < 0) 1973 tprintf("syscall_%lu", tcp->scno); 1974 else 1975 tprintf("%s", sysent[tcp->scno].sys_name); 1976 tprintf(" resumed> "); 1977 } 1978 1979 if (cflag && tcp->scno < nsyscalls && tcp->scno >= 0) { 1980 call_count[tcp->scno]++; 1981 if (tcp->u_error) 1982 error_count[tcp->scno]++; 1983 tv_sub(&tv, &tv, &tcp->etime); 1984#ifdef LINUX 1985 if (tv_cmp(&tv, &tcp->dtime) > 0) { 1986 static struct timeval one_tick = 1987 { 0, 1000000 / HZ }; 1988 1989 if (tv_nz(&tcp->dtime)) 1990 tv = tcp->dtime; 1991 else if (tv_cmp(&tv, &one_tick) > 0) { 1992 if (tv_cmp(&shortest, &one_tick) < 0) 1993 tv = shortest; 1994 else 1995 tv = one_tick; 1996 } 1997 } 1998#endif /* LINUX */ 1999 if (tv_cmp(&tv, &shortest) < 0) 2000 shortest = tv; 2001 tv_add(&tv_count[tcp->scno], 2002 &tv_count[tcp->scno], &tv); 2003 tcp->flags &= ~TCB_INSYSCALL; 2004 return 0; 2005 } 2006 2007 if (tcp->scno >= nsyscalls || tcp->scno < 0 2008 || (qual_flags[tcp->scno] & QUAL_RAW)) 2009 sys_res = printargs(tcp); 2010 else { 2011 if (not_failing_only && tcp->u_error) 2012 return 0; /* ignore failed syscalls */ 2013 sys_res = (*sysent[tcp->scno].sys_func)(tcp); 2014 } 2015 u_error = tcp->u_error; 2016 tprintf(") "); 2017 tabto(acolumn); 2018 if (tcp->scno >= nsyscalls || tcp->scno < 0 || 2019 qual_flags[tcp->scno] & QUAL_RAW) { 2020 if (u_error) 2021 tprintf("= -1 (errno %ld)", u_error); 2022 else 2023 tprintf("= %#lx", tcp->u_rval); 2024 } 2025 else if (!(sys_res & RVAL_NONE) && u_error) { 2026 switch (u_error) { 2027#ifdef LINUX 2028 case ERESTARTSYS: 2029 tprintf("= ? ERESTARTSYS (To be restarted)"); 2030 break; 2031 case ERESTARTNOINTR: 2032 tprintf("= ? ERESTARTNOINTR (To be restarted)"); 2033 break; 2034 case ERESTARTNOHAND: 2035 tprintf("= ? ERESTARTNOHAND (To be restarted)"); 2036 break; 2037#endif /* LINUX */ 2038 default: 2039 tprintf("= -1 "); 2040 if (u_error < 0) 2041 tprintf("E??? (errno %ld)", u_error); 2042 else if (u_error < nerrnos) 2043 tprintf("%s (%s)", errnoent[u_error], 2044 strerror(u_error)); 2045 else 2046 tprintf("ERRNO_%ld (%s)", u_error, 2047 strerror(u_error)); 2048 break; 2049 } 2050 } 2051 else { 2052 if (sys_res & RVAL_NONE) 2053 tprintf("= ?"); 2054 else { 2055 switch (sys_res & RVAL_MASK) { 2056 case RVAL_HEX: 2057 tprintf("= %#lx", tcp->u_rval); 2058 break; 2059 case RVAL_OCTAL: 2060 tprintf("= %#lo", tcp->u_rval); 2061 break; 2062 case RVAL_UDECIMAL: 2063 tprintf("= %lu", tcp->u_rval); 2064 break; 2065 case RVAL_DECIMAL: 2066 tprintf("= %ld", tcp->u_rval); 2067 break; 2068#ifdef HAVE_LONG_LONG 2069 case RVAL_LHEX: 2070 tprintf("= %#llx", tcp->u_lrval); 2071 break; 2072 case RVAL_LOCTAL: 2073 tprintf("= %#llo", tcp->u_lrval); 2074 break; 2075 case RVAL_LUDECIMAL: 2076 tprintf("= %llu", tcp->u_lrval); 2077 break; 2078 case RVAL_LDECIMAL: 2079 tprintf("= %lld", tcp->u_lrval); 2080 break; 2081#endif 2082 default: 2083 fprintf(stderr, 2084 "invalid rval format\n"); 2085 break; 2086 } 2087 } 2088 if ((sys_res & RVAL_STR) && tcp->auxstr) 2089 tprintf(" (%s)", tcp->auxstr); 2090 } 2091 if (dtime) { 2092 tv_sub(&tv, &tv, &tcp->etime); 2093 tprintf(" <%ld.%06ld>", 2094 (long) tv.tv_sec, (long) tv.tv_usec); 2095 } 2096 printtrailer(tcp); 2097 2098 dumpio(tcp); 2099 if (fflush(tcp->outf) == EOF) 2100 return -1; 2101 tcp->flags &= ~TCB_INSYSCALL; 2102 return 0; 2103 } 2104 2105 /* Entering system call */ 2106 res = syscall_enter(tcp); 2107 if (res != 1) 2108 return res; 2109 2110 switch (tcp->scno + NR_SYSCALL_BASE) { 2111#ifdef LINUX 2112#if !defined (ALPHA) && !defined(SPARC) && !defined(MIPS) && !defined(HPPA) && !defined(X86_64) 2113 case SYS_socketcall: 2114 decode_subcall(tcp, SYS_socket_subcall, 2115 SYS_socket_nsubcalls, deref_style); 2116 break; 2117 case SYS_ipc: 2118 decode_subcall(tcp, SYS_ipc_subcall, 2119 SYS_ipc_nsubcalls, shift_style); 2120 break; 2121#endif /* !ALPHA && !MIPS && !SPARC && !HPPA && !X86_64 */ 2122#ifdef SPARC 2123 case SYS_socketcall: 2124 sparc_socket_decode (tcp); 2125 break; 2126#endif 2127#endif /* LINUX */ 2128#ifdef SVR4 2129#ifdef SYS_pgrpsys_subcall 2130 case SYS_pgrpsys: 2131 decode_subcall(tcp, SYS_pgrpsys_subcall, 2132 SYS_pgrpsys_nsubcalls, shift_style); 2133 break; 2134#endif /* SYS_pgrpsys_subcall */ 2135#ifdef SYS_sigcall_subcall 2136 case SYS_sigcall: 2137 decode_subcall(tcp, SYS_sigcall_subcall, 2138 SYS_sigcall_nsubcalls, mask_style); 2139 break; 2140#endif /* SYS_sigcall_subcall */ 2141 case SYS_msgsys: 2142 decode_subcall(tcp, SYS_msgsys_subcall, 2143 SYS_msgsys_nsubcalls, shift_style); 2144 break; 2145 case SYS_shmsys: 2146 decode_subcall(tcp, SYS_shmsys_subcall, 2147 SYS_shmsys_nsubcalls, shift_style); 2148 break; 2149 case SYS_semsys: 2150 decode_subcall(tcp, SYS_semsys_subcall, 2151 SYS_semsys_nsubcalls, shift_style); 2152 break; 2153#if 0 /* broken */ 2154 case SYS_utssys: 2155 decode_subcall(tcp, SYS_utssys_subcall, 2156 SYS_utssys_nsubcalls, shift_style); 2157 break; 2158#endif 2159 case SYS_sysfs: 2160 decode_subcall(tcp, SYS_sysfs_subcall, 2161 SYS_sysfs_nsubcalls, shift_style); 2162 break; 2163 case SYS_spcall: 2164 decode_subcall(tcp, SYS_spcall_subcall, 2165 SYS_spcall_nsubcalls, shift_style); 2166 break; 2167#ifdef SYS_context_subcall 2168 case SYS_context: 2169 decode_subcall(tcp, SYS_context_subcall, 2170 SYS_context_nsubcalls, shift_style); 2171 break; 2172#endif /* SYS_context_subcall */ 2173#ifdef SYS_door_subcall 2174 case SYS_door: 2175 decode_subcall(tcp, SYS_door_subcall, 2176 SYS_door_nsubcalls, door_style); 2177 break; 2178#endif /* SYS_door_subcall */ 2179#ifdef SYS_kaio_subcall 2180 case SYS_kaio: 2181 decode_subcall(tcp, SYS_kaio_subcall, 2182 SYS_kaio_nsubcalls, shift_style); 2183 break; 2184#endif 2185#endif /* SVR4 */ 2186#ifdef FREEBSD 2187 case SYS_msgsys: 2188 case SYS_shmsys: 2189 case SYS_semsys: 2190 decode_subcall(tcp, 0, 0, table_style); 2191 break; 2192#endif 2193#ifdef SUNOS4 2194 case SYS_semsys: 2195 decode_subcall(tcp, SYS_semsys_subcall, 2196 SYS_semsys_nsubcalls, shift_style); 2197 break; 2198 case SYS_msgsys: 2199 decode_subcall(tcp, SYS_msgsys_subcall, 2200 SYS_msgsys_nsubcalls, shift_style); 2201 break; 2202 case SYS_shmsys: 2203 decode_subcall(tcp, SYS_shmsys_subcall, 2204 SYS_shmsys_nsubcalls, shift_style); 2205 break; 2206#endif 2207 } 2208 2209 internal_syscall(tcp); 2210 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) { 2211 tcp->flags |= TCB_INSYSCALL; 2212 return 0; 2213 } 2214 2215 if (cflag) { 2216 gettimeofday(&tcp->etime, NULL); 2217 tcp->flags |= TCB_INSYSCALL; 2218 return 0; 2219 } 2220 2221 printleader(tcp); 2222 tcp->flags &= ~TCB_REPRINT; 2223 tcp_last = tcp; 2224 if (tcp->scno >= nsyscalls || tcp->scno < 0) 2225 tprintf("syscall_%lu(", tcp->scno); 2226 else 2227 tprintf("%s(", sysent[tcp->scno].sys_name); 2228 if (tcp->scno >= nsyscalls || tcp->scno < 0 || 2229 ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit)) 2230 sys_res = printargs(tcp); 2231 else 2232 sys_res = (*sysent[tcp->scno].sys_func)(tcp); 2233 if (fflush(tcp->outf) == EOF) 2234 return -1; 2235 tcp->flags |= TCB_INSYSCALL; 2236 /* Measure the entrance time as late as possible to avoid errors. */ 2237 if (dtime) 2238 gettimeofday(&tcp->etime, NULL); 2239 return sys_res; 2240} 2241 2242int 2243printargs(tcp) 2244struct tcb *tcp; 2245{ 2246 if (entering(tcp)) { 2247 int i; 2248 2249 for (i = 0; i < tcp->u_nargs; i++) 2250 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]); 2251 } 2252 return 0; 2253} 2254 2255long 2256getrval2(tcp) 2257struct tcb *tcp; 2258{ 2259 long val = -1; 2260 2261#ifdef LINUX 2262#ifdef SPARC 2263 struct regs regs; 2264 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0) 2265 return -1; 2266 val = regs.r_o1; 2267#endif /* SPARC */ 2268#endif /* LINUX */ 2269 2270#ifdef SUNOS4 2271 if (upeek(tcp->pid, uoff(u_rval2), &val) < 0) 2272 return -1; 2273#endif /* SUNOS4 */ 2274 2275#ifdef SVR4 2276#ifdef SPARC 2277 val = tcp->status.PR_REG[R_O1]; 2278#endif /* SPARC */ 2279#ifdef I386 2280 val = tcp->status.PR_REG[EDX]; 2281#endif /* I386 */ 2282#ifdef X86_64 2283 val = tcp->status.PR_REG[RDX]; 2284#endif /* X86_64 */ 2285#ifdef MIPS 2286 val = tcp->status.PR_REG[CTX_V1]; 2287#endif /* MIPS */ 2288#endif /* SVR4 */ 2289#ifdef FREEBSD 2290 struct reg regs; 2291 pread(tcp->pfd_reg, ®s, sizeof(regs), 0); 2292 val = regs.r_edx; 2293#endif 2294 return val; 2295} 2296 2297/* 2298 * Apparently, indirect system calls have already be converted by ptrace(2), 2299 * so if you see "indir" this program has gone astray. 2300 */ 2301int 2302sys_indir(tcp) 2303struct tcb *tcp; 2304{ 2305 int i, scno, nargs; 2306 2307 if (entering(tcp)) { 2308 if ((scno = tcp->u_arg[0]) > nsyscalls) { 2309 fprintf(stderr, "Bogus syscall: %u\n", scno); 2310 return 0; 2311 } 2312 nargs = sysent[scno].nargs; 2313 tprintf("%s", sysent[scno].sys_name); 2314 for (i = 0; i < nargs; i++) 2315 tprintf(", %#lx", tcp->u_arg[i+1]); 2316 } 2317 return 0; 2318} 2319 2320static int 2321time_cmp(a, b) 2322void *a; 2323void *b; 2324{ 2325 return -tv_cmp(&tv_count[*((int *) a)], &tv_count[*((int *) b)]); 2326} 2327 2328static int 2329syscall_cmp(a, b) 2330void *a; 2331void *b; 2332{ 2333 return strcmp(sysent[*((int *) a)].sys_name, 2334 sysent[*((int *) b)].sys_name); 2335} 2336 2337static int 2338count_cmp(a, b) 2339void *a; 2340void *b; 2341{ 2342 int m = call_count[*((int *) a)], n = call_count[*((int *) b)]; 2343 2344 return (m < n) ? 1 : (m > n) ? -1 : 0; 2345} 2346 2347static int (*sortfun)(); 2348static struct timeval overhead = { -1, -1 }; 2349 2350void 2351set_sortby(sortby) 2352char *sortby; 2353{ 2354 if (strcmp(sortby, "time") == 0) 2355 sortfun = time_cmp; 2356 else if (strcmp(sortby, "calls") == 0) 2357 sortfun = count_cmp; 2358 else if (strcmp(sortby, "name") == 0) 2359 sortfun = syscall_cmp; 2360 else if (strcmp(sortby, "nothing") == 0) 2361 sortfun = NULL; 2362 else { 2363 fprintf(stderr, "invalid sortby: `%s'\n", sortby); 2364 exit(1); 2365 } 2366} 2367 2368void set_overhead(n) 2369int n; 2370{ 2371 overhead.tv_sec = n / 1000000; 2372 overhead.tv_usec = n % 1000000; 2373} 2374 2375void 2376call_summary(outf) 2377FILE *outf; 2378{ 2379 int i, j; 2380 int call_cum, error_cum; 2381 struct timeval tv_cum, dtv; 2382 double percent; 2383 char *dashes = "-------------------------"; 2384 char error_str[16]; 2385 2386 call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0; 2387 if (overhead.tv_sec == -1) { 2388 tv_mul(&overhead, &shortest, 8); 2389 tv_div(&overhead, &overhead, 10); 2390 } 2391 for (i = 0; i < nsyscalls; i++) { 2392 sorted_count[i] = i; 2393 if (call_count[i] == 0) 2394 continue; 2395 tv_mul(&dtv, &overhead, call_count[i]); 2396 tv_sub(&tv_count[i], &tv_count[i], &dtv); 2397 call_cum += call_count[i]; 2398 error_cum += error_count[i]; 2399 tv_add(&tv_cum, &tv_cum, &tv_count[i]); 2400 } 2401 if (sortfun) 2402 qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun); 2403 fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n", 2404 "% time", "seconds", "usecs/call", 2405 "calls", "errors", "syscall"); 2406 fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n", 2407 dashes, dashes, dashes, dashes, dashes, dashes); 2408 for (i = 0; i < nsyscalls; i++) { 2409 j = sorted_count[i]; 2410 if (call_count[j] == 0) 2411 continue; 2412 tv_div(&dtv, &tv_count[j], call_count[j]); 2413 if (error_count[j]) 2414 sprintf(error_str, "%d", error_count[j]); 2415 else 2416 error_str[0] = '\0'; 2417 percent = 100.0*tv_float(&tv_count[j])/tv_float(&tv_cum); 2418 fprintf(outf, "%6.2f %4ld.%06ld %11ld %9d %9.9s %s\n", 2419 percent, (long) tv_count[j].tv_sec, 2420 (long) tv_count[j].tv_usec, 2421 (long) 1000000 * dtv.tv_sec + dtv.tv_usec, 2422 call_count[j], error_str, sysent[j].sys_name); 2423 } 2424 fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n", 2425 dashes, dashes, dashes, dashes, dashes, dashes); 2426 if (error_cum) 2427 sprintf(error_str, "%d", error_cum); 2428 else 2429 error_str[0] = '\0'; 2430 fprintf(outf, "%6.6s %4ld.%06ld %11.11s %9d %9.9s %s\n", 2431 "100.00", (long) tv_cum.tv_sec, (long) tv_cum.tv_usec, "", 2432 call_cum, error_str, "total"); 2433} 2434