aboutsummaryrefslogtreecommitdiff
path: root/sg_io_v3.c
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2017-02-15 15:19:05 -0800
committerElliott Hughes <enh@google.com>2017-02-15 16:23:02 -0800
commitd35df493b4e7684c50d2d2fa032ee3a7ac228009 (patch)
tree389a89297d98da7bd3dcc4e4f8b1df69ea85bba0 /sg_io_v3.c
parentee18e8ae76b0828006d07262ed6085dca9fd08c1 (diff)
downloadstrace-d35df493b4e7684c50d2d2fa032ee3a7ac228009.tar.gz
Upgrade strace to 4.16 from 4.14.
Noteworthy changes in release 4.16 (2017-02-14) * Improvements * Implemented syscall return value injection (-e inject=SET:retval= option). * Implemented signal injection (-e inject=SET:signal= option). * Implemented decoding of SUID_DUMP_* constants in PR_[GS]ET_DUMPABLE. * Implemented decoding of all SG_* ioctl commands. * Implemented decoding of ustat syscall. * Implemented decoding of BPF_OBJ_PIN, BPF_OBJ_GET, BPF_PROG_ATTACH, and BPF_PROG_DETACH commands of bpf syscall. * Enhanced decoding of sg_io_hdr and sg_io_v4 structures. * Enhanced decoding of get_robust_list, getrandom, io_submit, set_robust_list syscalls. * Enhanced decoding of entities of kernel long type on x32 and mips n32 ABIs. * Updated lists of IP_*, IPV6_*, and LOOP_* constants. * Updated lists of ioctl commands from Linux 4.10. * Added decoding of recently added syscalls on avr32, microblaze, ppc, and ppc64. * Bug fixes * Fixed pathmatch of oldselect syscall on 64-bit architectures. * Fixed decoding of mmap2 syscall on s390 when arguments are not available. * Fixed decoding of kexec_file_load, mprotect, pkey_mprotect, prctl, preadv*, and pwritev* syscalls on x32. * Fixed printing of string arguments of getxattr and setxattr syscalls when -s option is used to limit the printed string size. * Fixed decoding of ifconf, ifreq, and loop_info structures on non-native personalities. * Fixed decoding of SG_* and LOOP_* ioctl commands. * Fixed build on mips with musl libc. * Fixed cross-building of ioctlsort. * Applied minor formatting fixes to the manual page. Noteworthy changes in release 4.15 (2016-12-14) * Changes in behavior * Time stamps are now printed according to ISO 8601. * Changed output format of val3 parameter of futex FUTEX_WAKE_OP operation. * The last argument of mincore, sched_getaffinity, and sched_setaffinity syscalls is now formatted as an array. * Improvements * Implemented syscall fault injection (-e fault=... option). * Implemented decoding of DM_* ioctl commands. * Implemented decoding of attr parameter of perf_event_open syscall. * Implemented decoding of pkey_alloc, pkey_free, and pkey_mprotect syscalls. * Implemented dumping of mq_timedsend and mq_timedreceive syscalls. * Implemented decoding of PR_SET_FP_MODE and PR_GET_FP_MODE operations of prctl syscall. * Implemented PTRACE_GETREGS API support on m68k. * Updated lists of ARCH_*, BPF_*, BTRFS_*, FALLOC_*, MS_*, *_MAGIC, and V4L2_* constants. * Updated lists of ioctl commands from Linux 4.9. * Added decoding of recently added syscalls on arc, x32, and xtensa. * Enhanced manual page. * Bug fixes * Fixed corner cases in decoding of exit, exit_group, futimesat, getgroups, getresuid, init_module, inotify_init1, kcmp, kexec_load, lookup_dcookie, mq_getsetattr, mq_notify, mq_open, mq_timedreceive, mq_timedsend, name_to_handle_at, prctl, process_vm_readv, process_vm_writev, setfsuid, setgroups, setns, unshare, and utimes syscalls. * Fixed handling of verbose flag in printing of controls array of struct v4l2_ext_controls. * Fixed omission of field names in the output of capability, sigaction, sigevent, statfs, timespec, timeval, and utimbuf structures. * Fixed printing of unknown syscalls in siginfo structure. * Fixed decoding of ioctl constants on m68k. * Fixed cris architecture support. * Fixed cross build when host compiler does not support the same set of warning flags as the cross compiler. * Fixed build on SLE10 and SLE11. Bug: N/A Test: manual Change-Id: I590bf5db1652aa1dfdc0eb16e30fd97c82af2261
Diffstat (limited to 'sg_io_v3.c')
-rw-r--r--sg_io_v3.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/sg_io_v3.c b/sg_io_v3.c
new file mode 100644
index 00000000..33aff506
--- /dev/null
+++ b/sg_io_v3.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2007 Vladimir Nadvornik <nadvornik@suse.cz>
+ * Copyright (c) 2007-2017 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2015 Bart Van Assche <bart.vanassche@sandisk.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#ifdef HAVE_SCSI_SG_H
+
+#include DEF_MPERS_TYPE(struct_sg_io_hdr)
+
+# include <scsi/sg.h>
+
+typedef struct sg_io_hdr struct_sg_io_hdr;
+
+#endif /* HAVE_SCSI_SG_H */
+
+#include MPERS_DEFS
+
+#include "xlat/sg_io_info.h"
+
+#ifdef HAVE_SCSI_SG_H
+# include "xlat/sg_io_dxfer_direction.h"
+# include "xlat/sg_io_flags.h"
+
+static void
+print_sg_io_buffer(struct tcb *const tcp, const kernel_ulong_t addr,
+ const unsigned int data_size, const unsigned int iovec_count)
+{
+ if (iovec_count) {
+ tprint_iov_upto(tcp, iovec_count, addr, IOV_DECODE_STR,
+ data_size);
+ } else {
+ printstr_ex(tcp, addr, data_size, QUOTE_FORCE_HEX);
+ }
+}
+
+static int
+decode_request(struct tcb *const tcp, const kernel_ulong_t arg)
+{
+ struct_sg_io_hdr sg_io;
+ static const size_t skip_iid =
+ offsetof(struct_sg_io_hdr, dxfer_direction);
+
+ tprints("{interface_id='S', ");
+ if (umoven_or_printaddr(tcp, arg + skip_iid, sizeof(sg_io) - skip_iid,
+ &sg_io.dxfer_direction)) {
+ tprints("}");
+ return RVAL_DECODED | 1;
+ }
+
+ tprints("dxfer_direction=");
+ printxval(sg_io_dxfer_direction, sg_io.dxfer_direction,
+ "SG_DXFER_???");
+ tprintf(", cmd_len=%u, cmdp=", sg_io.cmd_len);
+ print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.cmdp), sg_io.cmd_len, 0);
+ tprintf(", mx_sb_len=%d", sg_io.mx_sb_len);
+ tprintf(", iovec_count=%d", sg_io.iovec_count);
+ tprintf(", dxfer_len=%u", sg_io.dxfer_len);
+ tprintf(", timeout=%u", sg_io.timeout);
+ tprints(", flags=");
+ printflags(sg_io_flags, sg_io.flags, "SG_FLAG_???");
+
+ if (sg_io.dxfer_direction == SG_DXFER_TO_DEV ||
+ sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
+ tprints(", dxferp=");
+ print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.dxferp),
+ sg_io.dxfer_len, sg_io.iovec_count);
+ }
+
+ struct_sg_io_hdr *entering_sg_io = malloc(sizeof(*entering_sg_io));
+ if (entering_sg_io) {
+ memcpy(entering_sg_io, &sg_io, sizeof(sg_io));
+ entering_sg_io->interface_id = (unsigned char) 'S';
+ set_tcb_priv_data(tcp, entering_sg_io, free);
+ }
+
+ return 1;
+}
+
+static int
+decode_response(struct tcb *const tcp, const kernel_ulong_t arg)
+{
+ struct_sg_io_hdr *entering_sg_io = get_tcb_priv_data(tcp);
+ struct_sg_io_hdr sg_io;
+
+ if (umove(tcp, arg, &sg_io) < 0) {
+ /* print i/o fields fetched on entering syscall */
+ if (entering_sg_io->dxfer_direction == SG_DXFER_FROM_DEV) {
+ tprints(", dxferp=");
+ printaddr(ptr_to_kulong(entering_sg_io->dxferp));
+ }
+ tprints(", sbp=");
+ printaddr(ptr_to_kulong(entering_sg_io->sbp));
+ return RVAL_DECODED | 1;
+ }
+
+ if (sg_io.interface_id != entering_sg_io->interface_id) {
+ tprintf(" => interface_id=%u", sg_io.interface_id);
+ return RVAL_DECODED | 1;
+ }
+
+ if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV ||
+ sg_io.dxfer_direction == SG_DXFER_TO_FROM_DEV) {
+ uint32_t din_len = sg_io.dxfer_len;
+
+ if (sg_io.resid > 0 && (unsigned int) sg_io.resid <= din_len)
+ din_len -= sg_io.resid;
+ if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV) {
+ tprints(", dxferp=");
+ } else if (din_len) {
+ tprints(" => dxferp=");
+ }
+ if (sg_io.dxfer_direction == SG_DXFER_FROM_DEV || din_len) {
+ print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.dxferp),
+ din_len, sg_io.iovec_count);
+ }
+ }
+ tprintf(", status=%#x", sg_io.status);
+ tprintf(", masked_status=%#x", sg_io.masked_status);
+ tprintf(", msg_status=%#x", sg_io.msg_status);
+ tprintf(", sb_len_wr=%u, sbp=", sg_io.sb_len_wr);
+ print_sg_io_buffer(tcp, ptr_to_kulong(sg_io.sbp), sg_io.sb_len_wr, 0);
+ tprintf(", host_status=%#x", sg_io.host_status);
+ tprintf(", driver_status=%#x", sg_io.driver_status);
+ tprintf(", resid=%d", sg_io.resid);
+ tprintf(", duration=%u", sg_io.duration);
+ tprints(", info=");
+ printflags(sg_io_info, sg_io.info, "SG_INFO_???");
+
+ return RVAL_DECODED | 1;
+}
+
+#else /* !HAVE_SCSI_SG_H */
+
+static int
+decode_request(struct tcb *const tcp, const kernel_ulong_t arg)
+{
+ tprints("{interface_id='S', ...}");
+ return RVAL_DECODED | 1;
+}
+
+static int
+decode_response(struct tcb *const tcp, const kernel_ulong_t arg)
+{
+ return 0;
+}
+
+#endif
+
+MPERS_PRINTER_DECL(int, decode_sg_io_v3,
+ struct tcb *const tcp, const kernel_ulong_t arg)
+{
+ return entering(tcp) ? decode_request(tcp, arg)
+ : decode_response(tcp, arg);
+}