#define INJECT_F_RETVAL 0x04
#define INJECT_F_DELAY_ENTER 0x08
#define INJECT_F_DELAY_EXIT 0x10
+#define INJECT_F_SYSCALL 0x20
+
+#define INJECT_ACTION_FLAGS \
+ (INJECT_F_SIGNAL \
+ |INJECT_F_ERROR \
+ |INJECT_F_RETVAL \
+ |INJECT_F_DELAY_ENTER \
+ |INJECT_F_DELAY_EXIT \
+ )
struct inject_data {
- uint8_t flags; /* 5 of 8 flags are used so far */
+ uint8_t flags; /* 6 of 8 flags are used so far */
uint8_t signo; /* NSIG <= 128 */
uint16_t rval_idx; /* index in retval_vec */
uint16_t delay_idx; /* index in delay_data_vec */
+ uint16_t scno; /* syscall to be injected instead of -1 */
};
struct inject_opts {
struct mmap_cache_t *mmap_cache;
+#ifdef HAVE_LINUX_KVM_H
+ struct vcpu_info *vcpu_info_list;
+#endif
+
#ifdef ENABLE_STACKTRACE
void *unwind_ctx;
struct unwind_queue_t *unwind_queue;
#define TCB_INJECT_DELAY_EXIT 0x800 /* Current syscall needs to be delayed
on exit */
#define TCB_DELAYED 0x1000 /* Current syscall has been delayed */
+#define TCB_TAMPERED_NO_FAIL 0x2000 /* We tamper tcb with syscall
+ that should not fail. */
/* qualifier flags */
#define QUAL_TRACE 0x001 /* this system call should be traced */
#define recovering(tcp) ((tcp)->flags & TCB_RECOVERING)
#define inject_delay_exit(tcp) ((tcp)->flags & TCB_INJECT_DELAY_EXIT)
#define syscall_delayed(tcp) ((tcp)->flags & TCB_DELAYED)
+#define syscall_tampered_nofail(tcp) ((tcp)->flags & TCB_TAMPERED_NO_FAIL)
#include "xlat.h"
extern const struct xlat addrfams[];
+
+/** Protocol hardware identifiers array, sorted, defined in sockaddr.c. */
extern const struct xlat arp_hardware_types[];
+/** Protocol hardware identifiers array size without terminating record. */
+extern const size_t arp_hardware_types_size;
+
extern const struct xlat at_flags[];
extern const struct xlat clocknames[];
extern const struct xlat dirent_types[];
/** Ethernet protocols array size without terminating record. */
extern const size_t ethernet_protocols_size;
+/** IP protocols list, sorted, defined in net.c. */
+extern const struct xlat inet_protocols[];
+/** IP protocols array size without terminating record. */
+extern const size_t inet_protocols_size;
+
extern const struct xlat evdev_abs[];
/** Number of elements in evdev_abs array without the terminating record. */
extern const size_t evdev_abs_size;
extern const struct xlat iffflags[];
-extern const struct xlat inet_protocols[];
extern const struct xlat ip_type_of_services[];
extern const struct xlat ipc_private[];
extern const struct xlat msg_flags[];
return set_tcb_priv_data(tcp, (void *) val, 0);
}
+/**
+ * @return 0 on success, -1 on error.
+ */
extern int
umoven(struct tcb *, kernel_ulong_t addr, unsigned int len, void *laddr);
#define umove(pid, addr, objp) \
umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
+/**
+ * @return true on success, false on error.
+ */
+extern bool
+tfetch_mem64(struct tcb *, uint64_t addr, unsigned int len, void *laddr);
+
+static inline bool
+tfetch_mem(struct tcb *tcp, const kernel_ulong_t addr,
+ unsigned int len, void *laddr)
+{
+ return tfetch_mem64(tcp, addr, len, laddr);
+}
+#define tfetch_obj(pid, addr, objp) \
+ tfetch_mem((pid), (addr), sizeof(*(objp)), (void *) (objp))
+
+/**
+ * @return true on success, false on error.
+ */
+extern bool
+tfetch_mem64_ignore_syserror(struct tcb *, uint64_t addr,
+ unsigned int len, void *laddr);
+
+static inline bool
+tfetch_mem_ignore_syserror(struct tcb *tcp, const kernel_ulong_t addr,
+ unsigned int len, void *laddr)
+{
+ return tfetch_mem64_ignore_syserror(tcp, addr, len, laddr);
+}
+
+/**
+ * @return 0 on success, -1 on error (and print addr).
+ */
extern int
umoven_or_printaddr64(struct tcb *, uint64_t addr,
unsigned int len, void *laddr);
#define umove_or_printaddr(pid, addr, objp) \
umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
+/**
+ * @return 0 on success, -1 on error (and print addr).
+ */
extern int
umoven_or_printaddr64_ignore_syserror(struct tcb *, uint64_t addr,
unsigned int len, void *laddr);
umoven_or_printaddr_ignore_syserror((pid), (addr), sizeof(*(objp)), \
(void *) (objp))
+/**
+ * @return strlen + 1 on success, 0 on success and no NUL seen, -1 on error.
+ */
extern int
umovestr(struct tcb *, kernel_ulong_t addr, unsigned int len, char *laddr);
ATTRIBUTE_FORMAT((printf, 2, 0));
extern void printaddr64(uint64_t addr);
-extern void printaddr(kernel_ulong_t addr);
-#define XLAT_STYLE_VERBOSITY_MASK (XLAT_STYLE_RAW | XLAT_STYLE_ABBREV)
-#define XLAT_STYLE_FORMAT_SHIFT 2
-#define XLAT_STYLE_FORMAT_MASK (3 << XLAT_STYLE_FORMAT_SHIFT)
+static inline void
+printaddr(const kernel_ulong_t addr)
+{
+ printaddr64(addr);
+}
#define xlat_verbose(style_) ((style_) & XLAT_STYLE_VERBOSITY_MASK)
#define xlat_format(style_) ((style_) & XLAT_STYLE_FORMAT_MASK)
-enum xlat_type {
- XT_NORMAL,
- XT_SORTED,
- XT_INDEXED,
-};
-
-enum xlat_style {
- /**
- * Special value that is used for passing to *print{xval,flags}*_ex
- * routines that indicates that no overriding of user-supplied xlat
- * verbosity/formatting configuration is intended.
- */
- XLAT_STYLE_DEFAULT = 0,
-
- /** Print xlat value as is without xlat processing */
- XLAT_STYLE_RAW = 1 << 0,
- /**
- * Historic strace style, process xlat and print the result (xlat
- * constant name/combination of flags), raw number only if nothing is
- * found.
- */
- XLAT_STYLE_ABBREV = 1 << 1,
- /** Always print both raw number and xlat processing result. */
- XLAT_STYLE_VERBOSE = XLAT_STYLE_RAW | XLAT_STYLE_ABBREV,
-
- XLAT_STYLE_FMT_X = 0 << XLAT_STYLE_FORMAT_SHIFT,
- XLAT_STYLE_FMT_U = 1 << XLAT_STYLE_FORMAT_SHIFT,
- XLAT_STYLE_FMT_D = 2 << XLAT_STYLE_FORMAT_SHIFT,
-};
-
extern enum xlat_style xlat_verbosity;
extern int printxvals_ex(uint64_t val, const char *dflt,
extern bool print_uint64_array_member(struct tcb *, void *elem_buf,
size_t elem_size, void *data);
+typedef bool (*tfetch_mem_fn)(struct tcb *, kernel_ulong_t addr,
+ unsigned int size, void *dest);
+typedef bool (*print_fn)(struct tcb *, void *elem_buf,
+ size_t elem_size, void *opaque_data);
+
+enum print_array_flag_bits {
+ PAF_PRINT_INDICES_BIT = XLAT_STYLE_SPEC_BITS + 1,
+ PAF_INDEX_XLAT_SORTED_BIT,
+ PAF_INDEX_XLAT_VALUE_INDEXED_BIT,
+};
+
+#define FLAG_(name_) name_ = 1 << name_##_BIT
+
+enum print_array_flags {
+ FLAG_(PAF_PRINT_INDICES),
+ FLAG_(PAF_INDEX_XLAT_SORTED),
+ FLAG_(PAF_INDEX_XLAT_VALUE_INDEXED),
+};
+
+#undef FLAG_
+
+/**
+ * @param flags Combination of xlat style settings and additional flags from
+ * enum print_array_flags.
+ */
extern bool
-print_array(struct tcb *,
- kernel_ulong_t start_addr,
- size_t nmemb,
- void *elem_buf,
- size_t elem_size,
- int (*umoven_func)(struct tcb *,
- kernel_ulong_t,
- unsigned int,
- void *),
- bool (*print_func)(struct tcb *,
- void *elem_buf,
- size_t elem_size,
- void *opaque_data),
- void *opaque_data);
+print_array_ex(struct tcb *,
+ kernel_ulong_t start_addr,
+ size_t nmemb,
+ void *elem_buf,
+ size_t elem_size,
+ tfetch_mem_fn tfetch_mem_func,
+ print_fn print_func,
+ void *opaque_data,
+ unsigned int flags,
+ const struct xlat *index_xlat,
+ size_t index_xlat_size,
+ const char *index_dflt);
+
+static inline bool
+print_array(struct tcb *const tcp,
+ const kernel_ulong_t start_addr,
+ const size_t nmemb,
+ void *const elem_buf,
+ const size_t elem_size,
+ tfetch_mem_fn tfetch_mem_func,
+ print_fn print_func,
+ void *const opaque_data)
+{
+ return print_array_ex(tcp, start_addr, nmemb, elem_buf, elem_size,
+ tfetch_mem_func, print_func, opaque_data,
+ 0, NULL, 0, NULL);
+}
extern kernel_ulong_t *
fetch_indirect_syscall_args(struct tcb *, kernel_ulong_t addr, unsigned int n_args);
extern void
print_struct_statfs64(struct tcb *, kernel_ulong_t addr, kernel_ulong_t size);
+extern int
+fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr);
+extern void
+print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr);
+
extern void print_ifindex(unsigned int);
extern void print_bpf_filter_code(const uint16_t code, bool extended);
DECL_IOCTL(evdev);
DECL_IOCTL(file);
DECL_IOCTL(fs_x);
+DECL_IOCTL(inotify);
DECL_IOCTL(kvm);
DECL_IOCTL(nsfs);
DECL_IOCTL(ptp);
extern void unwind_tcb_capture(struct tcb *);
#endif
+#ifdef HAVE_LINUX_KVM_H
+extern void kvm_run_structure_decoder_init(void);
+extern void kvm_vcpu_info_free(struct tcb *);
+#endif
+
static inline int
printstrn(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len)
{
extern void tprintf_comment(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
extern void tprints_comment(const char *str);
+static inline void
+printaddr_comment(const kernel_ulong_t addr)
+{
+ tprintf_comment("%#llx", (unsigned long long) addr);
+}
+
static inline void
print_mac_addr(const char *prefix, const uint8_t addr[], size_t size)
{
extern const struct_ioctlent ioctlent0[];
extern const char *const personality_names[];
+/* Personality designators to be used for specifying personality */
+extern const char *const personality_designators[];
#if SUPPORTED_PERSONALITIES > 1
extern const struct_sysent *sysent;