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