summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2006-12-13 17:08:08 +0000
committerDmitry V. Levin <ldv@altlinux.org>2006-12-13 17:08:08 +0000
commit4ebb4e3d312bb8215f4eea9130cce6bb8bdb972f (patch)
tree7c8f9230f535868e4c3b28d1471ab5525fed618b
parentac518d10777f9dd95aad22939da6c867cf4c193e (diff)
downloadstrace-4ebb4e3d312bb8215f4eea9130cce6bb8bdb972f.tar.gz
strace-4ebb4e3d312bb8215f4eea9130cce6bb8bdb972f.tar.bz2
strace-4ebb4e3d312bb8215f4eea9130cce6bb8bdb972f.tar.xz
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.
-rw-r--r--ChangeLog9
-rw-r--r--defs.h1
-rw-r--r--io.c36
-rw-r--r--util.c37
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 <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 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