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.
This commit is contained in:
Дмитрий Левин 2006-12-13 17:08:08 +00:00
parent ac518d1077
commit 4ebb4e3d31
4 changed files with 69 additions and 14 deletions

View File

@ -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.

1
defs.h
View File

@ -531,6 +531,7 @@ const char *strsignal P((int));
#endif
extern int current_personality;
extern const int personality_wordsize[];
struct sysent {
int nargs;

36
io.c
View File

@ -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

37
util.c
View File

@ -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