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.
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.
#endif
extern int current_personality;
+extern const int personality_wordsize[];
struct sysent {
int nargs;
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;
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
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;
}
/* 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