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