]> granicus.if.org Git - strace/blobdiff - defs.h
2005-05-31 Dmitry V. Levin <ldv@altlinux.org>
[strace] / defs.h
diff --git a/defs.h b/defs.h
index 0a6bd639b8aed5d2ef401d3ec5ed701edc993d42..e32e3ed9fb35098ff95a1573d6bb8eba3881e865 100644 (file)
--- a/defs.h
+++ b/defs.h
  *     $Id$
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifdef linux
 #include <features.h>
 #endif
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
+#ifdef _LARGEFILE64_SOURCE
+/* This is the macro everything checks before using foo64 names.  */
+# ifndef _LFS64_LARGEFILE
+#  define _LFS64_LARGEFILE 1
+# endif
 #endif
 
 /* configuration section */
 #ifndef MAX_QUALS
-#if defined(linux) && defined(MIPS)
-#define MAX_QUALS      4999    /* maximum number of syscalls, signals, etc. */
+#if defined(LINUX) && defined(MIPS)
+#define MAX_QUALS      5000    /* maximum number of syscalls, signals, etc. */
 #else
 #define MAX_QUALS      2048    /* maximum number of syscalls, signals, etc. */
 #endif
-#ifndef MAX_PROCS
-#define MAX_PROCS      64      /* maximum number of processes tracable */
 #endif
 #ifndef DEFAULT_STRLEN
 #define DEFAULT_STRLEN 32      /* default maximum # of bytes printed in
@@ -67,6 +72,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include <time.h>
 #include <sys/time.h>
 #include <errno.h>
 
 #include <stddef.h>
 #endif /* STDC_HEADERS */
 
+#ifdef HAVE_SIGINFO_T
+#include <signal.h>
+#endif
+
 #if defined(LINUX)
-#  if defined(SPARC)
+#  if defined(SPARC) || defined(SPARC64)
 #     define LINUXSPARC
 #  endif
 #  if defined(ALPHA)
 #     define LINUX_64BIT
 #  endif
-#endif 
+#  if defined(X86_64)
+#     define LINUX_X86_64
+#  endif
+#endif
 
-#ifdef SVR4
+#if defined(SVR4) || defined(FREEBSD)
+#define USE_PROCFS
+#else
+#undef USE_PROCFS
+#endif
+
+#ifdef FREEBSD
+#ifndef I386
+#error "FreeBSD support is only for i386 arch right now."
+#endif
+#include <machine/psl.h>
+#include <machine/reg.h>
+#include <sys/syscall.h>
+#endif
+
+#ifdef USE_PROCFS
 #include <sys/procfs.h>
 #ifdef HAVE_MP_PROCFS
 #include <sys/uio.h>
 #endif
-#else /* !SVR4 */
-#if defined(LINUXSPARC) && defined(__GLIBC__)
+#ifdef FREEBSD
+#include <sys/pioctl.h>
+#endif /* FREEBSD */
+#else /* !USE_PROCFS */
+#if (defined(LINUXSPARC) || defined (LINUX_X86_64)) && defined(__GLIBC__)
 #include <sys/ptrace.h>
 #else
 /* Work around awkward prototype in ptrace.h. */
 #define __KERNEL__
 #include <asm/ptrace.h>
 #undef __KERNEL__
-/* TEMP */
-#define UESP   PT_R1
-#define EIP    PT_NIP
-#define EAX    PT_R3
-#define ORIG_EAX PT_ORIG_R3
 #endif
 #ifdef __STDC__
 #ifdef LINUX
@@ -137,6 +163,29 @@ extern int ptrace();
 #  define REG_SP 29
 #  define REG_EPC 64
 #endif /* MIPS */
