* defs.h (umove_ulong_array_or_printaddr): New prototype.
* util.c (umove_ulong_array_or_printaddr): New function.
* desc.c (sys_pselect6): Use it instead of open-coding
a proxy struct parser for different personalities.
* io.c (tprint_iov_upto): Use it instead of open-coding
a struct iovec parser for different personalities.
* kexec.c (print_kexec_segments): Use it instead of open-coding
a struct kexec_segment parser for different personalities.
(print_seg): Pass arguments using an array.
#define umove_or_printaddr(pid, addr, objp) \
umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
extern int umove_ulong_or_printaddr(struct tcb *, long, unsigned long *);
+extern int umove_ulong_array_or_printaddr(struct tcb *, long, unsigned long *, size_t);
extern int umovestr(struct tcb *, long, unsigned int, char *);
extern int upeek(int pid, long, long *);
{
int rc = decode_select(tcp, tcp->u_arg, BITNESS_CURRENT);
if (entering(tcp)) {
- long r;
- struct {
- unsigned long ptr;
- unsigned long len;
- } data;
+ unsigned long data[2];
tprints(", ");
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- if (current_wordsize == 4) {
- struct {
- uint32_t ptr;
- uint32_t len;
- } data32;
- r = umove_or_printaddr(tcp, tcp->u_arg[5], &data32);
- data.ptr = data32.ptr;
- data.len = data32.len;
- } else
-#endif
- r = umove_or_printaddr(tcp, tcp->u_arg[5], &data);
- if (r == 0) {
+ if (!umove_ulong_array_or_printaddr(tcp, tcp->u_arg[5], data,
+ ARRAY_SIZE(data))) {
tprints("{");
- /* NB: kernel requires data.len == NSIG / 8 */
- print_sigset_addr_len(tcp, data.ptr, data.len);
- tprintf(", %lu}", data.len);
+ /* NB: kernel requires data[1] == NSIG / 8 */
+ print_sigset_addr_len(tcp, data[0], data[1]);
+ tprintf(", %lu}", data[1]);
}
}
return rc;
void
tprint_iov_upto(struct tcb *tcp, unsigned long len, unsigned long addr, int decode_iov, unsigned long data_size)
{
-#if 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 \
- (current_wordsize == 4 ? sizeof(iov.iov32) : sizeof(iov.iov64))
-#define iov_iov_base \
- (current_wordsize == 4 ? (uint64_t) iov.iov32.base : iov.iov64.base)
-#define iov_iov_len \
- (current_wordsize == 4 ? (uint64_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 iov[2];
unsigned long size, cur, end, abbrev_end;
+ const unsigned long sizeof_iov = current_wordsize * 2;
if (!len) {
tprints("[]");
tprints("...");
break;
}
- if (umoven_or_printaddr(tcp, cur, sizeof_iov, &iov))
+ if (umove_ulong_array_or_printaddr(tcp, cur, iov,
+ ARRAY_SIZE(iov)))
break;
tprints("{");
if (decode_iov) {
- unsigned long len = iov_iov_len;
+ unsigned long len = iov[1];
if (len > data_size)
len = data_size;
data_size -= len;
- printstr(tcp, (long) iov_iov_base, len);
+ printstr(tcp, iov[0], len);
} else
- printaddr((long) iov_iov_base);
- tprintf(", %lu}", (unsigned long)iov_iov_len);
+ printaddr(iov[0]);
+ tprintf(", %lu}", iov[1]);
}
tprints("]");
-#undef sizeof_iov
-#undef iov_iov_base
-#undef iov_iov_len
}
void
#endif
static void
-print_seg(const long seg_buf, const unsigned long seg_bufsz,
- const long seg_mem, const unsigned long seg_memsz)
+print_seg(const unsigned long *seg)
{
tprints("{");
- printaddr(seg_buf);
- tprintf(", %lu, ", seg_bufsz);
- printaddr(seg_mem);
- tprintf(", %lu}", seg_memsz);
+ printaddr(seg[0]);
+ tprintf(", %lu, ", seg[1]);
+ printaddr(seg[2]);
+ tprintf(", %lu}", seg[3]);
}
static void
print_kexec_segments(struct tcb *tcp, const unsigned long addr,
const unsigned long len)
{
-#if SUPPORTED_PERSONALITIES > 1
- union {
- struct { u_int32_t buf, bufsz, mem, memsz; } seg32;
- struct { u_int64_t buf, bufsz, mem, memsz; } seg64;
- } seg;
-# define sizeof_seg \
- (current_wordsize == 4 ? sizeof(seg.seg32) : sizeof(seg.seg64))
-# define seg_buf \
- (current_wordsize == 4 ? (uint64_t) seg.seg32.buf : seg.seg64.buf)
-# define seg_bufsz \
- (current_wordsize == 4 ? (uint64_t) seg.seg32.bufsz : seg.seg64.bufsz)
-# define seg_mem \
- (current_wordsize == 4 ? (uint64_t) seg.seg32.mem : seg.seg64.mem)
-# define seg_memsz \
- (current_wordsize == 4 ? (uint64_t) seg.seg32.memsz : seg.seg64.memsz)
-#else
- struct {
- void *buf;
- size_t bufsz;
- void *mem;
- size_t memsz;
- } seg;
-# define sizeof_seg sizeof(seg)
-# define seg_buf seg.buf
-# define seg_bufsz seg.bufsz
-# define seg_mem seg.mem
-# define seg_memsz seg.memsz
-#endif
+ unsigned long seg[4];
+ const size_t sizeof_seg = ARRAY_SIZE(seg) * current_wordsize;
unsigned int i;
if (!len) {
return;
}
- if (umoven_or_printaddr(tcp, addr, sizeof_seg, &seg))
+ if (umove_ulong_array_or_printaddr(tcp, addr, seg, ARRAY_SIZE(seg)))
return;
tprints("[");
- print_seg((unsigned long) seg_buf, seg_bufsz,
- (unsigned long) seg_mem, seg_memsz);
+ print_seg(seg);
for (i = 1; i < len; ++i) {
tprints(", ");
- if (umoven_or_printaddr(tcp, addr + i * sizeof_seg,
- sizeof_seg, &seg))
+ if (umove_ulong_array_or_printaddr(tcp,
+ addr + i * sizeof_seg,
+ seg, ARRAY_SIZE(seg)))
break;
- print_seg((unsigned long) seg_buf, seg_bufsz,
- (unsigned long) seg_mem, seg_memsz);
+ print_seg(seg);
}
tprints("]");
return umove_or_printaddr(tcp, addr, ptr);
}
+int
+umove_ulong_array_or_printaddr(struct tcb *tcp, const long addr,
+ unsigned long *ptr, size_t n)
+{
+ if (current_wordsize < sizeof(*ptr)) {
+ uint32_t ptr32[n];
+ int r = umove_or_printaddr(tcp, addr, &ptr32);
+ if (!r) {
+ size_t i;
+
+ for (i = 0; i < n; ++i)
+ ptr[i] = (unsigned long) ptr32[i];
+ }
+ return r;
+ }
+ return umoven_or_printaddr(tcp, addr, n * sizeof(*ptr), ptr);
+}
+
/*
* Like `umove' but make the additional effort of looking
* for a terminating zero byte.