X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=defs.h;h=92c7fec3b5ae98e334b28bc7ff10a0138121c9d5;hb=7005bcd451920ef5ec01295f17620ff155620b7a;hp=7c062eb6fe7ed50a88617f68e03f04d5203c30d3;hpb=7fa3d78319b20a996923f9b665afc3a3571ed08b;p=strace diff --git a/defs.h b/defs.h index 7c062eb6..92c7fec3 100644 --- a/defs.h +++ b/defs.h @@ -2,6 +2,7 @@ * Copyright (c) 1991, 1992 Paul Kranenburg * Copyright (c) 1993 Branko Lankester * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey + * Copyright (c) 2001-2017 The strace developers. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,11 +52,11 @@ #include #include #include -#include #include "kernel_types.h" #include "mpers_type.h" #include "gcc_compat.h" +#include "sysent.h" #ifndef HAVE_STRERROR const char *strerror(int); @@ -125,15 +126,6 @@ extern char *stpcpy(char *dst, const char *src); #define USE_SEIZE 1 /* To force NOMMU build, set to 1 */ #define NOMMU_SYSTEM 0 -/* - * Set to 1 to use speed-optimized vfprintf implementation. - * It results in strace using about 5% less CPU in user space - * (compared to glibc version). - * But strace spends a lot of time in kernel space, - * so overall it does not appear to be a significant win. - * Thus disabled by default. - */ -#define USE_CUSTOM_PRINTF 0 #ifndef ERESTARTSYS # define ERESTARTSYS 512 @@ -201,30 +193,20 @@ extern char *stpcpy(char *dst, const char *src); # define PERSONALITY2_INCLUDE_FUNCS "empty.h" #endif -typedef struct sysent { - unsigned nargs; - int sys_flags; - int sen; - int (*sys_func)(); - const char *sys_name; -} struct_sysent; - typedef struct ioctlent { const char *symbol; unsigned int code; } struct_ioctlent; -struct fault_opts { +struct inject_opts { uint16_t first; uint16_t step; - uint16_t err; + uint16_t signo; + int rval; }; -#if defined LINUX_MIPSN32 || defined X32 -# define HAVE_STRUCT_TCB_EXT_ARG 1 -#else -# define HAVE_STRUCT_TCB_EXT_ARG 0 -#endif +#define MAX_ERRNO_VALUE 4095 +#define INJECT_OPTS_RVAL_DEFAULT (-(MAX_ERRNO_VALUE + 1)) /* Trace Control Block */ struct tcb { @@ -234,10 +216,6 @@ struct tcb { unsigned long u_error; /* Error code */ kernel_ulong_t scno; /* System call number */ kernel_ulong_t u_arg[MAX_ARGS]; /* System call arguments */ -#if HAVE_STRUCT_TCB_EXT_ARG - unsigned long long ext_arg[MAX_ARGS]; - long long u_lrval; /* long long return value */ -#endif kernel_long_t u_rval; /* Return value */ #if SUPPORTED_PERSONALITIES > 1 unsigned int currpers; /* Personality at the time of scno update */ @@ -250,7 +228,7 @@ struct tcb { void (*_free_priv_data)(void *); /* Callback for freeing priv_data */ const struct_sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */ const struct_sysent *s_prev_ent; /* for "resuming interrupted SYSCALL" msg */ - struct fault_opts *fault_vec[SUPPORTED_PERSONALITIES]; + struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES]; 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 */ @@ -287,7 +265,7 @@ struct tcb { #define TCB_ATTACHED 0x08 /* We attached to it already */ #define TCB_REPRINT 0x10 /* We should reprint this syscall on exit */ #define TCB_FILTERED 0x20 /* This system call has been filtered out */ -#define TCB_FAULT_INJ 0x40 /* A syscall fault has been injected */ +#define TCB_TAMPERED 0x40 /* A syscall has been tampered with */ #define TCB_HIDE_LOG 0x80 /* We should hide everything (until execve) */ #define TCB_SKIP_DETACH_ON_FIRST_EXEC 0x100 /* -b execve should skip detach on first execve */ @@ -296,7 +274,7 @@ struct tcb { #define QUAL_ABBREV 0x002 /* abbreviate the structures of this syscall */ #define QUAL_VERBOSE 0x004 /* decode the structures of this syscall */ #define QUAL_RAW 0x008 /* print all args in hex for this syscall */ -#define QUAL_FAULT 0x010 /* fail this system call on purpose */ +#define QUAL_INJECT 0x010 /* tamper with this system call on purpose */ #define QUAL_SIGNAL 0x100 /* report events with this signal */ #define QUAL_READ 0x200 /* dump data read from this file descriptor */ #define QUAL_WRITE 0x400 /* dump data written to this file descriptor */ @@ -315,12 +293,16 @@ struct tcb { extern const struct xlat addrfams[]; extern const struct xlat at_flags[]; +extern const struct xlat clocknames[]; extern const struct xlat dirent_types[]; extern const struct xlat evdev_abs[]; extern const struct xlat msg_flags[]; +extern const struct xlat netlink_protocols[]; extern const struct xlat open_access_modes[]; extern const struct xlat open_mode_flags[]; extern const struct xlat resource_flags[]; +extern const struct xlat setns_types[]; +extern const struct xlat sg_io_info[]; extern const struct xlat socketlayers[]; extern const struct xlat whence_codes[]; @@ -329,35 +311,14 @@ extern const struct xlat whence_codes[]; #define RVAL_HEX 001 /* hex format */ #define RVAL_OCTAL 002 /* octal format */ #define RVAL_UDECIMAL 003 /* unsigned decimal format */ -#if HAVE_STRUCT_TCB_EXT_ARG -# if 0 /* unused so far */ -# define RVAL_LDECIMAL 004 /* long decimal format */ -# define RVAL_LHEX 005 /* long hex format */ -# define RVAL_LOCTAL 006 /* long octal format */ -# endif -# define RVAL_LUDECIMAL 007 /* long unsigned decimal format */ -#endif /* HAVE_STRUCT_TCB_EXT_ARG */ #define RVAL_FD 010 /* file descriptor */ -#define RVAL_MASK 017 /* mask for these values */ +#define RVAL_MASK 013 /* mask for these values */ #define RVAL_STR 020 /* Print `auxstr' field after return val */ #define RVAL_NONE 040 /* Print nothing */ #define RVAL_DECODED 0100 /* syscall decoding finished */ -#define TRACE_FILE 001 /* Trace file-related syscalls. */ -#define TRACE_IPC 002 /* Trace IPC-related syscalls. */ -#define TRACE_NETWORK 004 /* Trace network-related syscalls. */ -#define TRACE_PROCESS 010 /* Trace process-related syscalls. */ -#define TRACE_SIGNAL 020 /* Trace signal-related syscalls. */ -#define TRACE_DESC 040 /* Trace file descriptor-related syscalls. */ -#define TRACE_MEMORY 0100 /* Trace memory mapping-related syscalls. */ -#define SYSCALL_NEVER_FAILS 0200 /* Syscall is always successful. */ -#define STACKTRACE_INVALIDATE_CACHE 0400 /* Trigger proc/maps cache updating */ -#define STACKTRACE_CAPTURE_ON_ENTER 01000 /* Capture stacktrace on "entering" stage */ -#define TRACE_INDIRECT_SUBCALL 02000 /* Syscall is an indirect socket/ipc subcall. */ -#define COMPAT_SYSCALL_TYPES 04000 /* A compat syscall that uses compat types. */ - #define IOCTL_NUMBER_UNKNOWN 0 #define IOCTL_NUMBER_HANDLED 1 #define IOCTL_NUMBER_STOP_LOOKUP 010 @@ -442,28 +403,19 @@ void *xreallocarray(void *ptr, size_t nmemb, size_t size) ATTRIBUTE_ALLOC_SIZE((2, 3)); char *xstrdup(const char *str) ATTRIBUTE_MALLOC; -#if USE_CUSTOM_PRINTF -/* - * See comment in vsprintf.c for allowed formats. - * Short version: %h[h]u, %zu, %tu are not allowed, use %[l[l]]u. - */ -int strace_vfprintf(FILE *fp, const char *fmt, va_list args); -#else -# define strace_vfprintf vfprintf -#endif - extern int read_int_from_file(const char *, int *); extern void set_sortby(const char *); extern void set_overhead(int); extern void print_pc(struct tcb *); -extern int trace_syscall(struct tcb *); +extern int trace_syscall(struct tcb *, unsigned int *); extern void count_syscall(struct tcb *, const struct timeval *); extern void call_summary(FILE *); extern void clear_regs(void); -extern void get_regs(pid_t pid); -extern int get_scno(struct tcb *tcp); +extern int get_scno(struct tcb *); +extern kernel_ulong_t get_rt_sigframe_addr(struct tcb *); + /** * Convert syscall number to syscall name. * @@ -542,6 +494,7 @@ extern const char *signame(const int); extern void pathtrace_select(const char *); extern int pathtrace_match(struct tcb *); extern int getfdpath(struct tcb *, int, char *, unsigned); +extern unsigned long getfdinode(struct tcb *, int); extern enum sock_proto getfdproto(struct tcb *, int); extern const char *xlookup(const struct xlat *, const uint64_t); @@ -559,9 +512,24 @@ string_to_uint_upto(const char *const str, unsigned int max_val) } extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits); +/* + * Returns STR if it does not start with PREFIX, + * or a pointer to the first char in STR after PREFIX. + * The length of PREFIX is specified by PREFIX_LEN. + */ +static inline const char * +str_strip_prefix_len(const char *str, const char *prefix, size_t prefix_len) +{ + return strncmp(str, prefix, prefix_len) ? str : str + prefix_len; +} + +#define STR_STRIP_PREFIX(str, prefix) \ + str_strip_prefix_len((str), (prefix), sizeof(prefix) - 1) + #define QUOTE_0_TERMINATED 0x01 #define QUOTE_OMIT_LEADING_TRAILING_QUOTES 0x02 #define QUOTE_OMIT_TRAILING_0 0x08 +#define QUOTE_FORCE_HEX 0x10 extern int string_quote(const char *, char *, unsigned int, unsigned int); extern int print_quoted_string(const char *, unsigned int, unsigned int); @@ -580,14 +548,13 @@ extern int getllval(struct tcb *, unsigned long long *, int); extern int printllval(struct tcb *, const char *, int) ATTRIBUTE_FORMAT((printf, 2, 0)); -extern void printaddr_klu(kernel_ulong_t addr); +extern void printaddr(kernel_ulong_t addr); extern int printxvals(const uint64_t, const char *, const struct xlat *, ...) ATTRIBUTE_SENTINEL; extern int printxval_searchn(const struct xlat *xlat, size_t xlat_size, uint64_t val, const char *dflt); #define printxval_search(xlat__, val__, dflt__) \ printxval_searchn(xlat__, ARRAY_SIZE(xlat__), val__, dflt__) -extern kernel_ulong_t getarg_klu(struct tcb *tcp, int argn); extern int printargs(struct tcb *); extern int printargs_u(struct tcb *); extern int printargs_d(struct tcb *); @@ -595,10 +562,14 @@ extern int printargs_d(struct tcb *); extern void addflags(const struct xlat *, uint64_t); extern int printflags64(const struct xlat *, uint64_t, const char *); extern const char *sprintflags(const char *, const struct xlat *, uint64_t); -extern const char *sprinttime(time_t); +extern const char *sprinttime(long long sec); +extern const char *sprinttime_nsec(long long sec, unsigned long long nsec); +extern const char *sprinttime_usec(long long sec, unsigned long long usec); extern void print_symbolic_mode_t(unsigned int); extern void print_numeric_umode_t(unsigned short); extern void print_numeric_long_umask(unsigned long); +extern void print_dev_t(unsigned long long dev); +extern void print_abnormal_hi(kernel_ulong_t); extern void dumpiov_in_msghdr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t data_size); @@ -616,51 +587,6 @@ extern void printstr_ex(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len, unsigned int user_style); -#define DECL_PRINTNUM(name) \ -extern bool \ -printnum_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \ - ATTRIBUTE_FORMAT((printf, 3, 0)) -DECL_PRINTNUM(short); -DECL_PRINTNUM(int); -DECL_PRINTNUM(int64); -#undef DECL_PRINTNUM - -#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 -extern bool -printnum_long_int(struct tcb *, kernel_ulong_t addr, - const char *fmt_long, const char *fmt_int) - ATTRIBUTE_FORMAT((printf, 3, 0)) - ATTRIBUTE_FORMAT((printf, 4, 0)); -# define printnum_slong(tcp, addr) \ - printnum_long_int((tcp), (addr), "%" PRId64, "%d") -# define printnum_ulong(tcp, addr) \ - printnum_long_int((tcp), (addr), "%" PRIu64, "%u") -# define printnum_ptr(tcp, addr) \ - printnum_long_int((tcp), (addr), "%#" PRIx64, "%#x") -#elif SIZEOF_LONG > 4 -# define printnum_slong(tcp, addr) \ - printnum_int64((tcp), (addr), "%" PRId64) -# define printnum_ulong(tcp, addr) \ - printnum_int64((tcp), (addr), "%" PRIu64) -# define printnum_ptr(tcp, addr) \ - printnum_int64((tcp), (addr), "%#" PRIx64) -#else -# define printnum_slong(tcp, addr) \ - printnum_int((tcp), (addr), "%d") -# define printnum_ulong(tcp, addr) \ - printnum_int((tcp), (addr), "%u") -# define printnum_ptr(tcp, addr) \ - printnum_int((tcp), (addr), "%#x") -#endif - -#define DECL_PRINTPAIR(name) \ -extern bool \ -printpair_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \ - ATTRIBUTE_FORMAT((printf, 3, 0)) -DECL_PRINTPAIR(int); -DECL_PRINTPAIR(int64); -#undef DECL_PRINTPAIR - extern void printpathn(struct tcb *, kernel_ulong_t addr, unsigned int n); @@ -668,11 +594,11 @@ extern void printpath(struct tcb *, kernel_ulong_t addr); #define TIMESPEC_TEXT_BUFSIZE \ - (sizeof(intmax_t)*3 * 2 + sizeof("{tv_sec=%jd, tv_nsec=%jd}")) + (sizeof(long long) * 3 * 2 + sizeof("{tv_sec=-, tv_nsec=}")) extern void printfd(struct tcb *, int); extern void print_sockaddr(struct tcb *tcp, const void *, int); -extern bool print_sockaddr_by_inode(const unsigned long, const enum sock_proto); -extern bool print_sockaddr_by_inode_cached(const unsigned long); +extern const char *get_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode); +extern bool print_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode); extern void print_dirfd(struct tcb *, int); extern int @@ -682,6 +608,8 @@ extern void printuid(const char *, const unsigned int); extern void print_sigset_addr_len(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len); +extern void +print_sigset_addr(struct tcb *, kernel_ulong_t addr); extern const char *sprintsigmask_n(const char *, const void *, unsigned int); #define tprintsigmask_addr(prefix, mask) \ @@ -693,7 +621,7 @@ tprint_iov_upto(struct tcb *, kernel_ulong_t len, kernel_ulong_t addr, enum iov_decode, kernel_ulong_t data_size); extern void -decode_netlink(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len); +decode_netlink(struct tcb *, int fd, kernel_ulong_t addr, kernel_ulong_t len); extern void tprint_open_modes(unsigned int); extern const char *sprint_open_modes(unsigned int); @@ -732,15 +660,16 @@ name ## _ioctl(struct tcb *, unsigned int request, kernel_ulong_t arg) DECL_IOCTL(dm); DECL_IOCTL(file); DECL_IOCTL(fs_x); -DECL_IOCTL(loop); +DECL_IOCTL(nsfs); DECL_IOCTL(ptp); DECL_IOCTL(scsi); -DECL_IOCTL(sock); DECL_IOCTL(term); DECL_IOCTL(ubi); DECL_IOCTL(uffdio); #undef DECL_IOCTL +extern int decode_sg_io_v4(struct tcb *, const kernel_ulong_t arg); + extern int tv_nz(const struct timeval *); extern int tv_cmp(const struct timeval *, const struct timeval *); extern double tv_float(const struct timeval *); @@ -758,12 +687,6 @@ extern void unwind_print_stacktrace(struct tcb* tcp); extern void unwind_capture_stacktrace(struct tcb* tcp); #endif -static inline void -printaddr(kernel_ulong_t addr) -{ - printaddr_klu(addr); -} - static inline void printstrn(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len) { @@ -810,7 +733,7 @@ extern void print_timeval32_t(const timeval32_t *); extern void printrusage32(struct tcb *, kernel_ulong_t); extern const char *sprint_timeval32(struct tcb *tcp, kernel_ulong_t); extern void print_timeval32(struct tcb *tcp, kernel_ulong_t); -extern void print_timeval32_pair(struct tcb *tcp, kernel_ulong_t); +extern void print_timeval32_utimes(struct tcb *tcp, kernel_ulong_t); extern void print_itimerval32(struct tcb *tcp, kernel_ulong_t); #endif @@ -841,6 +764,8 @@ extern void line_ended(void); extern void tabto(void); extern void tprintf(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2)); extern void tprints(const char *str); +extern void tprintf_comment(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2)); +extern void tprints_comment(const char *str); #if SUPPORTED_PERSONALITIES > 1 extern void set_personality(int personality); @@ -866,24 +791,101 @@ extern unsigned current_klongsize; # endif #endif -/* In many, many places we play fast and loose and use - * tprintf("%d", (int) tcp->u_arg[N]) to print fds, pids etc. - * We probably need to use widen_to_long() instead: - */ -#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 -# define widen_to_long(v) (current_wordsize == 4 ? (long)(int32_t)(v) : (long)(v)) -#else -# define widen_to_long(v) ((long)(v)) +#define ANY_WORDSIZE_LESS_THAN_KERNEL_LONG \ + (SIZEOF_KERNEL_LONG_T > 4 \ + && (SIZEOF_LONG < SIZEOF_KERNEL_LONG_T || !defined(current_wordsize))) + +#define DECL_PRINTNUM(name) \ +extern bool \ +printnum_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \ + ATTRIBUTE_FORMAT((printf, 3, 0)) +DECL_PRINTNUM(short); +DECL_PRINTNUM(int); +DECL_PRINTNUM(int64); +#undef DECL_PRINTNUM + +#define DECL_PRINTNUM_ADDR(name) \ +extern bool \ +printnum_addr_ ## name(struct tcb *, kernel_ulong_t addr) +DECL_PRINTNUM_ADDR(int); +DECL_PRINTNUM_ADDR(int64); +#undef DECL_PRINTNUM_ADDR + +#ifndef current_wordsize +extern bool +printnum_long_int(struct tcb *, kernel_ulong_t addr, + const char *fmt_long, const char *fmt_int) + ATTRIBUTE_FORMAT((printf, 3, 0)) + ATTRIBUTE_FORMAT((printf, 4, 0)); +extern bool printnum_addr_long_int(struct tcb *, kernel_ulong_t addr); +# define printnum_slong(tcp, addr) \ + printnum_long_int((tcp), (addr), "%" PRId64, "%d") +# define printnum_ulong(tcp, addr) \ + printnum_long_int((tcp), (addr), "%" PRIu64, "%u") +# define printnum_ptr(tcp, addr) \ + printnum_addr_long_int((tcp), (addr)) +#elif current_wordsize > 4 +# define printnum_slong(tcp, addr) \ + printnum_int64((tcp), (addr), "%" PRId64) +# define printnum_ulong(tcp, addr) \ + printnum_int64((tcp), (addr), "%" PRIu64) +# define printnum_ptr(tcp, addr) \ + printnum_addr_int64((tcp), (addr)) +#else /* current_wordsize == 4 */ +# define printnum_slong(tcp, addr) \ + printnum_int((tcp), (addr), "%d") +# define printnum_ulong(tcp, addr) \ + printnum_int((tcp), (addr), "%u") +# define printnum_ptr(tcp, addr) \ + printnum_addr_int((tcp), (addr)) #endif -#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 -# define widen_to_ulong(v) \ - (current_wordsize == 4 ? (unsigned long) (uint32_t) (v) : \ - (unsigned long) (v)) -#else -# define widen_to_ulong(v) ((unsigned long)(v)) +#ifndef current_klongsize +extern bool printnum_addr_klong_int(struct tcb *, kernel_ulong_t addr); +# define printnum_kptr(tcp, addr) \ + printnum_addr_klong_int((tcp), (addr)) +#elif current_klongsize > 4 +# define printnum_kptr(tcp, addr) \ + printnum_addr_int64((tcp), (addr)) +#else /* current_klongsize == 4 */ +# define printnum_kptr(tcp, addr) \ + printnum_addr_int((tcp), (addr)) #endif +#define DECL_PRINTPAIR(name) \ +extern bool \ +printpair_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \ + ATTRIBUTE_FORMAT((printf, 3, 0)) +DECL_PRINTPAIR(int); +DECL_PRINTPAIR(int64); +#undef DECL_PRINTPAIR + +static inline kernel_long_t +truncate_klong_to_current_wordsize(const kernel_long_t v) +{ +#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG + if (current_wordsize < sizeof(v)) { + return (int) v; + } else +#endif + { + return v; + } +} + +static inline kernel_ulong_t +truncate_kulong_to_current_wordsize(const kernel_ulong_t v) +{ +#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG + if (current_wordsize < sizeof(v)) { + return (unsigned int) v; + } else +#endif + { + return v; + } +} + /* * Cast a pointer or a pointer-sized integer to kernel_ulong_t. */ @@ -933,7 +935,7 @@ extern unsigned nioctlents; extern const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES]; extern const struct_sysent *const sysent_vec[SUPPORTED_PERSONALITIES]; -extern struct fault_opts *fault_vec[SUPPORTED_PERSONALITIES]; +extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES]; #ifdef IN_MPERS_BOOTSTRAP /* Transform multi-line MPERS_PRINTER_DECL statements to one-liners. */ @@ -985,10 +987,6 @@ scno_is_valid(kernel_ulong_t scno) #define PRI_klu PRI_kl"u" #define PRI_klx PRI_kl"x" -#define PRI_krd PRI_kld -#define PRI_kru PRI_klu -#define PRI_krx PRI_klx - /* * The kernel used to define 64-bit types on 64-bit systems on a per-arch * basis. Some architectures would use unsigned long and others would use