From 4ebb4e3d312bb8215f4eea9130cce6bb8bdb972f Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 13 Dec 2006 17:08:08 +0000 Subject: 2006-12-10 Dmitry V. Levin 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 | 9 +++++++++ defs.h | 1 + io.c | 36 +++++++++++++++++++++++++++++------- util.c | 37 ++++++++++++++++++++++++++++++------- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08ae0dd..582599f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2006-12-10 Dmitry V. Levin + 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 f60b558..344e4e1 100644 --- 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 414fbbb..5896634 100644 --- 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 4b0a061..470cec7 100644 --- 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 -- cgit v1.2.3