+#ifdef HPPA
+#  define PT_GR20 (20*4)
+#  define PT_GR26 (26*4)
+#  define PT_GR28 (28*4)
+#  define PT_IAOQ0 (106*4)
+#  define PT_IAOQ1 (107*4)
+#endif /* HPPA */
+#ifdef SH64
+   /* SH64 Linux - this code assumes the following kernel API for system calls:
+          PC           Offset 0
+          System Call  Offset 16 (actually, (syscall no.) | (0x1n << 16),
+                       where n = no. of parameters.
+          Other regs   Offset 24+
+
+          On entry:    R2-7 = parameters 1-6 (as many as necessary)
+          On return:   R9   = result. */
+
+   /* Offset for peeks of registers */
+#  define REG_OFFSET         (24)
+#  define REG_GENERAL(x)     (8*(x)+REG_OFFSET)
+#  define REG_PC             (0*8)
+#  define REG_SYSCALL        (2*8)
+#endif /* SH64 */
 #endif /* LINUX */
 
 #define SUPPORTED_PERSONALITIES 1
@@ -146,9 +195,17 @@ extern int ptrace();
 #include <linux/a.out.h>
 #include <asm/psr.h>
 #undef  SUPPORTED_PERSONALITIES
+#if defined(SPARC64)
+#define SUPPORTED_PERSONALITIES 3
+#else
 #define SUPPORTED_PERSONALITIES 2
+#endif /* SPARC64 */
 #endif /* LINUXSPARC */
 
+#ifdef X86_64
+#undef SUPPORTED_PERSONALITIES
+#define SUPPORTED_PERSONALITIES 2
+#endif
 
 #ifdef SVR4
 #ifdef HAVE_MP_PROCFS
@@ -157,12 +214,14 @@ extern int mp_ioctl (int f, int c, void *a, int s);
 #define IOCTL_STATUS(t) \
         pread (t->pfd_stat, &t->status, sizeof t->status, 0)
 #define IOCTL_WSTOP(t)                                         \
