]> granicus.if.org Git - strace/blobdiff - io.c
2003-07-28 Daniel Jacobowitz <drow@mvista.com>
[strace] / io.c
diff --git a/io.c b/io.c
index 823f9c3705c349f6e404e7f913d75827355c730e..65b48fdb96541e24d4c03b03ee1d3a604eea01f1 100644 (file)
--- a/io.c
+++ b/io.c
@@ -89,7 +89,7 @@ long addr;
                tprintf("[]");
                return;
        }
-         
+
        if ((iov = (struct iovec *) malloc(len * sizeof *iov)) == NULL) {
                fprintf(stderr, "No memory");
                return;
@@ -162,7 +162,7 @@ struct tcb *tcp;
 #else
                tprintf(", %lu, %llu", tcp->u_arg[2],
                                (((unsigned long long) tcp->u_arg[4]) << 32
-                                | tcp->u_arg[3]));
+                                | (unsigned) tcp->u_arg[3]));
 #endif
        }
        return 0;
@@ -181,7 +181,7 @@ struct tcb *tcp;
 #else
                tprintf(", %lu, %llu", tcp->u_arg[2],
                                (((unsigned long long) tcp->u_arg[4]) << 32
-                                | tcp->u_arg[3]));
+                                | (unsigned) tcp->u_arg[3]));
 #endif
        }
        return 0;
@@ -199,7 +199,7 @@ struct tcb *tcp;
        if (entering(tcp)) {
                tprintf("%ld, %ld, %llu, %lu", tcp->u_arg[0], tcp->u_arg[1],
                        (((unsigned long long) tcp->u_arg[3]) << 32 |
-                        tcp->u_arg[2]), tcp->u_arg[4]);
+                        (unsigned) tcp->u_arg[2]), tcp->u_arg[4]);
        } else {
                off_t offset;
 
@@ -231,6 +231,18 @@ struct tcb *tcp;
 #endif /* FREEBSD */
 
 #ifdef LINUX
+
+/* The SH4 ABI does allow long longs in odd-numbered registers, but
+   does not allow them to be split between registers and memory - and
+   there are only four argument registers for normal functions.  As a
+   result pread takes an extra padding argument before the offset.  This
+   was changed late in the 2.4 series (around 2.4.20).  */
+#if defined(SH)
+#define PREAD_OFFSET_ARG 4
+#else
+#define PREAD_OFFSET_ARG 3
+#endif
+
 int
 sys_pread(tcp)
 struct tcb *tcp;
@@ -242,8 +254,9 @@ struct tcb *tcp;
                        tprintf("%#lx", tcp->u_arg[1]);
                else
                        printstr(tcp, tcp->u_arg[1], tcp->u_rval);
+               ALIGN64 (tcp, PREAD_OFFSET_ARG); /* PowerPC alignment restriction */
                tprintf(", %lu, %llu", tcp->u_arg[2],
-                       *(unsigned long long *)&tcp->u_arg[3]);
+                       *(unsigned long long *)&tcp->u_arg[PREAD_OFFSET_ARG]);
        }
        return 0;
 }
@@ -255,8 +268,9 @@ struct tcb *tcp;
        if (entering(tcp)) {
                tprintf("%ld, ", tcp->u_arg[0]);
                printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+               ALIGN64 (tcp, PREAD_OFFSET_ARG); /* PowerPC alignment restriction */
                tprintf(", %lu, %llu", tcp->u_arg[2],
-                       *(unsigned long long *)&tcp->u_arg[3]);
+                       *(unsigned long long *)&tcp->u_arg[PREAD_OFFSET_ARG]);
        }
        return 0;
 }
@@ -280,6 +294,25 @@ struct tcb *tcp;
        return 0;
 }
 
+int
+sys_sendfile64(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               loff_t offset;
+
+               tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
+               if (!tcp->u_arg[2])
+                       tprintf("NULL");
+               else if (umove(tcp, tcp->u_arg[2], &offset) < 0)
+                       tprintf("%#lx", tcp->u_arg[2]);
+               else
+                       tprintf("[%llu]", (unsigned long long int) offset);
+               tprintf(", %lu", tcp->u_arg[3]);
+       }
+       return 0;
+}
+
 #endif /* LINUX */
 
 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
@@ -315,7 +348,7 @@ struct tcb *tcp;
        return 0;
 }
 #endif
+
 int
 sys_ioctl(tcp)
 struct tcb *tcp;
@@ -332,8 +365,11 @@ struct tcb *tcp;
                ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
        }
        else {
-               if (ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]) == 0)
+               int ret;
+               if (!(ret = ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2])))
                        tprintf(", %#lx", tcp->u_arg[2]);
+               else
+                       return ret - 1;
        }
        return 0;
 }