]> granicus.if.org Git - strace/blobdiff - io.c
Move ioctl syscall parser to ioctl.c
[strace] / io.c
diff --git a/io.c b/io.c
index 0e9bb32de8758814ddbba55a72709d4397bfaa1b..eec496ad70d97e70e2fc0fb59751d0819cc7c4fa 100644 (file)
--- a/io.c
+++ b/io.c
 
 #include "defs.h"
 #include <fcntl.h>
-#if HAVE_SYS_UIO_H
-# include <sys/uio.h>
-#endif
+#include <sys/uio.h>
 
-int
-sys_read(struct tcb *tcp)
+SYS_FUNC(read)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -50,8 +47,7 @@ sys_read(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_write(struct tcb *tcp)
+SYS_FUNC(write)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -62,7 +58,6 @@ sys_write(struct tcb *tcp)
        return 0;
 }
 
-#if HAVE_SYS_UIO_H
 /*
  * data_size limits the cumulative size of printed data.
  * Example: recvmsg returing a short read.
@@ -115,7 +110,7 @@ tprint_iov_upto(struct tcb *tcp, unsigned long len, unsigned long addr, int deco
                        tprints("...");
                        break;
                }
-               if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) {
+               if (umoven(tcp, cur, sizeof_iov, &iov) < 0) {
                        tprints("?");
                        failed = 1;
                        break;
@@ -145,8 +140,7 @@ tprint_iov(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_io
        tprint_iov_upto(tcp, len, addr, decode_iov, (unsigned long) -1L);
 }
 
-int
-sys_readv(struct tcb *tcp)
+SYS_FUNC(readv)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -163,8 +157,7 @@ sys_readv(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_writev(struct tcb *tcp)
+SYS_FUNC(writev)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -174,7 +167,6 @@ sys_writev(struct tcb *tcp)
        }
        return 0;
 }
-#endif
 
 /* The SH4 ABI does allow long longs in odd-numbered registers, but
    does not allow them to be split between registers and memory - and
@@ -187,8 +179,7 @@ sys_writev(struct tcb *tcp)
 #define PREAD_OFFSET_ARG 3
 #endif
 
-int
-sys_pread(struct tcb *tcp)
+SYS_FUNC(pread)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -204,8 +195,7 @@ sys_pread(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_pwrite(struct tcb *tcp)
+SYS_FUNC(pwrite)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -217,9 +207,33 @@ sys_pwrite(struct tcb *tcp)
        return 0;
 }
 
-#if HAVE_SYS_UIO_H
-int
-sys_preadv(struct tcb *tcp)
+static void
+print_llu_from_low_high_val(struct tcb *tcp, int arg)
+{
+#if SIZEOF_LONG == SIZEOF_LONG_LONG
+# if SUPPORTED_PERSONALITIES > 1
+       if (current_wordsize == sizeof(long))
+# endif
+               tprintf("%lu", (unsigned long) tcp->u_arg[arg]);
+# if SUPPORTED_PERSONALITIES > 1
+       else
+               tprintf("%lu",
+                       ((unsigned long) tcp->u_arg[arg + 1] << current_wordsize * 8)
+                       | (unsigned long) tcp->u_arg[arg]);
+# endif
+#else
+# ifdef X32
+       if (current_personality == 0)
+               tprintf("%llu", (unsigned long long) tcp->ext_arg[arg]);
+       else
+# endif
+       tprintf("%llu",
+               ((unsigned long long) (unsigned long) tcp->u_arg[arg + 1] << sizeof(long) * 8)
+               | (unsigned long long) (unsigned long) tcp->u_arg[arg]);
+#endif
+}
+
+SYS_FUNC(preadv)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -231,49 +245,57 @@ sys_preadv(struct tcb *tcp)
                }
                tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1);
                tprintf(", %lu, ", tcp->u_arg[2]);
-               printllval(tcp, "%llu", PREAD_OFFSET_ARG);
+               print_llu_from_low_high_val(tcp, 3);
        }
        return 0;
 }
 
-int
-sys_pwritev(struct tcb *tcp)
+SYS_FUNC(pwritev)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
                tprints(", ");
                tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1);
                tprintf(", %lu, ", tcp->u_arg[2]);
-               printllval(tcp, "%llu", PREAD_OFFSET_ARG);
+               print_llu_from_low_high_val(tcp, 3);
        }
        return 0;
 }
-#endif /* HAVE_SYS_UIO_H */
 