-       (IOCTL (t->pfd, PCWSTOP, NULL) < 0 ? -1 :               \
+       (IOCTL (t->pfd, PCWSTOP, (char *)NULL) < 0 ? -1 :               \
         IOCTL_STATUS (t))
 #define PR_WHY         pr_lwp.pr_why
 #define PR_WHAT                pr_lwp.pr_what
 #define PR_REG         pr_lwp.pr_context.uc_mcontext.gregs
 #define PR_FLAGS       pr_lwp.pr_flags
+#define PR_SYSCALL     pr_lwp.pr_syscall
+#define PR_INFO                pr_lwp.pr_info
 #define PIOCSTIP       PCSTOP
 #define PIOCSET                PCSET
 #define PIOCRESET      PCRESET
@@ -176,12 +235,31 @@ extern int mp_ioctl (int f, int c, void *a, int s);
 #else
 #define IOCTL          ioctl
 #define IOCTL_STATUS(t)        ioctl (t->pfd, PIOCSTATUS, &t->status)
-#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status)   
+#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWSTOP, &t->status)
 #define PR_WHY         pr_why
 #define PR_WHAT                pr_what
 #define PR_REG         pr_reg
 #define PR_FLAGS       pr_flags
+#define PR_SYSCALL     pr_syscall
+#define PR_INFO                pr_info
+#endif
 #endif
+#ifdef FREEBSD
+#define IOCTL          ioctl
+#define IOCTL_STATUS(t)        ioctl (t->pfd, PIOCSTATUS, &t->status)
+#define IOCTL_WSTOP(t) ioctl (t->pfd, PIOCWAIT, &t->status)
+#define PIOCRUN         PIOCCONT
+#define PIOCWSTOP       PIOCWAIT
+#define PR_WHY         why
+#define PR_WHAT                val
+#define PR_FLAGS       state
+/* from /usr/src/sys/miscfs/procfs/procfs_vnops.c,
+   status.state = 0 for running, 1 for stopped */
+#define PR_ASLEEP      1
+#define PR_SYSENTRY     S_SCE
+#define PR_SYSEXIT      S_SCX
+#define PR_SIGNALLED    S_SIG
+#define PR_FAULTED      S_CORE
 #endif
 
 /* Trace Control Block */
@@ -193,8 +271,11 @@ struct tcb {
        long u_arg[MAX_ARGS];   /* System call arguments */
        int u_error;            /* Error code */
        long u_rval;            /* (first) return value */
+#ifdef HAVE_LONG_LONG
+       long long u_lrval;      /* long long return value */
+#endif
        FILE *outf;             /* Output file for this process */
-       char *auxstr;           /* Auxiliary info from syscall (see RVAL_STR) */
+       const char *auxstr;     /* Auxiliary info from syscall (see RVAL_STR) */
        struct timeval stime;   /* System time usage as of last process wait */
        struct timeval dtime;   /* Delta for system time usage */
        struct timeval etime;   /* Syscall entry time */
@@ -202,6 +283,12 @@ struct tcb {
        struct tcb *parent;     /* Parent of this process */
        int nchildren;          /* # of traced children */
        int waitpid;            /* pid(s) this process is waiting for */
+       int nzombies;           /* # of formerly traced children now dead */
+#ifdef LINUX
+       int nclone_threads;     /* # of nchildren with CLONE_THREAD */
+       int nclone_detached;    /* # of nchildren with CLONE_DETACHED */
+       int nclone_waiting;     /* clone threads in wait4 (TCB_SUSPENDED) */
+#endif
                                /* (1st arg of wait4()) */
        long baddr;             /* `Breakpoint' address */
        long inst[2];           /* Instructions on above */
@@ -215,6 +302,11 @@ struct tcb {
        prstatus_t status;      /* procfs status structure */
 #endif
 #endif
+#ifdef FREEBSD
+       struct procfs_status status;
+       int pfd_reg;
+       int pfd_status;
+#endif
 };
 
 /* TCB flags */
@@ -230,9 +322,29 @@ struct tcb {
 #define TCB_FOLLOWFORK 00400   /* Process should have forks followed */
 #define TCB_REPRINT    01000   /* We should reprint this syscall on exit */
 #ifdef LINUX
-#if defined(ALPHA) || defined(SPARC) || defined(POWERPC)
-#define TCB_WAITEXECVE 02000   /* ignore SIGTRAP after exceve */
-#endif /* ALPHA */
+# if defined(ALPHA) || defined(SPARC) || defined(SPARC64) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SH64) || defined(S390) || defined(S390X) || defined(ARM)
+#  define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
+# endif
+# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
+# define TCB_CLONE_THREAD  010000 /* CLONE_THREAD set in creating syscall */
+# define TCB_GROUP_EXITING 020000 /* TCB_EXITING was exit_group, not _exit */
+# include <sys/syscall.h>
+# ifndef __NR_exit_group
+# /* Hack: Most headers around are too old to have __NR_exit_group.  */
+#  ifdef ALPHA
+#   define __NR_exit_group 405
+#  elif defined I386
+#   define __NR_exit_group 252
+#  elif defined IA64
+#   define __NR_exit_group 1236
+#  elif defined POWERPC
+#   define __NR_exit_group 234
+#  elif defined S390 || defined S390X
+#   define __NR_exit_group 248
+#  elif defined SPARC || defined SPARC64
+#   define __NR_exit_group 188
+#  endif /* ALPHA et al */
+# endif        /* !__NR_exit_group */
 #endif /* LINUX */
 
 /* qualifier flags */
@@ -250,10 +362,6 @@ struct tcb {
 #define syserror(tcp)  ((tcp)->u_error != 0)
 #define verbose(tcp)   (qual_flags[(tcp)->scno] & QUAL_VERBOSE)
 #define abbrev(tcp)    (qual_flags[(tcp)->scno] & QUAL_ABBREV)
-#define waiting_parent(tcp) \
-               (tcp->parent && \
-               (tcp->parent->flags & TCB_SUSPENDED) && \
-               (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid))
 
 struct xlat {
        int val;
@@ -265,6 +373,10 @@ struct xlat {
 #define RVAL_HEX       001     /* hex format */
 #define RVAL_OCTAL     002     /* octal format */
 #define RVAL_UDECIMAL  003     /* unsigned decimal format */
+#define RVAL_LDECIMAL  004     /* long decimal format */
+#define RVAL_LHEX      005     /* long hex format */
+#define RVAL_LOCTAL    006     /* long octal format */
+#define RVAL_LUDECIMAL 007     /* long unsigned decimal format */
 #define RVAL_MASK      007     /* mask for these values */
 
 #define RVAL_STR       010     /* Print `auxstr' field after return val */
@@ -284,13 +396,13 @@ struct xlat {
 #define TRACE_PROCESS  010     /* Trace process-related syscalls. */
 #define TRACE_SIGNAL   020     /* Trace signal-related syscalls. */
 
-extern struct tcb tcbtab[];
+extern struct tcb **tcbtab;
 extern int qual_flags[];
 extern int debug, followfork, followvfork;
 extern int rflag, tflag, dtime, cflag, xflag, qflag;
 extern int acolumn;
 extern char *outfname;
-extern int nprocs;
+extern unsigned int nprocs, tcbtabsize;
 extern int max_strlen;
 extern struct tcb *tcp_last;
 
@@ -301,22 +413,26 @@ extern struct tcb *tcp_last;
 #endif
 
 extern int set_personality P((int personality));
-extern char *xlookup P((struct xlat *, int));
+extern char *xlookup P((const struct xlat *, int));
 extern struct tcb *alloctcb P((int));
+extern struct tcb *pid2tcb P((int));
 extern void droptcb P((struct tcb *));
+extern int expand_tcbtab P((void));
 
 extern void set_sortby P((char *));
 extern void set_overhead P((int));
 extern void qualify P((char *));
 extern void newoutf P((struct tcb *));
+extern int get_scno P((struct tcb *));
 extern int trace_syscall P((struct tcb *));
-extern void printxval P((struct xlat *, int, char *));
+extern void printxval P((const struct xlat *, int, const char *));
 extern int printargs P((struct tcb *));
-extern int addflags P((struct xlat *, int));
-extern int printflags P((struct xlat *, int));
+extern int addflags P((const struct xlat *, int));
+extern int printflags P((const struct xlat *, int, const char *));
 extern int umoven P((struct tcb *, long, int, char *));
 extern int umovestr P((struct tcb *, long, int, char *));
 extern int upeek P((int, long, long *));
+extern void dumpiov P((struct tcb *, int, long));
 extern void dumpstr P((struct tcb *, long, int));
 extern void string_quote P((char *str));
 extern void printstr P((struct tcb *, long, int));
@@ -324,35 +440,44 @@ extern void printnum P((struct tcb *, long, char *));
 extern void printpath P((struct tcb *, long));
 extern void printpathn P((struct tcb *, long, int));
 extern void printtv P((struct tcb *, long));
+#ifdef HAVE_SIGINFO_T
+extern void printsiginfo P((siginfo_t *, int));
+#endif
 extern void printsock P((struct tcb *, long, int));
+extern void print_sock_optmgmt P((struct tcb *, long, int));
 extern void printrusage P((struct tcb *, long));
+extern void printuid P((const char *, unsigned long));
 extern int clearbpt P((struct tcb *));
 extern int setbpt P((struct tcb *));
 extern int sigishandled P((struct tcb *, int));
 extern void printcall P((struct tcb *));
-extern char *signame P((int));
+extern const char *signame P((int));
 extern void printsignal P((int));
 extern void printleader P((struct tcb *));
 extern void printtrailer P((struct tcb *));
 extern void tabto P((int));
 extern void call_summary P((FILE *));
-extern void fake_execve P((struct tcb *, char *, char *[], char *[]));
 extern void printtv32 P((struct tcb*, long));
+extern void tprint_iov P((struct tcb *, unsigned long, unsigned long));
 
 #ifdef LINUX
 extern int internal_clone P((struct tcb *));
 #endif
 extern int internal_fork P((struct tcb *));
 extern int internal_exec P((struct tcb *));
-extern int internal_wait P((struct tcb *));
+extern int internal_wait P((struct tcb *, int));
 extern int internal_exit P((struct tcb *));
 
-extern char *ioctl_lookup P((long));
+extern const struct ioctlent *ioctl_lookup P((long));
+extern const struct ioctlent *ioctl_next_match P((const struct ioctlent *));
 extern int ioctl_decode P((struct tcb *, long, long));
 extern int term_ioctl P((struct tcb *, long, long));
 extern int sock_ioctl P((struct tcb *, long, long));
 extern int proc_ioctl P((struct tcb *, int, int));
 extern int stream_ioctl P((struct tcb *, int, int));
+#ifdef LINUX
+extern int rtc_ioctl P((struct tcb *, long, long));
+#endif
 
 extern void tv_tv P((struct timeval *, int, int));
 extern int tv_nz P((struct timeval *));
@@ -366,10 +491,10 @@ extern void tv_div P((struct timeval *, struct timeval *, int));
 #ifdef SUNOS4
 extern int fixvfork P((struct tcb *));
 #endif
-#if !(defined(LINUX) && !defined(SPARC))
+#if !(defined(LINUX) && !defined(SPARC) && !defined(SPARC64) && !defined(IA64))
 extern long getrval2 P((struct tcb *));
 #endif
-#ifdef SVR4
+#ifdef USE_PROCFS
 extern int proc_open P((struct tcb *tcp, int attaching));
 #endif
 
@@ -400,47 +525,77 @@ struct sysent {
        int     nargs;
        int     sys_flags;
        int     (*sys_func)();
-       char    *sys_name;
+       const char *sys_name;
 };
 
-extern struct sysent *sysent;
+extern const struct sysent *sysent;
 extern int nsyscalls;
 
-extern char **errnoent;
+extern const char *const *errnoent;
 extern int nerrnos;
 
 struct ioctlent {
-       char *doth;
-       char *symbol;
+       const char *doth;
+       const char *symbol;
        unsigned long code;
 };
 
-extern struct ioctlent *ioctlent;
-extern int nioctlent;
-
-extern char **signalent;
-extern int nsignals;
-
-extern struct ioctlent *ioctlent;
+extern const struct ioctlent *ioctlent;
 extern int nioctlents;
-extern char **signalent;
+
+extern const char *const *signalent;
 extern int nsignals;
 
-extern struct ioctlent ioctlent0[];
-extern int nioctlents0;
-extern char *signalent0[];
-extern int nsignals0;
+extern const struct ioctlent ioctlent0[];
+extern const int nioctlents0;
+extern const char *const signalent0[];
+extern const int nsignals0;
 
 #if SUPPORTED_PERSONALITIES >= 2
-extern struct ioctlent ioctlent1[];
-extern int nioctlents1;
-extern char *signalent1[];
-extern int nsignals1;
+extern const struct ioctlent ioctlent1[];
+extern const int nioctlents1;
+extern const char *const signalent1[];
+extern const int nsignals1;
 #endif /* SUPPORTED_PERSONALITIES >= 2 */
 
 #if SUPPORTED_PERSONALITIES >= 3
-extern struct ioctlent ioctlent2[];
-extern int nioctlents2;
-extern char *signalent2[];
-extern int nsignals2;
+extern const struct ioctlent ioctlent2[];
+extern const int nioctlents2;
+extern const char *const signalent2[];
+extern const int nsignals2;
 #endif /* SUPPORTED_PERSONALITIES >= 3 */
+
+#if defined(FREEBSD) || (defined(LINUX) \
+                        && defined(POWERPC) && !defined(__powerpc64__)) \
+  || (defined (LINUX) && defined (MIPS) && !defined(__mips64))
+/* ARRGH!  off_t args are aligned on 64 bit boundaries! */
+#define ALIGN64(tcp,arg)                                               \
+do {                                                                   \
+       if (arg % 2)                                                    \
+           memmove (&tcp->u_arg[arg], &tcp->u_arg[arg + 1],            \
+                    (tcp->u_nargs - arg - 1) * sizeof tcp->u_arg[0]);  \
+} while (0)
+#else
+#define ALIGN64(tcp,arg) do { } while (0)
+#endif
+
+#if HAVE_LONG_LONG
+
+/* _l refers to the lower numbered u_arg,
+ * _h refers to the higher numbered u_arg
+ */
+
+#if HAVE_LITTLE_ENDIAN_LONG_LONG
+#define LONG_LONG(_l,_h) \
+    ((long long)((unsigned long long)(unsigned)(_l) | ((unsigned long long)(_h)<<32)))
+#else
+#define LONG_LONG(_l,_h) \
+    ((long long)((unsigned long long)(unsigned)(_h) | ((unsigned long long)(_l)<<32)))
+#endif
+#endif
+
+#ifdef IA64
+extern long ia32;
+#endif
+
+extern int not_failing_only;