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