-int
-sys_sendfile(struct tcb *tcp)
+static void
+print_off_t(struct tcb *tcp, long addr)
 {
-       if (entering(tcp)) {
-               off_t offset;
+       unsigned long offset;
+
+       if (!addr) {
+               tprints("NULL");
+               return;
+       }
+
+#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+       if (current_wordsize == 4) {
+               uint32_t off;
+
+               if (umove(tcp, addr, &off) < 0)
+                       tprintf("%#lx", addr);
+               else
+                       tprintf("[%u]", off);
+       } else
+#endif
+       if (umove(tcp, addr, &offset) < 0)
+               tprintf("%#lx", addr);
+       else
+               tprintf("[%lu]", offset);
+}
 
+SYS_FUNC(sendfile)
+{
+       if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
                tprints(", ");
                printfd(tcp, tcp->u_arg[1]);
                tprints(", ");
-               if (!tcp->u_arg[2])
-                       tprints("NULL");
-//FIXME: obviously bogus.
-//Probably should use explicit long.
-//Arches with long long offset param should use
-//sys_sendfile64, not this fn.
-               else if (umove(tcp, tcp->u_arg[2], &offset) < 0)
-                       tprintf("%#lx", tcp->u_arg[2]);
-               else
-#ifdef HAVE_LONG_LONG_OFF_T
-                       tprintf("[%llu]", offset);
-#else
-                       tprintf("[%lu]", offset);
-#endif
+               print_off_t(tcp, tcp->u_arg[2]);
                tprintf(", %lu", tcp->u_arg[3]);
        }
        return 0;
@@ -292,8 +314,7 @@ print_loff_t(struct tcb *tcp, long addr)
                tprintf("[%llu]", (unsigned long long int) offset);
 }
 
-int
-sys_sendfile64(struct tcb *tcp)
+SYS_FUNC(sendfile64)
 {
        if (entering(tcp)) {
                printfd(tcp, tcp->u_arg[0]);
@@ -306,24 +327,9 @@ sys_sendfile64(struct tcb *tcp)
        return 0;
 }
 
-static const struct xlat splice_flags[] = {
-#ifdef SPLICE_F_MOVE
-       { SPLICE_F_MOVE,     "SPLICE_F_MOVE"     },
-#endif
-#ifdef SPLICE_F_NONBLOCK
-       { SPLICE_F_NONBLOCK, "SPLICE_F_NONBLOCK" },
-#endif
-#ifdef SPLICE_F_MORE
-       { SPLICE_F_MORE,     "SPLICE_F_MORE"     },
-#endif
-#ifdef SPLICE_F_GIFT
-       { SPLICE_F_GIFT,     "SPLICE_F_GIFT"     },
-#endif
-       { 0,                 NULL                },
-};
+#include "xlat/splice_flags.h"
 
-int
-sys_tee(struct tcb *tcp)
+SYS_FUNC(tee)
 {
        if (entering(tcp)) {
                /* int fd_in */
@@ -340,8 +346,7 @@ sys_tee(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_splice(struct tcb *tcp)
+SYS_FUNC(splice)
 {
        if (entering(tcp)) {
                /* int fd_in */
@@ -364,8 +369,7 @@ sys_splice(struct tcb *tcp)
        return 0;
 }
 
-int
-sys_vmsplice(struct tcb *tcp)
+SYS_FUNC(vmsplice)
 {
        if (entering(tcp)) {
                /* int fd */
@@ -379,30 +383,3 @@ sys_vmsplice(struct tcb *tcp)
        }
        return 0;
 }
-
-int
-sys_ioctl(struct tcb *tcp)
-{
-       const struct_ioctlent *iop;
-
-       if (entering(tcp)) {
-               printfd(tcp, tcp->u_arg[0]);
-               tprints(", ");
-               iop = ioctl_lookup(tcp->u_arg[1]);
-               if (iop) {
-                       tprints(iop->symbol);
-                       while ((iop = ioctl_next_match(iop)))
-                               tprintf(" or %s", iop->symbol);
-               } else
-                       tprintf("%#lx", tcp->u_arg[1]);
-               ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
-       }
-       else {
-               int ret = ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
-               if (!ret)
-                       tprintf(", %#lx", tcp->u_arg[2]);
-               else
-                       return ret - 1;
-       }
-       return 0;
-}