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 <dima@secretsauce.net>
diff --git a/defs.h b/defs.h
index f457d30..074c8f0 100644
--- a/defs.h
+++ b/defs.h
@@ -647,7 +647,11 @@
 # 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 @@
 	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 @@
 {
 	if (entering(tcp)) {
 		printpath(tcp, tcp->u_arg[0]);
-		printllval(tcp, ", %llu", 1);
+		printllval_aligned(tcp, ", %llu", 1);
 	}
 	return 0;
 }
@@ -660,7 +660,7 @@
 {
 	if (entering(tcp)) {
 		printfd(tcp, tcp->u_arg[0]);
-		printllval(tcp, ", %llu", 1);
+		printllval_aligned(tcp, ", %llu", 1);
 	}
 	return 0;
 }
@@ -2663,7 +2663,7 @@
 	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 @@
 	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 @@
 	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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		}
 		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 @@
 		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 @@
  * 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 @@
 # 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 @@
      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;