]> granicus.if.org Git - strace/commitdiff
2006-12-10 Dmitry V. Levin <ldv@altlinux.org>
authorDmitry V. Levin <ldv@altlinux.org>
Wed, 13 Dec 2006 17:08:08 +0000 (17:08 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 13 Dec 2006 17:08:08 +0000 (17:08 +0000)
Add biarch support for "struct iovec".
* defs.h (personality_wordsize): Add.
* io.c [HAVE_SYS_UIO_H] (tprint_iov): [LINUX &&
SUPPORTED_PERSONALITIES > 1] Handle 32-bit personality.
* util.c [HAVE_SYS_UIO_H] (dumpiov): [LINUX &&
SUPPORTED_PERSONALITIES > 1] Likewise.
Patch from Jakub Jelinek.
Fixes RH#218433.

ChangeLog
defs.h
io.c
util.c

index 08ae0dd4fa0116e79f284b35bbb246ae2cc8bf09..582599f7824b148e157c38c8ac85fe4b6bd993b8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2006-12-10  Dmitry V. Levin <ldv@altlinux.org>
 
+       Add biarch support for "struct iovec".
+       * defs.h (personality_wordsize): Add.
+       * io.c [HAVE_SYS_UIO_H] (tprint_iov): [LINUX &&
+       SUPPORTED_PERSONALITIES > 1] Handle 32-bit personality.
+       * util.c [HAVE_SYS_UIO_H] (dumpiov): [LINUX &&
+       SUPPORTED_PERSONALITIES > 1] Likewise.
+       Patch from Jakub Jelinek.
+       Fixes RH#218433.
+
        * time.c (sys_timer_create): Check umove() return code.
 
        Make several global variables static.
diff --git a/defs.h b/defs.h
index f60b558d7019c33ed294356211469667f4d7344c..344e4e1a2613987aec3fb5e7593b86246db7a27e 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -531,6 +531,7 @@ const char *strsignal P((int));
 #endif
 
 extern int current_personality;
+extern const int personality_wordsize[];
 
 struct sysent {
        int     nargs;
diff --git a/io.c b/io.c
index 414fbbb38b6ad7a88deee065a5fc5347a3a6d56e..5896634e13241f05b7e773f7574d3891c83eedd2 100644 (file)
--- a/io.c
+++ b/io.c
@@ -81,7 +81,26 @@ struct tcb * tcp;
 unsigned long len;
 unsigned long addr;
 {
+#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
+       union {
+               struct { u_int32_t base; u_int32_t len; } iov32;
+               struct { u_int64_t base; u_int64_t len; } iov64;
+       } iov;
+#define sizeof_iov \
+  (personality_wordsize[current_personality] == 4 \
+   ? sizeof(iov.iov32) : sizeof(iov.iov64))
+#define iov_iov_base \
+  (personality_wordsize[current_personality] == 4 \
+   ? (u_int64_t) iov.iov32.base : iov.iov64.base)
+#define iov_iov_len \
+  (personality_wordsize[current_personality] == 4 \
+   ? (u_int64_t) iov.iov32.len : iov.iov64.len)
+#else
        struct iovec iov;
+#define sizeof_iov sizeof(iov)
+#define iov_iov_base iov.iov_base
+#define iov_iov_len iov.iov_len
+#endif
        unsigned long size, cur, end, abbrev_end;
        int failed = 0;
 
@@ -89,39 +108,42 @@ unsigned long addr;
                tprintf("[]");
                return;
        }
-       size = len * sizeof(iov);
+       size = len * sizeof_iov;
        end = addr + size;
-       if (!verbose(tcp) || size / sizeof(iov) != len || end < addr) {
+       if (!verbose(tcp) || size / sizeof_iov != len || end < addr) {
                tprintf("%#lx", addr);
                return;
        }
        if (abbrev(tcp)) {
-               abbrev_end = addr + max_strlen * sizeof(iov);
+               abbrev_end = addr + max_strlen * sizeof_iov;
                if (abbrev_end < addr)
                        abbrev_end = end;
        } else {
                abbrev_end = end;
        }
        tprintf("[");
-       for (cur = addr; cur < end; cur += sizeof(iov)) {
+       for (cur = addr; cur < end; cur += sizeof_iov) {
                if (cur > addr)
                        tprintf(", ");
                if (cur >= abbrev_end) {
                        tprintf("...");
                        break;
                }
-               if (umoven(tcp, cur, sizeof iov, (char *) &iov) < 0) {
+               if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) {
                        tprintf("?");
                        failed = 1;
                        break;
                }
                tprintf("{");
-               printstr(tcp, (long) iov.iov_base, iov.iov_len);
-               tprintf(", %lu}", (unsigned long)iov.iov_len);
+               printstr(tcp, (long) iov_iov_base, iov_iov_len);
+               tprintf(", %lu}", (unsigned long)iov_iov_len);
        }
        tprintf("]");
        if (failed)
                tprintf(" %#lx", addr);
+#undef sizeof_iov
+#undef iov_iov_base
+#undef iov_iov_len
 }
 
 int
diff --git a/util.c b/util.c
index 4b0a0616efab6ec7fa0309785f52e92c64a58371..470cec73b225fcca2545dcc764087a3fb99b7999 100644 (file)
--- a/util.c
+++ b/util.c
@@ -556,13 +556,33 @@ struct tcb * tcp;
 int len;
 long addr;
 {
+#if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
+       union {
+               struct { u_int32_t base; u_int32_t len; } *iov32;
+               struct { u_int64_t base; u_int64_t len; } *iov64;
+       } iovu;
+#define iov iovu.iov64
+#define sizeof_iov \
+  (personality_wordsize[current_personality] == 4 \
+   ? sizeof(*iovu.iov32) : sizeof(*iovu.iov64))
+#define iov_iov_base(i) \
+  (personality_wordsize[current_personality] == 4 \
+   ? (u_int64_t) iovu.iov32[i].base : iovu.iov64[i].base)
+#define iov_iov_len(i) \
+  (personality_wordsize[current_personality] == 4 \
+   ? (u_int64_t) iovu.iov32[i].len : iovu.iov64[i].len)
+#else
        struct iovec *iov;
+#define sizeof_iov sizeof(*iov)
+#define iov_iov_base(i) iov[i].iov_base
+#define iov_iov_len(i) iov[i].iov_len
+#endif
        int i;
        unsigned long size;
 
-       size = sizeof(*iov) * (unsigned long) len;
-       if (size / sizeof(*iov) != len
-           || (iov = (struct iovec *) malloc(size)) == NULL) {
+       size = sizeof_iov * (unsigned long) len;
+       if (size / sizeof_iov != len
+           || (iov = malloc(size)) == NULL) {
                fprintf(stderr, "out of memory\n");
                return;
        }
@@ -571,13 +591,16 @@ long addr;
                         /* include the buffer number to make it easy to
                          * match up the trace with the source */
                         tprintf(" * %lu bytes in buffer %d\n",
-                                (unsigned long)iov[i].iov_len, i);
-                        dumpstr(tcp, (long) iov[i].iov_base,
-                                iov[i].iov_len);
+                                (unsigned long)iov_iov_len(i), i);
+                        dumpstr(tcp, (long) iov_iov_base(i),
+                                iov_iov_len(i));
                 }
        }
        free((char *) iov);
-
+#undef sizeof_iov
+#undef iov_iov_base
+#undef iov_iov_len
+#undef iov
 }
 #endif