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