From 7845a42b39e59e904d01e75e21f7bc7eb6462560 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Thu, 17 Apr 2014 13:32:47 +0000 Subject: Fix preadv/pwritev offset decoding * util.c (printllval): Add align argument. * defs.h (printllval): Update prototype. (printllval_aligned, printllval_unaligned): New macros. * file.c (sys_readahead, sys_truncate64, sys_ftruncate64, sys_fadvise64, sys_fadvise64_64, sys_sync_file_range, sys_sync_file_range2, sys_fallocate): Replace printllval call with printllval_aligned. * io.c (sys_pread, sys_pwrite): Likewise. (sys_preadv, sys_pwritev): Replace printllval call with printllval_unaligned. * linux/arm/syscallent.h: Set the number of preadv and pwritev arguments to 5. * linux/mips/syscallent-o32.h: Likewise. * linux/powerpc/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/xtensa/syscallent.h: Likewise. Reported-by: Dima Kogan --- defs.h | 6 +++++- file.c | 24 ++++++++++++------------ io.c | 8 ++++---- linux/arm/syscallent.h | 4 ++-- linux/mips/syscallent-o32.h | 8 ++++---- linux/powerpc/syscallent.h | 4 ++-- linux/sh/syscallent.h | 4 ++-- linux/xtensa/syscallent.h | 4 ++-- util.c | 14 +++++++++----- 9 files changed, 42 insertions(+), 34 deletions(-) diff --git a/defs.h b/defs.h index f457d30..074c8f0 100644 --- a/defs.h +++ b/defs.h @@ -647,7 +647,11 @@ extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_b # define LONG_LONG(a,b) \ ((long long)((unsigned long long)(unsigned)(b) | ((unsigned long long)(a)<<32))) #endif -extern int printllval(struct tcb *, const char *, int); +extern int printllval(struct tcb *, const char *, int, bool); +#define printllval_aligned(tcp, fmt, arg) \ + printllval((tcp), (fmt), (arg), true) +#define printllval_unaligned(tcp, fmt, arg) \ + printllval((tcp), (fmt), (arg), false) extern void printxval(const struct xlat *, int, const char *); extern int printargs(struct tcb *); diff --git a/file.c b/file.c index d82f4d1..b6cc135 100644 --- a/file.c +++ b/file.c @@ -619,7 +619,7 @@ sys_readahead(struct tcb *tcp) if (entering(tcp)) { int argn; printfd(tcp, tcp->u_arg[0]); - argn = printllval(tcp, ", %lld", 1); + argn = printllval_aligned(tcp, ", %lld", 1); tprintf(", %ld", tcp->u_arg[argn]); } return 0; @@ -640,7 +640,7 @@ sys_truncate64(struct tcb *tcp) { if (entering(tcp)) { printpath(tcp, tcp->u_arg[0]); - printllval(tcp, ", %llu", 1); + printllval_aligned(tcp, ", %llu", 1); } return 0; } @@ -660,7 +660,7 @@ sys_ftruncate64(struct tcb *tcp) { if (entering(tcp)) { printfd(tcp, tcp->u_arg[0]); - printllval(tcp, ", %llu", 1); + printllval_aligned(tcp, ", %llu", 1); } return 0; } @@ -2663,7 +2663,7 @@ sys_fadvise64(struct tcb *tcp) if (entering(tcp)) { int argn; printfd(tcp, tcp->u_arg[0]); - argn = printllval(tcp, ", %lld", 1); + argn = printllval_aligned(tcp, ", %lld", 1); tprintf(", %ld, ", tcp->u_arg[argn++]); printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???"); } @@ -2676,8 +2676,8 @@ sys_fadvise64_64(struct tcb *tcp) if (entering(tcp)) { int argn; printfd(tcp, tcp->u_arg[0]); - argn = printllval(tcp, ", %lld, ", 1); - argn = printllval(tcp, "%lld, ", argn); + argn = printllval_aligned(tcp, ", %lld, ", 1); + argn = printllval_aligned(tcp, "%lld, ", argn); #if defined __ARM_EABI__ || defined AARCH64 || defined POWERPC || defined XTENSA printxval(advise, tcp->u_arg[1], "POSIX_FADV_???"); #else @@ -2700,8 +2700,8 @@ sys_sync_file_range(struct tcb *tcp) if (entering(tcp)) { int argn; printfd(tcp, tcp->u_arg[0]); - argn = printllval(tcp, ", %lld, ", 1); - argn = printllval(tcp, "%lld, ", argn); + argn = printllval_aligned(tcp, ", %lld, ", 1); + argn = printllval_aligned(tcp, "%lld, ", argn); printflags(sync_file_range_flags, tcp->u_arg[argn], "SYNC_FILE_RANGE_???"); } @@ -2716,8 +2716,8 @@ sys_sync_file_range2(struct tcb *tcp) printfd(tcp, tcp->u_arg[0]); printflags(sync_file_range_flags, 1, "SYNC_FILE_RANGE_???"); - argn = printllval(tcp, ", %lld, ", 2); - argn = printllval(tcp, "%lld, ", argn); + argn = printllval_aligned(tcp, ", %lld, ", 2); + argn = printllval_aligned(tcp, "%lld, ", argn); } return 0; } @@ -2729,8 +2729,8 @@ sys_fallocate(struct tcb *tcp) int argn; printfd(tcp, tcp->u_arg[0]); /* fd */ tprintf(", %#lo, ", tcp->u_arg[1]); /* mode */ - argn = printllval(tcp, "%llu, ", 2); /* offset */ - printllval(tcp, "%llu", argn); /* len */ + argn = printllval_aligned(tcp, "%llu, ", 2); /* offset */ + printllval_aligned(tcp, "%llu", argn); /* len */ } return 0; } diff --git a/io.c b/io.c index fac5615..f5458f7 100644 --- a/io.c +++ b/io.c @@ -199,7 +199,7 @@ sys_pread(struct tcb *tcp) else printstr(tcp, tcp->u_arg[1], tcp->u_rval); tprintf(", %lu, ", tcp->u_arg[2]); - printllval(tcp, "%llu", PREAD_OFFSET_ARG); + printllval_aligned(tcp, "%llu", PREAD_OFFSET_ARG); } return 0; } @@ -212,7 +212,7 @@ sys_pwrite(struct tcb *tcp) tprints(", "); printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); tprintf(", %lu, ", tcp->u_arg[2]); - printllval(tcp, "%llu", PREAD_OFFSET_ARG); + printllval_aligned(tcp, "%llu", PREAD_OFFSET_ARG); } return 0; } @@ -231,7 +231,7 @@ sys_preadv(struct tcb *tcp) } tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); tprintf(", %lu, ", tcp->u_arg[2]); - printllval(tcp, "%llu", PREAD_OFFSET_ARG); + printllval_unaligned(tcp, "%llu", 3); } return 0; } @@ -244,7 +244,7 @@ sys_pwritev(struct tcb *tcp) tprints(", "); tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1); tprintf(", %lu, ", tcp->u_arg[2]); - printllval(tcp, "%llu", PREAD_OFFSET_ARG); + printllval_unaligned(tcp, "%llu", 3); } return 0; } diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h index f9b2b9a..4f556f4 100644 --- a/linux/arm/syscallent.h +++ b/linux/arm/syscallent.h @@ -389,8 +389,8 @@ { 3, TD, sys_dup3, "dup3" }, /* 358 */ { 2, TD, sys_pipe2, "pipe2" }, /* 359 */ { 1, TD, sys_inotify_init1, "inotify_init1" }, /* 360 */ - { 6, TD, sys_preadv, "preadv" }, /* 361 */ - { 6, TD, sys_pwritev, "pwritev" }, /* 362 */ + { 5, TD, sys_preadv, "preadv" }, /* 361 */ + { 5, TD, sys_pwritev, "pwritev" }, /* 362 */ { 4, TP|TS, sys_rt_tgsigqueueinfo, "rt_tgsigqueueinfo"}, /* 363 */ { 5, TD, sys_perf_event_open, "perf_event_open"}, /* 364 */ { 5, TN, sys_recvmmsg, "recvmmsg" }, /* 365 */ diff --git a/linux/mips/syscallent-o32.h b/linux/mips/syscallent-o32.h index 0608f9d..859c618 100644 --- a/linux/mips/syscallent-o32.h +++ b/linux/mips/syscallent-o32.h @@ -330,8 +330,8 @@ { 3, TD, sys_dup3, "dup3" }, /* 4327 */ { 2, TD, sys_pipe2, "pipe2" }, /* 4328 */ { 1, TD, sys_inotify_init1, "inotify_init1" }, /* 4329 */ - { 6, TD, sys_preadv, "preadv" }, /* 4330 */ - { 6, TD, sys_pwritev, "pwritev" }, /* 4331 */ + { 5, TD, sys_preadv, "preadv" }, /* 4330 */ + { 5, TD, sys_pwritev, "pwritev" }, /* 4331 */ { 4, TP|TS, sys_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" }, /* 4332 */ { 5, TD, sys_perf_event_open, "perf_event_open" }, /* 4333 */ { 4, TN, sys_accept4, "accept4" }, /* 4334 */ @@ -680,8 +680,8 @@ { 3, TD, printargs, "o32_dup3" }, /* 4327 */ { 2, TD, printargs, "o32_pipe2" }, /* 4328 */ { 1, TD, printargs, "o32_inotify_init1" }, /* 4329 */ - { 6, TD, printargs, "o32_preadv" }, /* 4330 */ - { 6, TD, printargs, "o32_pwritev" }, /* 4331 */ + { 5, TD, printargs, "o32_preadv" }, /* 4330 */ + { 5, TD, printargs, "o32_pwritev" }, /* 4331 */ { 4, TP|TS, printargs, "o32_rt_tgsigqueueinfo" }, /* 4332 */ { 5, TD, printargs, "o32_perf_event_open" }, /* 4333 */ { 4, TN, printargs, "o32_accept4" }, /* 4334 */ diff --git a/linux/powerpc/syscallent.h b/linux/powerpc/syscallent.h index 6f0cb7c..8a50429 100644 --- a/linux/powerpc/syscallent.h +++ b/linux/powerpc/syscallent.h @@ -346,8 +346,8 @@ { 2, TD, sys_pipe2, "pipe2" }, /* 317 */ { 1, TD, sys_inotify_init1, "inotify_init1" }, /* 318 */ { 5, TD, sys_perf_event_open, "perf_event_open" }, /* 319 */ - { 6, TD, sys_preadv, "preadv" }, /* 320 */ - { 6, TD, sys_pwritev, "pwritev" }, /* 321 */ + { 5, TD, sys_preadv, "preadv" }, /* 320 */ + { 5, TD, sys_pwritev, "pwritev" }, /* 321 */ { 4, TP|TS, sys_rt_tgsigqueueinfo, "rt_tgsigqueueinfo" }, /* 322 */ { 2, TD, sys_fanotify_init, "fanotify_init" }, /* 323 */ { 6, TD|TF, sys_fanotify_mark, "fanotify_mark" }, /* 324 */ diff --git a/linux/sh/syscallent.h b/linux/sh/syscallent.h index bd337ae..ed5812d 100644 --- a/linux/sh/syscallent.h +++ b/linux/sh/syscallent.h @@ -363,8 +363,8 @@ { 3, TD, sys_dup3, "dup3" }, /* 330 */ { 2, TD, sys_pipe2, "pipe2" }, /* 331 */ { 1, TD, sys_inotify_init1, "inotify_init1" }, /* 332 */ - { 6, TD, sys_preadv, "preadv" }, /* 333 */ - { 6, TD, sys_pwritev, "pwritev" }, /* 334 */ + { 5, TD, sys_preadv, "preadv" }, /* 333 */ + { 5, TD, sys_pwritev, "pwritev" }, /* 334 */ { 4, TP|TS, sys_rt_tgsigqueueinfo, "rt_tgsigqueueinfo"}, /* 335 */ { 5, TD, sys_perf_event_open, "perf_event_open"}, /* 336 */ { 2, TD, sys_fanotify_init, "fanotify_init" }, /* 337 */ diff --git a/linux/xtensa/syscallent.h b/linux/xtensa/syscallent.h index 62cb40d..9034961 100644 --- a/linux/xtensa/syscallent.h +++ b/linux/xtensa/syscallent.h @@ -307,8 +307,8 @@ { 2, TD, sys_timerfd_gettime, "timerfd_gettime"}, /* 314 */ { 0, 0, printargs, "SYS_315" }, /* 315 */ { 2, TD, sys_eventfd2, "eventfd2" }, /* 316 */ - { 6, TD, sys_preadv, "preadv" }, /* 317 */ - { 6, TD, sys_pwritev, "pwritev" }, /* 318 */ + { 5, TD, sys_preadv, "preadv" }, /* 317 */ + { 5, TD, sys_pwritev, "pwritev" }, /* 318 */ [319] = { }, { 2, TD, sys_fanotify_init, "fanotify_init" }, /* 320 */ { 6, TD|TF, sys_fanotify_mark, "fanotify_mark" }, /* 321 */ diff --git a/util.c b/util.c index 85bb94c..d986f7c 100644 --- a/util.c +++ b/util.c @@ -225,7 +225,7 @@ printxval(const struct xlat *xlat, int val, const char *dflt) * argument. */ int -printllval(struct tcb *tcp, const char *format, int arg_no) +printllval(struct tcb *tcp, const char *format, int arg_no, bool align) { #if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG # if SUPPORTED_PERSONALITIES > 1 @@ -236,8 +236,10 @@ printllval(struct tcb *tcp, const char *format, int arg_no) # if SUPPORTED_PERSONALITIES > 1 } else { # if defined(AARCH64) || defined(POWERPC64) - /* Align arg_no to the next even number. */ - arg_no = (arg_no + 1) & 0xe; + if (align) { + /* Align arg_no to the next even number. */ + arg_no = (arg_no + 1) & 0xe; + } # endif tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1])); arg_no += 2; @@ -261,8 +263,10 @@ printllval(struct tcb *tcp, const char *format, int arg_no) defined LINUX_MIPSO32 || \ defined POWERPC || \ defined XTENSA - /* Align arg_no to the next even number. */ - arg_no = (arg_no + 1) & 0xe; + if (align) { + /* Align arg_no to the next even number. */ + arg_no = (arg_no + 1) & 0xe; + } # endif tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1])); arg_no += 2; -- cgit v1.2.3