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