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.
diff --git a/util.c b/util.c
index 4b0a061..470cec7 100644
--- a/util.c
+++ b/util.c
@@ -556,13 +556,33 @@
 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 @@
                         /* 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