defs.h revision ee9d435275fd7abf736992f84b5053ee16ec4fc7
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 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $Id$ 30 */ 31 32#ifdef linux 33#include <features.h> 34#endif 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40/* configuration section */ 41#ifndef MAX_QUALS 42#if defined(linux) && defined(MIPS) 43#define MAX_QUALS 4999 /* maximum number of syscalls, signals, etc. */ 44#else 45#define MAX_QUALS 2048 /* maximum number of syscalls, signals, etc. */ 46#endif 47#endif 48#ifndef DEFAULT_STRLEN 49#define DEFAULT_STRLEN 32 /* default maximum # of bytes printed in 50 `printstr', change with `-s' switch */ 51#endif 52#ifndef DEFAULT_ACOLUMN 53#define DEFAULT_ACOLUMN 40 /* default alignment column for results */ 54#endif 55#ifndef MAX_ARGS 56#define MAX_ARGS 32 /* maximum number of args to a syscall */ 57#endif 58#ifndef DEFAULT_SORTBY 59#define DEFAULT_SORTBY "time" /* default sorting method for call profiling */ 60#endif 61 62#include <sys/types.h> 63#include <unistd.h> 64#include <stdlib.h> 65#include <stdio.h> 66#include <ctype.h> 67#include <string.h> 68#include <time.h> 69#include <sys/time.h> 70#include <errno.h> 71 72#ifdef STDC_HEADERS 73#include <stddef.h> 74#endif /* STDC_HEADERS */ 75 76#ifdef HAVE_SIGINFO_T 77#include <signal.h> 78#endif 79 80#if defined(LINUX) 81# if defined(SPARC) 82# define LINUXSPARC 83# endif 84# if defined(ALPHA) 85# define LINUX_64BIT 86# endif 87# if defined(X86_64) 88# define LINUX_X86_64 89# endif 90#endif 91 92#if defined(SVR4) || defined(FREEBSD) 93#define USE_PROCFS 94#else 95#undef USE_PROCFS 96#endif 97 98#ifdef FREEBSD 99#ifndef I386 100#error "FreeBSD support is only for i386 arch right now." 101#endif 102#include <machine/psl.h> 103#include <machine/reg.h> 104#include <sys/syscall.h> 105#endif 106 107#ifdef USE_PROCFS 108#include <sys/procfs.h> 109#ifdef HAVE_MP_PROCFS 110#include <sys/uio.h> 111#endif 112#ifdef FREEBSD 113#include <sys/pioctl.h> 114#endif /* FREEBSD */ 115#else /* !USE_PROCFS */ 116#if (defined(LINUXSPARC) || defined (LINUX_X86_64)) && defined(__GLIBC__) 117#include <sys/ptrace.h> 118#else 119/* Work around awkward prototype in ptrace.h. */ 120#define ptrace xptrace 121#include <sys/ptrace.h> 122#undef ptrace 123#ifdef POWERPC 124#define __KERNEL__ 125#include <asm/ptrace.h> 126#undef __KERNEL__ 127/* TEMP */ 128#define UESP PT_R1 129#define EIP PT_NIP 130#define EAX PT_R3 131#define ORIG_EAX PT_ORIG_R3 132#endif 133#ifdef __STDC__ 134#ifdef LINUX 135extern long ptrace(int, int, char *, long); 136#else /* !LINUX */ 137extern int ptrace(int, int, char *, int, ...); 138#endif /* !LINUX */ 139#else /* !__STDC__ */ 140extern int ptrace(); 141#endif /* !__STDC__ */ 142#endif /* !LINUXSPARC */ 143#endif /* !SVR4 */ 144 145#ifdef LINUX 146#if !defined(__GLIBC__) 147#define PTRACE_PEEKUSER PTRACE_PEEKUSR 148#define PTRACE_POKEUSER PTRACE_POKEUSR 149#endif 150#ifdef ALPHA 151# define REG_R0 0 152# define REG_A0 16 153# define REG_A3 19 154# define REG_FP 30 155# define REG_PC 64 156#endif /* ALPHA */ 157#ifdef MIPS 158# define REG_V0 2 159# define REG_A0 4 160# define REG_A3 7 161# define REG_SP 29 162# define REG_EPC 64 163#endif /* MIPS */ 164#ifdef HPPA 165# define PT_GR20 (20*4) 166# define PT_GR26 (26*4) 167# define PT_GR28 (28*4) 168# define PT_IAOQ0 (106*4) 169# define PT_IAOQ1 (107*4) 170#endif /* HPPA */ 171#endif /* LINUX */ 172 173#define SUPPORTED_PERSONALITIES 1 174#define DEFAULT_PERSONALITY 0 175 176#ifdef LINUXSPARC 177#include <linux/a.out.h> 178#include <asm/psr.h> 179#undef SUPPORTED_PERSONALITIES 180#define SUPPORTED_PERSONALITIES 2 181#endif /* LINUXSPARC */ 182 183#ifdef X86_64 184#undef SUPPORTED_PERSONALITIES 185#define SUPPORTED_PERSONALITIES 2 186#endif 187 188#ifdef SVR4 189#ifdef HAVE_MP_PROCFS 190extern int mp_ioctl (int f, int c, void *a, int s); 191#define IOCTL(f,c,a) mp_ioctl (f, c, a, sizeof *a) 192#define IOCTL_STATUS(t) \ 193 pread (t->pfd_stat, &t->status, sizeof t->status, 0) 194#define IOCTL_WSTOP(t) \ 195 (IOCTL (t->pfd, PCWSTOP, (char *)NULL) < 0 ? -1 : \ 196 IOCTL_STATUS (t)) 197#define PR_WHY pr_lwp.pr_why 198#define PR_WHAT pr_lwp.pr_what 199#define PR_REG pr_lwp.pr_context.uc_mcontext.gregs 200#define PR_FLAGS pr_lwp.pr_flags 201#define PR_SYSCALL pr_lwp.pr_syscall 202#define PR_INFO pr_lwp.pr_info 203#define PIOCSTIP PCSTOP 204#define PIOCSET PCSET 205#define PIOCRESET PCRESET 206#define PIOCSTRACE PCSTRACE 207#define PIOCSFAULT PCSFAULT 208#define PIOCWSTOP PCWSTOP 209#define PIOCSTOP PCSTOP 210#define PIOCSENTRY PCSENTRY 211#define PIOCSEXIT PCSEXIT 212#define PIOCRUN PCRUN 213#else 214#define IOCTL ioctl 215#define IOCTL_STATUS(t) ioctl (t->pfd, PIOCSTATUS, &t->status) 216#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status) 217#define PR_WHY pr_why 218#define PR_WHAT pr_what 219#define PR_REG pr_reg 220#define PR_FLAGS pr_flags 221#define PR_SYSCALL pr_syscall 222#define PR_INFO pr_info 223#endif 224#endif 225#ifdef FREEBSD 226#define IOCTL ioctl 227#define IOCTL_STATUS(t) ioctl (t->pfd, PIOCSTATUS, &t->status) 228#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWAIT, &t->status) 229#define PIOCRUN PIOCCONT 230#define PIOCWSTOP PIOCWAIT 231#define PR_WHY why 232#define PR_WHAT val 233#define PR_FLAGS state 234/* from /usr/src/sys/miscfs/procfs/procfs_vnops.c, 235 status.state = 0 for running, 1 for stopped */ 236#define PR_ASLEEP 1 237#define PR_SYSENTRY S_SCE 238#define PR_SYSEXIT S_SCX 239#define PR_SIGNALLED S_SIG 240#define PR_FAULTED S_CORE 241#endif 242 243/* Trace Control Block */ 244struct tcb { 245 short flags; /* See below for TCB_ values */ 246 int pid; /* Process Id of this entry */ 247 long scno; /* System call number */ 248 int u_nargs; /* System call arguments */ 249 long u_arg[MAX_ARGS]; /* System call arguments */ 250 int u_error; /* Error code */ 251 long u_rval; /* (first) return value */ 252#ifdef HAVE_LONG_LONG 253 long long u_lrval; /* long long return value */ 254#endif 255 FILE *outf; /* Output file for this process */ 256 const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */ 257 struct timeval stime; /* System time usage as of last process wait */ 258 struct timeval dtime; /* Delta for system time usage */ 259 struct timeval etime; /* Syscall entry time */ 260 /* Support for tracing forked processes */ 261 struct tcb *parent; /* Parent of this process */ 262 int nchildren; /* # of traced children */ 263 int waitpid; /* pid(s) this process is waiting for */ 264 /* (1st arg of wait4()) */ 265 long baddr; /* `Breakpoint' address */ 266 long inst[2]; /* Instructions on above */ 267 int pfd; /* proc file descriptor */ 268#ifdef SVR4 269#ifdef HAVE_MP_PROCFS 270 int pfd_stat; 271 int pfd_as; 272 pstatus_t status; 273#else 274 prstatus_t status; /* procfs status structure */ 275#endif 276#endif 277#ifdef FREEBSD 278 struct procfs_status status; 279 int pfd_reg; 280 int pfd_status; 281#endif 282}; 283 284/* TCB flags */ 285#define TCB_STARTUP 00001 /* We have just begun ptracing this process */ 286#define TCB_INUSE 00002 /* This table entry is in use */ 287#define TCB_INSYSCALL 00004 /* A system call is in progress */ 288#define TCB_ATTACHED 00010 /* Process is not our own child */ 289#define TCB_EXITING 00020 /* As far as we know, this process is exiting */ 290#define TCB_SUSPENDED 00040 /* Process has done a wait(4), that can 291 not be allowed to complete just now */ 292#define TCB_BPTSET 00100 /* "Breakpoint" set after fork(2) */ 293#define TCB_SIGTRAPPED 00200 /* Process wanted to block SIGTRAP */ 294#define TCB_FOLLOWFORK 00400 /* Process should have forks followed */ 295#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */ 296#ifdef LINUX 297# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) 298# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */ 299# endif 300#endif /* LINUX */ 301 302/* qualifier flags */ 303#define QUAL_TRACE 0001 /* this system call should be traced */ 304#define QUAL_ABBREV 0002 /* abbreviate the structures of this syscall */ 305#define QUAL_VERBOSE 0004 /* decode the structures of this syscall */ 306#define QUAL_RAW 0010 /* print all args in hex for this syscall */ 307#define QUAL_SIGNAL 0020 /* report events with this signal */ 308#define QUAL_FAULT 0040 /* report events with this fault */ 309#define QUAL_READ 0100 /* dump data read on this file descriptor */ 310#define QUAL_WRITE 0200 /* dump data written to this file descriptor */ 311 312#define entering(tcp) (!((tcp)->flags & TCB_INSYSCALL)) 313#define exiting(tcp) ((tcp)->flags & TCB_INSYSCALL) 314#define syserror(tcp) ((tcp)->u_error != 0) 315#define verbose(tcp) (qual_flags[(tcp)->scno] & QUAL_VERBOSE) 316#define abbrev(tcp) (qual_flags[(tcp)->scno] & QUAL_ABBREV) 317#define waiting_parent(tcp) \ 318 (tcp->parent && \ 319 (tcp->parent->flags & TCB_SUSPENDED) && \ 320 (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) 321 322struct xlat { 323 int val; 324 char *str; 325}; 326 327/* Format of syscall return values */ 328#define RVAL_DECIMAL 000 /* decimal format */ 329#define RVAL_HEX 001 /* hex format */ 330#define RVAL_OCTAL 002 /* octal format */ 331#define RVAL_UDECIMAL 003 /* unsigned decimal format */ 332#define RVAL_LDECIMAL 004 /* long decimal format */ 333#define RVAL_LHEX 005 /* long hex format */ 334#define RVAL_LOCTAL 006 /* long octal format */ 335#define RVAL_LUDECIMAL 007 /* long unsigned decimal format */ 336#define RVAL_MASK 007 /* mask for these values */ 337 338#define RVAL_STR 010 /* Print `auxstr' field after return val */ 339#define RVAL_NONE 020 /* Print nothing */ 340 341#ifndef offsetof 342#define offsetof(type, member) (((char *) &(((type *) NULL)->member)) - \ 343 ((char *) (type *) NULL)) 344#endif /* !offsetof */ 345 346/* get offset of member within a user struct */ 347#define uoff(member) offsetof(struct user, member) 348 349#define TRACE_FILE 001 /* Trace file-related syscalls. */ 350#define TRACE_IPC 002 /* Trace IPC-related syscalls. */ 351#define TRACE_NETWORK 004 /* Trace network-related syscalls. */ 352#define TRACE_PROCESS 010 /* Trace process-related syscalls. */ 353#define TRACE_SIGNAL 020 /* Trace signal-related syscalls. */ 354 355extern struct tcb **tcbtab; 356extern int qual_flags[]; 357extern int debug, followfork, followvfork; 358extern int rflag, tflag, dtime, cflag, xflag, qflag; 359extern int acolumn; 360extern char *outfname; 361extern unsigned int nprocs, tcbtabsize; 362extern int max_strlen; 363extern struct tcb *tcp_last; 364 365#ifdef __STDC__ 366#define P(args) args 367#else 368#define P(args) () 369#endif 370 371extern int set_personality P((int personality)); 372extern char *xlookup P((struct xlat *, int)); 373extern struct tcb *alloctcb P((int)); 374extern void droptcb P((struct tcb *)); 375 376extern void set_sortby P((char *)); 377extern void set_overhead P((int)); 378extern void qualify P((char *)); 379extern void newoutf P((struct tcb *)); 380extern int get_scno P((struct tcb *)); 381extern int trace_syscall P((struct tcb *)); 382extern void printxval P((struct xlat *, int, char *)); 383extern int printargs P((struct tcb *)); 384extern int addflags P((struct xlat *, int)); 385extern int printflags P((struct xlat *, int)); 386extern int umoven P((struct tcb *, long, int, char *)); 387extern int umovestr P((struct tcb *, long, int, char *)); 388extern int upeek P((int, long, long *)); 389extern void dumpiov P((struct tcb *, int, long)); 390extern void dumpstr P((struct tcb *, long, int)); 391extern void string_quote P((char *str)); 392extern void printstr P((struct tcb *, long, int)); 393extern void printnum P((struct tcb *, long, char *)); 394extern void printpath P((struct tcb *, long)); 395extern void printpathn P((struct tcb *, long, int)); 396extern void printtv P((struct tcb *, long)); 397#ifdef HAVE_SIGINFO_T 398extern void printsiginfo P((siginfo_t *, int)); 399#endif 400extern void printsock P((struct tcb *, long, int)); 401extern void print_sock_optmgmt P((struct tcb *, long, int)); 402extern void printrusage P((struct tcb *, long)); 403extern int clearbpt P((struct tcb *)); 404extern int setbpt P((struct tcb *)); 405extern int sigishandled P((struct tcb *, int)); 406extern void printcall P((struct tcb *)); 407extern char *signame P((int)); 408extern void printsignal P((int)); 409extern void printleader P((struct tcb *)); 410extern void printtrailer P((struct tcb *)); 411extern void tabto P((int)); 412extern void call_summary P((FILE *)); 413extern void fake_execve P((struct tcb *, char *, char *[], char *[])); 414extern void printtv32 P((struct tcb*, long)); 415extern void tprint_iov P((struct tcb *, int, long)); 416 417#ifdef LINUX 418extern int internal_clone P((struct tcb *)); 419#endif 420extern int internal_fork P((struct tcb *)); 421extern int internal_exec P((struct tcb *)); 422extern int internal_wait P((struct tcb *)); 423extern int internal_exit P((struct tcb *)); 424 425extern char *ioctl_lookup P((long)); 426extern int ioctl_decode P((struct tcb *, long, long)); 427extern int term_ioctl P((struct tcb *, long, long)); 428extern int sock_ioctl P((struct tcb *, long, long)); 429extern int proc_ioctl P((struct tcb *, int, int)); 430extern int stream_ioctl P((struct tcb *, int, int)); 431 432extern void tv_tv P((struct timeval *, int, int)); 433extern int tv_nz P((struct timeval *)); 434extern int tv_cmp P((struct timeval *, struct timeval *)); 435extern double tv_float P((struct timeval *)); 436extern void tv_add P((struct timeval *, struct timeval *, struct timeval *)); 437extern void tv_sub P((struct timeval *, struct timeval *, struct timeval *)); 438extern void tv_mul P((struct timeval *, struct timeval *, int)); 439extern void tv_div P((struct timeval *, struct timeval *, int)); 440 441#ifdef SUNOS4 442extern int fixvfork P((struct tcb *)); 443#endif 444#if !(defined(LINUX) && !defined(SPARC)) 445extern long getrval2 P((struct tcb *)); 446#endif 447#ifdef USE_PROCFS 448extern int proc_open P((struct tcb *tcp, int attaching)); 449#endif 450 451#define umove(pid, addr, objp) \ 452 umoven((pid), (addr), sizeof *(objp), (char *) (objp)) 453 454#ifdef __STDC__ 455#ifdef __GNUC__ 456extern void tprintf(const char *fmt, ...) 457 __attribute__ ((format (printf, 1, 2))); 458#else 459extern void tprintf(const char *fmt, ...); 460#endif 461#else 462extern void tprintf(); 463#endif 464 465#ifndef HAVE_STRERROR 466const char *strerror P((int)); 467#endif 468#ifndef HAVE_STRSIGNAL 469const char *strsignal P((int)); 470#endif 471 472extern int current_personality; 473 474struct sysent { 475 int nargs; 476 int sys_flags; 477 int (*sys_func)(); 478 char *sys_name; 479}; 480 481extern struct sysent *sysent; 482extern int nsyscalls; 483 484extern char **errnoent; 485extern int nerrnos; 486 487struct ioctlent { 488 char *doth; 489 char *symbol; 490 unsigned long code; 491}; 492 493extern struct ioctlent *ioctlent; 494extern int nioctlent; 495 496extern char **signalent; 497extern int nsignals; 498 499extern struct ioctlent *ioctlent; 500extern int nioctlents; 501extern char **signalent; 502extern int nsignals; 503 504extern struct ioctlent ioctlent0[]; 505extern int nioctlents0; 506extern char *signalent0[]; 507extern int nsignals0; 508 509#if SUPPORTED_PERSONALITIES >= 2 510extern struct ioctlent ioctlent1[]; 511extern int nioctlents1; 512extern char *signalent1[]; 513extern int nsignals1; 514#endif /* SUPPORTED_PERSONALITIES >= 2 */ 515 516#if SUPPORTED_PERSONALITIES >= 3 517extern struct ioctlent ioctlent2[]; 518extern int nioctlents2; 519extern char *signalent2[]; 520extern int nsignals2; 521#endif /* SUPPORTED_PERSONALITIES >= 3 */ 522 523#if FREEBSD 524/* ARRGH! off_t args are aligned on 64 bit boundaries! */ 525#define ALIGN64(tcp,arg) \ 526do { \ 527 if (arg % 2) \ 528 memmove (&tcp->u_arg[arg], &tcp->u_arg[arg + 1], \ 529 (tcp->u_nargs - arg - 1) * sizeof tcp->u_arg[0]); \ 530} while (0) 531#else 532#define ALIGN64(tcp,arg) do { } while (0) 533#endif 534 535#if HAVE_LONG_LONG 536 537/* _l refers to the lower numbered u_arg, 538 * _h refers to the higher numbered u_arg 539 */ 540 541#if HAVE_LITTLE_ENDIAN_LONG_LONG 542#define LONG_LONG(_l,_h) \ 543 ((long long)((unsigned long long)(unsigned)(_l) | ((unsigned long long)(_h)<<32))) 544#else 545#define LONG_LONG(_l,_h) \ 546 ((long long)((unsigned long long)(unsigned)(_h) | ((unsigned long long)(_l)<<32))) 547#endif 548#endif 549 550#ifdef IA64 551extern long ia32; 552#endif 553 554extern int not_failing_only; 555