Merge "Merge remote-tracking branch 'aosp/upstream-master' into merge"
diff --git a/.mailmap b/.mailmap
index a04a2f8..b8565ae 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,7 +1,9 @@
 # Map git author names and email addresses to canonical/preferred form.
 <ak@linux.intel.com>	<ak@suse.de>
+<dgilbert@redhat.com>	<dave@treblig.org>
 <holger@freyther.de>	<zecke@selfish.org>
 <kirill@shutemov.name>	<kirill.shutemov@linux.intel.com>
 <schwab@linux-m68k.org>	<schwab@redhat.com>
 <schwab@linux-m68k.org>	<schwab@suse.de>
 <vda.linux@googlemail.com>	<dvlasenk@redhat.com>
+Eugene Syromyatnikov	<evgsyr@gmail.com>
diff --git a/.travis.yml b/.travis.yml
index d3307a0..0eba591 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,3 +39,6 @@
     - compiler: clang-3.6
       env:
         - TARGET=x86
+    - compiler: musl-gcc
+      env:
+        - TARGET=x86
diff --git a/Android.mk b/Android.mk
index a75a812..717d60c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -74,8 +74,9 @@
     fetch_struct_flock.c \
     fetch_struct_mmsghdr.c \
     fetch_struct_msghdr.c \
+    fetch_struct_stat.c \
+    fetch_struct_stat64.c \
     fetch_struct_statfs.c \
-    file.c \
     file_handle.c \
     file_ioctl.c \
     flock.c \
@@ -121,6 +122,7 @@
     net.c \
     netlink.c \
     numa.c \
+    oldstat.c \
     open.c \
     pathtrace.c \
     perf.c \
@@ -131,6 +133,7 @@
     print_msgbuf.c \
     print_sigevent.c \
     print_statfs.c \
+    print_struct_stat.c \
     print_time.c \
     print_timex.c \
     printmode.c \
@@ -159,6 +162,8 @@
     socketcall.c \
     socketutils.c \
     sram_alloc.c \
+    stat.c \
+    stat64.c \
     statfs.c \
     statfs64.c \
     strace.c \
@@ -242,7 +247,6 @@
     -DHAVE_SIGINFO_T_SI_OVERRUN=1 \
     -DHAVE_SIGINFO_T_SI_SYSCALL=1 \
     -DHAVE_SIGINFO_T_SI_TIMERID=1 \
-    -UHAVE_STAT64 \
     -DHAVE_STATFS64=1 \
     -DHAVE_STDBOOL_H=1 \
     -DHAVE_STRERROR=1 \
@@ -290,7 +294,7 @@
 
 LOCAL_CFLAGS += -fno-strict-aliasing
 
-LOCAL_CFLAGS_32 += -DSIZEOF_LONG=4 -DSIZEOF_RLIM_T=4 -DHAVE_STAT64=1
+LOCAL_CFLAGS_32 += -DSIZEOF_LONG=4 -DSIZEOF_RLIM_T=4 -DHAVE_STRUCT_STAT64=1
 LOCAL_CFLAGS_64 += -DSIZEOF_LONG=8 -DSIZEOF_RLIM_T=8
 
 LOCAL_CFLAGS_arm += -DARM=1
diff --git a/Makefile.am b/Makefile.am
index 1e7554e..d1ad1fe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -112,8 +112,9 @@
 	fetch_struct_flock.c \
 	fetch_struct_mmsghdr.c \
 	fetch_struct_msghdr.c \
+	fetch_struct_stat.c \
+	fetch_struct_stat64.c \
 	fetch_struct_statfs.c \
-	file.c		\
 	file_handle.c	\
 	file_ioctl.c	\
 	fs_x_ioctl.c	\
@@ -147,6 +148,7 @@
 	link.c		\
 	linux/asm_stat.h \
 	linux/x32/asm_stat.h \
+	linux/x86_64/asm_stat.h \
 	lookup_dcookie.c \
 	loop.c		\
 	lseek.c		\
@@ -165,6 +167,7 @@
 	net.c		\
 	netlink.c       \
 	numa.c		\
+	oldstat.c	\
 	open.c		\
 	or1k_atomic.c	\
 	pathtrace.c	\
@@ -176,13 +179,13 @@
 	print_msgbuf.c	\
 	print_sigevent.c \
 	print_statfs.c	\
+	print_struct_stat.c \
 	print_time.c	\
 	print_timex.c	\
 	printmode.c	\
 	printrusage.c	\
 	printsiginfo.c	\
 	printsiginfo.h	\
-	printstat.h	\
 	process.c	\
 	process_vm.c	\
 	ptp.c		\
@@ -209,6 +212,9 @@
 	sockaddr.c	\
 	socketutils.c	\
 	sram_alloc.c	\
+	stat.c		\
+	stat.h		\
+	stat64.c	\
 	statfs.c	\
 	statfs.h	\
 	strace.c	\
@@ -250,7 +256,7 @@
 @CODE_COVERAGE_RULES@
 CODE_COVERAGE_BRANCH_COVERAGE = 1
 CODE_COVERAGE_GENHTML_OPTIONS = $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) \
-	--prefix $(shell realpath -Ls $(abs_top_srcdir)/..)
+	--prefix $(shell cd $(abs_top_srcdir)/.. && pwd || echo .)
 CODE_COVERAGE_IGNORE_PATTERN = '/usr/include/*'
 strace_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
 strace_CFLAGS += $(CODE_COVERAGE_CFLAGS)
@@ -497,6 +503,18 @@
 	linux/powerpc64/syscallent1.h	\
 	linux/powerpc64/userent.h	\
 	linux/ptp_clock.h		\
+	linux/riscv/arch_regs.c		\
+	linux/riscv/errnoent1.h		\
+	linux/riscv/get_error.c		\
+	linux/riscv/get_scno.c		\
+	linux/riscv/get_syscall_args.c	\
+	linux/riscv/ioctls_arch0.h	\
+	linux/riscv/ioctls_arch1.h	\
+	linux/riscv/ioctls_inc0.h	\
+	linux/riscv/ioctls_inc1.h	\
+	linux/riscv/signalent1.h	\
+	linux/riscv/syscallent.h	\
+	linux/riscv/syscallent1.h	\
 	linux/s390/arch_regs.c		\
 	linux/s390/arch_regs.h		\
 	linux/s390/arch_sigreturn.c	\
@@ -713,7 +731,7 @@
 ioctl_redefs%.h: ioctlent%.h ioctlent0.h
 	sort $< > $<-t
 	sort ioctlent0.h | comm -23 $<-t - | \
-		sed -n 's/^{ "\([^"]\+\)", \(0x[[:xdigit:]]\+\) },$$/#ifdef \1\n# undef \1\n# define \1 \2\n#endif/p' \
+		sed -r -n 's/^\{ "([^"]+)", (0x[[:xdigit:]]+) \},$$/#ifdef \1\n# undef \1\n# define \1 \2\n#endif/p' \
 		> $@-t
 	rm -f $<-t
 	mv $@-t $@
@@ -754,7 +772,7 @@
 
 mpers-m%.stamp: $(srcdir_mpers_source_files) | printers.h
 	for f in $^; do \
-		CC="$(CC)" CFLAGS="$(mpers_sh_opts)" \
+		CC="$(CC)" CFLAGS="$(mpers_sh_opts) -DMPERS_IS_$(mpers_NAME)" \
 		CPP="$(CPP)" CPPFLAGS="$(mpers_sh_opts) -DIN_MPERS -DMPERS_IS_$(mpers_NAME)" \
 		$(srcdir)/mpers.sh -$(mpers_NAME) $$f || exit; \
 	done
@@ -762,7 +780,7 @@
 
 m%_type_defs.h: $(srcdir_mpers_source_files)
 	for f in $^; do \
-		sed -n 's/^#include DEF_MPERS_TYPE(\([^)]\+\))/#ifdef MPERS_$(mpers_PREFIX)\1\n# define \1 MPERS_$(mpers_PREFIX)\1\n#endif/p' $$f || exit; \
+		sed -r -n 's/^#include DEF_MPERS_TYPE\(([^)]+)\)/#ifdef MPERS_$(mpers_PREFIX)\1\n# define \1 MPERS_$(mpers_PREFIX)\1\n#endif/p' $$f || exit; \
 	done > $@-t
 	echo '#undef MPERS_PRINTER_NAME' >> $@-t
 	echo '#define MPERS_PRINTER_NAME(printer_name) printer_name' >> $@-t
@@ -772,7 +790,7 @@
 
 m%_funcs.h: $(srcdir_mpers_source_files)
 	for f in $^; do \
-		sed -n 's/^SYS_FUNC(\([^)]\+\))/#undef sys_\1\n#define sys_\1 $(mpers_PREFIX)sys_\1/p' $$f || exit; \
+		sed -r -n 's/^SYS_FUNC\(([^)]+)\)/#undef sys_\1\n#define sys_\1 $(mpers_PREFIX)sys_\1/p' $$f || exit; \
 	done > $@-t && \
 	echo '#include "sys_func.h"' >> $@-t
 	mv $@-t $@
@@ -782,13 +800,13 @@
 %.c.mpers.i: $(srcdir)/%.c
 	$(CPP) -P $(mpers_sh_opts) -DIN_MPERS_BOOTSTRAP $< -o $@
 
-mpers_printer_decl_pattern = ^MPERS_PRINTER_DECL(\([^,)]\+\),[[:space:]]*\([^,)]\+\),[[:space:]]*\([^)]\+\))$$
+mpers_printer_decl_pattern = ^MPERS_PRINTER_DECL\(([^,)]+),[[:space:]]*([^,)]+),[[:space:]]*([^)]+)\)$$
 
 printers.h: $(mpers_preproc_files)
 	echo '/* Generated by Makefile from $^; do not edit. */' > $@-t
 	echo 'typedef struct {' >> $@-t
 	for f in $^; do \
-		sed -n 's/$(mpers_printer_decl_pattern)/ \1 (*\2)(\3);\n#define \2 MPERS_PRINTER_NAME(\2)\n/p' $$f \
+		sed -r -n 's/$(mpers_printer_decl_pattern)/ \1 (*\2)(\3);\n#define \2 MPERS_PRINTER_NAME(\2)\n/p' $$f \
 		|| exit; \
 	done >> $@-t
 	echo '} struct_printers;' >> $@-t
@@ -799,7 +817,7 @@
 %_printer_decls.h: $(mpers_preproc_files)
 	echo '/* Generated by Makefile from $^; do not edit. */' > $@-t
 	for f in $^; do \
-		sed -n 's/$(mpers_printer_decl_pattern)/extern \1 $(mpers_PREFIX)\2(\3);/p' $$f \
+		sed -r -n 's/$(mpers_printer_decl_pattern)/extern \1 $(mpers_PREFIX)\2(\3);/p' $$f \
 		|| exit; \
 	done >> $@-t
 	mv $@-t $@
@@ -807,7 +825,7 @@
 %_printer_defs.h: $(mpers_preproc_files)
 	echo '/* Generated by Makefile from $^; do not edit. */' > $@-t
 	for f in $^; do \
-		sed -n 's/$(mpers_printer_decl_pattern)/\.\2 = $(mpers_PREFIX)\2,/p' $$f \
+		sed -r -n 's/$(mpers_printer_decl_pattern)/.\2 = $(mpers_PREFIX)\2,/p' $$f \
 		|| exit; \
 	done >> $@-t
 	mv $@-t $@
@@ -869,7 +887,7 @@
 	(								\
 	  cd $(srcdir);							\
 	  sed '/^##/,$$d' CREDITS.in;					\
-	  { sed -n '1,/^##>/d; s/  \+/\t/; s/^./&/p' CREDITS.in;	\
+	  { sed -n '1,/^##>/d; s/   */\t/; s/^./&/p' CREDITS.in;	\
 	    git log --pretty=format:'%aN	%aE';			\
 	  } | LC_ALL=C sort -u						\
 	    | awk -F'\t' '{printf("\t%s <%s>\n",$$1,$$2)}';		\
diff --git a/NEWS b/NEWS
index 19a870d..47ffe02 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,40 @@
-Noteworthy changes in release ?.?? (????-??-??)
+Noteworthy changes in release 4.14 (2016-10-04)
 ===============================================
 
+* Changes in behavior
+  * When using -p option without a command and no processes has been attached,
+    strace exits with exit status 1.
+
+* Improvements
+  * Added printing of the mode argument of open and openat syscalls
+    when O_TMPFILE flag is set.  (Addresses Fedora bug #1377846).
+  * Enhanced -e abbrev=set, -e raw=set, and -e verbose=set.
+  * Enhanced decoding of futex, keyctl, quotactl, timerfd_settime,
+    and aio family syscalls.
+  * Implemented fetching of the 7th subcall argument on mips o32.
+  * Updated lists of BPF_*, ETH_P_*, KEXEC_ARCH_*, SCTP_*, TCP_*, and *_MAGIC
+    constants.
+  * Updated lists of ioctl commands from Linux 4.8.
+  * Added decoding of new syscalls on sh and sh64.
+  * Added RISC-V architecture support.
+
+* Bug fixes
+  * Marked io_setup and io_destroy as memory mapping related syscalls.
+  * Fixed leakage of placeholder descriptors to tracees.
+  * Fixed printing of mode_t, umode_t, and umask types.
+  * Fixed decoding of iovec arrays without a limit on total data size.
+  * Fixed decoding of fadvise64, fallocate, futex, keyctl, quotactl, readahead,
+    and ipc family syscalls.
+  * Fixed decoding of invalid syscalls mapped to indirect subcalls.
+  * Fixed decoding of struct btrfs_ioctl_vol_args_v2 on non-native
+    personalities.
+  * Fixed decoding of PTRACE_DETACH on sparc and sparc64.
+  * Fixed decoding of struct stat64 on sparc64.
+  * Fixed decoding of uid and gid-related syscalls on sparc64.
+  * Fixed decoding of the forth argument of semctl syscall on sparc64.
+  * Fixed values of tty ioctl constants on sparc64.
+  * Fixed sparc personality support on sparc64.
+
 Noteworthy changes in release 4.13 (2016-07-26)
 ===============================================
 
diff --git a/aio.c b/aio.c
index 29562d2..7caccdd 100644
--- a/aio.c
+++ b/aio.c
@@ -36,13 +36,13 @@
 	if (entering(tcp))
 		tprintf("%u, ", (unsigned int) tcp->u_arg[0]);
 	else
-		printnum_ulong(tcp, tcp->u_arg[1]);
+		printnum_ptr(tcp, tcp->u_arg[1]);
 	return 0;
 }
 
 SYS_FUNC(io_destroy)
 {
-	tprintf("%lu", tcp->u_arg[0]);
+	printaddr(tcp->u_arg[0]);
 
 	return RVAL_DECODED;
 }
@@ -78,12 +78,14 @@
 }
 
 static void
-print_common_flags(const struct iocb *cb)
+print_common_flags(struct tcb *tcp, const struct iocb *cb)
 {
 /* IOCB_FLAG_RESFD is available since v2.6.22-rc1~47 */
 #ifdef IOCB_FLAG_RESFD
-	if (cb->aio_flags & IOCB_FLAG_RESFD)
-		tprintf(", resfd=%d", cb->aio_resfd);
+	if (cb->aio_flags & IOCB_FLAG_RESFD) {
+		tprints(", resfd=");
+		printfd(tcp, cb->aio_resfd);
+	}
 	if (cb->aio_flags & ~IOCB_FLAG_RESFD)
 		tprintf(", flags=%x", cb->aio_flags);
 #endif
@@ -98,7 +100,7 @@
 }
 
 static enum iocb_sub
-print_iocb_header(const struct iocb *cb)
+print_iocb_header(struct tcb *tcp, const struct iocb *cb)
 {
 	enum iocb_sub sub;
 
@@ -113,7 +115,8 @@
 	if (cb->aio_reqprio)
 		tprintf(", reqprio=%hd", cb->aio_reqprio);
 
-	tprintf(", fildes=%d", cb->aio_fildes);
+	tprints(", fildes=");
+	printfd(tcp, cb->aio_fildes);
 
 	return sub;
 }
@@ -121,7 +124,7 @@
 static void
 print_iocb(struct tcb *tcp, const struct iocb *cb)
 {
-	enum iocb_sub sub = print_iocb_header(cb);
+	enum iocb_sub sub = print_iocb_header(tcp, cb);
 
 	switch (sub) {
 	case SUB_COMMON:
@@ -134,7 +137,7 @@
 		}
 		tprintf(", nbytes=%" PRIu64 ", offset=%" PRId64,
 			(uint64_t) cb->aio_nbytes, (int64_t) cb->aio_offset);
-		print_common_flags(cb);
+		print_common_flags(tcp, cb);
 		break;
 	case SUB_VECTOR:
 		if (iocb_is_valid(cb)) {
@@ -149,7 +152,7 @@
 				(uint64_t) cb->aio_nbytes);
 		}
 		tprintf(", offset=%" PRId64, (int64_t) cb->aio_offset);
-		print_common_flags(cb);
+		print_common_flags(tcp, cb);
 		break;
 	case SUB_NONE:
 		break;
@@ -182,7 +185,8 @@
 	const unsigned long addr = tcp->u_arg[2];
 	unsigned long iocbp;
 
-	tprintf("%lu, %ld, ", tcp->u_arg[0], nr);
+	printaddr(tcp->u_arg[0]);
+	tprintf(", %ld, ", nr);
 
 	if (nr < 0)
 		printaddr(addr);
@@ -209,12 +213,14 @@
 SYS_FUNC(io_cancel)
 {
 	if (entering(tcp)) {
-		tprintf("%lu, ", tcp->u_arg[0]);
+		printaddr(tcp->u_arg[0]);
+		tprints(", ");
+
 		struct iocb cb;
 
 		if (!umove_or_printaddr(tcp, tcp->u_arg[1], &cb)) {
 			tprints("{");
-			print_iocb_header(&cb);
+			print_iocb_header(tcp, &cb);
 			tprints("}");
 		}
 		tprints(", ");
@@ -230,8 +236,8 @@
 SYS_FUNC(io_getevents)
 {
 	if (entering(tcp)) {
-		tprintf("%lu, %ld, %ld, ",
-			tcp->u_arg[0],
+		printaddr(tcp->u_arg[0]);
+		tprintf(", %ld, %ld, ",
 			widen_to_long(tcp->u_arg[1]),
 			widen_to_long(tcp->u_arg[2]));
 	} else {
diff --git a/bootstrap b/bootstrap
index 395fc80..f7ef6f7 100755
--- a/bootstrap
+++ b/bootstrap
@@ -5,7 +5,9 @@
 	rm -rf $tests
 	mkdir $tests
 	s='[[:space:]]*'
-	sed "s/@arch@/@arch_$m@/;s/^MPERS_NAME$s=.*/& $m/;s/^ARCH_MFLAGS$s=.*/& -$m/" \
+	sed "s/@arch@/@arch_$m@/;
+	     s/^MPERS_NAME$s=.*/& $m/;
+	     s/^ARCH_MFLAGS$s=.*/& -DMPERS_IS_\$(MPERS_NAME) -$m/" \
 		tests/Makefile.am > $tests/Makefile.am
 	for f in tests/*; do
 		case "${f##*/}" in
diff --git a/btrfs.c b/btrfs.c
index 9c71768..1306cef 100644
--- a/btrfs.c
+++ b/btrfs.c
@@ -32,6 +32,7 @@
 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_dev_replace_args)
 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_send_args)
 #include DEF_MPERS_TYPE(struct_btrfs_ioctl_received_subvol_args)
+#include DEF_MPERS_TYPE(struct_btrfs_ioctl_vol_args_v2)
 
 # include <linux/btrfs.h>
 
@@ -41,6 +42,8 @@
 	struct_btrfs_ioctl_send_args;
 typedef struct btrfs_ioctl_received_subvol_args
 	struct_btrfs_ioctl_received_subvol_args;
+typedef struct btrfs_ioctl_vol_args_v2
+	struct_btrfs_ioctl_vol_args_v2;
 
 #endif /* HAVE_LINUX_BTRFS_H */
 
@@ -373,14 +376,14 @@
 }
 
 static void
-btrfs_print_qgroup_inherit(struct tcb *tcp, const uint64_t qgi_addr)
+btrfs_print_qgroup_inherit(struct tcb *tcp, const unsigned long qgi_addr)
 {
 	struct btrfs_qgroup_inherit inherit;
 
 	if (umove_or_printaddr(tcp, qgi_addr, &inherit))
 		return;
 
-	tprintf("{flags=");
+	tprints("{flags=");
 	printflags64(btrfs_qgroup_inherit_flags, inherit.flags,
 		     "BTRFS_QGROUP_INHERIT_???");
 	tprintf(", num_qgroups=%" PRI__u64 ", num_ref_copies=%" PRI__u64
@@ -420,7 +423,7 @@
 			uint64_t buf_addr, uint64_t buf_size, bool print_size)
 {
 	if (entering(tcp)) {
-		tprintf("{key={tree_id=");
+		tprints("{key={tree_id=");
 		btrfs_print_objectid(key->tree_id);
 
 		if (key->min_objectid != BTRFS_FIRST_FREE_OBJECTID ||
@@ -1294,7 +1297,7 @@
 
 	case BTRFS_IOC_SNAP_CREATE_V2:
 	case BTRFS_IOC_SUBVOL_CREATE_V2: { /* code is W, but is actually RW */
-		struct btrfs_ioctl_vol_args_v2 args;
+		struct_btrfs_ioctl_vol_args_v2 args;
 
 		if (entering(tcp))
 			tprints(", ");
@@ -1313,19 +1316,19 @@
 			printflags64(btrfs_snap_flags_v2, args.flags,
 				     "BTRFS_SUBVOL_???");
 			if (args.flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
-				tprintf(", size=%" PRI__u64 ", qgroup_inherit=",
-					args.size);
+				tprintf(", size=%llu, qgroup_inherit=",
+					(unsigned long long) args.size);
 
 				btrfs_print_qgroup_inherit(tcp,
-					(unsigned long)args.qgroup_inherit);
+					(unsigned long) args.qgroup_inherit);
 			}
-			tprintf(", name=");
+			tprints(", name=");
 			print_quoted_string(args.name, sizeof(args.name),
 					    QUOTE_0_TERMINATED);
 			tprints("}");
 			return 0;
 		}
-		tprintf("{transid=%" PRI__u64 "}", args.transid);
+		tprintf("{transid=%llu}", (unsigned long long) args.transid);
 		break;
 	}
 
diff --git a/chmod.c b/chmod.c
index 83741c9..fd76490 100644
--- a/chmod.c
+++ b/chmod.c
@@ -4,7 +4,8 @@
 decode_chmod(struct tcb *tcp, const int offset)
 {
 	printpath(tcp, tcp->u_arg[offset]);
-	tprintf(", %#lo", tcp->u_arg[offset + 1]);
+	tprints(", ");
+	print_numeric_umode_t(tcp->u_arg[offset + 1]);
 }
 
 SYS_FUNC(chmod)
@@ -25,7 +26,8 @@
 SYS_FUNC(fchmod)
 {
 	printfd(tcp, tcp->u_arg[0]);
-	tprintf(", %#lo", tcp->u_arg[1]);
+	tprints(", ");
+	print_numeric_umode_t(tcp->u_arg[1]);
 
 	return RVAL_DECODED;
 }
diff --git a/clone.c b/clone.c
index 99d0da7..604a695 100644
--- a/clone.c
+++ b/clone.c
@@ -42,10 +42,10 @@
 #if defined IA64
 # define ARG_FLAGS	0
 # define ARG_STACK	1
-# define ARG_STACKSIZE	(tcp->scno == SYS_clone2 ? 2 : -1)
-# define ARG_PTID	(tcp->scno == SYS_clone2 ? 3 : 2)
-# define ARG_CTID	(tcp->scno == SYS_clone2 ? 4 : 3)
-# define ARG_TLS	(tcp->scno == SYS_clone2 ? 5 : 4)
+# define ARG_STACKSIZE	(tcp->scno == __NR_clone2 ? 2 : -1)
+# define ARG_PTID	(tcp->scno == __NR_clone2 ? 3 : 2)
+# define ARG_CTID	(tcp->scno == __NR_clone2 ? 4 : 3)
+# define ARG_TLS	(tcp->scno == __NR_clone2 ? 5 : 4)
 #elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
 # define ARG_STACK	0
 # define ARG_FLAGS	1
@@ -59,7 +59,7 @@
 # define ARG_PTID	2
 # define ARG_CTID	((current_personality != 1) ? 3 : 4)
 # define ARG_TLS	((current_personality != 1) ? 4 : 3)
-#elif defined ALPHA || defined TILE || defined OR1K
+#elif defined ALPHA || defined TILE || defined OR1K || defined RISCV
 # define ARG_FLAGS	0
 # define ARG_STACK	1
 # define ARG_PTID	2
diff --git a/configure.ac b/configure.ac
index 4af1649..404dfb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -187,6 +187,11 @@
 	AC_DEFINE([XTENSA], 1, [Define for the Xtensa architecture])
 	;;
 
+riscv*)
+	arch=riscv
+	AC_DEFINE([RISCV], 1, [Define for the RISC-V architecture])
+	;;
+
 *)
 	AC_MSG_RESULT([NO!])
 	AC_MSG_ERROR([architecture $host_cpu is not supported by strace])
@@ -202,6 +207,7 @@
 AC_SUBST(arch_m32)
 AC_SUBST(arch_mx32)
 
+MIPS_ABI=
 if test "$arch" = mips; then
 	AC_CACHE_CHECK([for _MIPS_SIM], [st_cv__MIPS_SIM],
 		       [AC_COMPUTE_INT([st_cv__MIPS_SIM], [_MIPS_SIM],
@@ -229,7 +235,9 @@
 		n64) AC_DEFINE([LINUX_MIPSN64], [1], [Define for _MIPS_SIM_ABI64.]);;
 		*) AC_MSG_ERROR([Unsupported _MIPS_SIM]);;
 	esac
+	MIPS_ABI="$st_cv_mips_abi"
 fi
+AC_SUBST(MIPS_ABI)
 
 AC_ARG_ENABLE([arm-oabi],
 	      [AS_HELP_STRING([--enable-arm-oabi],
@@ -267,22 +275,13 @@
 AC_SUBST([WARN_CFLAGS])
 
 AC_C_BIGENDIAN
-AC_C_CONST
 AC_C_TYPEOF
 
-AC_TYPE_GETGROUPS
-AC_TYPE_MODE_T
-AC_TYPE_SIGNAL
 AC_TYPE_UID_T
 
-AC_HEADER_DIRENT
-AC_HEADER_MAJOR
-AC_HEADER_STAT
-AC_HEADER_STDBOOL
-AC_HEADER_STDC
-
 AC_CHECK_FUNCS(m4_normalize([
 	accept4
+	fallocate
 	fanotify_mark
 	fopen64
 	fork
@@ -297,7 +296,7 @@
 	preadv
 	process_vm_readv
 	pwritev
-	sigaction
+	readahead
 	signalfd
 	stpcpy
 	strerror
@@ -317,6 +316,12 @@
 [#include <sys/types.h>
 #include <asm/stat.h>])
 
+AC_CHECK_MEMBERS([struct stat.st_mtime_nsec, struct stat64.st_mtime_nsec],,,
+[#include <sys/types.h>
+#include <asm/stat.h>])
+
+AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec])
+
 AC_CHECK_TYPES(m4_normalize([
 	struct pt_all_user_regs,
 	struct ia64_fpreg,
@@ -332,30 +337,11 @@
 [#include <sys/types.h>
 #include <linux/fcntl.h>])
 
-AC_CHECK_MEMBERS(m4_normalize([
-	struct stat.st_atim.tv_nsec,
-	struct stat.st_blksize,
-	struct stat.st_blocks,
-	struct stat.st_ctim.tv_nsec,
-	struct stat.st_flags,
-	struct stat.st_fstype,
-	struct stat.st_gen,
-	struct stat.st_mtim.tv_nsec,
-	struct stat.st_rdev
-]))
-
 AC_CHECK_MEMBERS([struct timex.tai],,, [#include <sys/timex.h>])
 
 AC_CHECK_MEMBERS([struct utsname.domainname],,, [#include <sys/utsname.h>])
 
 AC_CHECK_MEMBERS(m4_normalize([
-	struct stat.st_atime_nsec,
-	struct stat.st_ctime_nsec,
-	struct stat.st_mtime_nsec
-]),,, [#include <sys/types.h>
-#include <asm/stat.h>])
-
-AC_CHECK_MEMBERS(m4_normalize([
 	siginfo_t.si_syscall,
 	siginfo_t.si_timerid,
 	siginfo_t.si_overrun
@@ -368,6 +354,7 @@
 	elf.h
 	inttypes.h
 	linux/bsg.h
+	linux/dqblk_xfs.h
 	linux/falloc.h
 	linux/fiemap.h
 	linux/filter.h
@@ -377,6 +364,7 @@
 	linux/mmtimer.h
 	linux/msg.h
 	linux/perf_event.h
+	linux/quota.h
 	linux/seccomp.h
 	linux/securebits.h
 	linux/sem.h
@@ -393,6 +381,7 @@
 	sys/fanotify.h
 	sys/ipc.h
 	sys/msg.h
+	sys/quota.h
 	sys/reg.h
 	sys/sem.h
 	sys/shm.h
diff --git a/defs.h b/defs.h
index 4b7e8ed..2b4118b 100644
--- a/defs.h
+++ b/defs.h
@@ -27,20 +27,19 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_DEFS_H
+#define STRACE_DEFS_H
+
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
 #include <features.h>
-#ifdef HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
+#include <stdbool.h>
 #include <stdint.h>
 #include <inttypes.h>
 #include <sys/types.h>
-#ifdef STDC_HEADERS
-# include <stddef.h>
-#endif
+#include <stddef.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -52,7 +51,7 @@
 #include <errno.h>
 #include <time.h>
 #include <sys/time.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #include "mpers_type.h"
 #include "gcc_compat.h"
@@ -69,11 +68,6 @@
 extern char *stpcpy(char *dst, const char *src);
 #endif
 
-#ifndef offsetof
-# define offsetof(type, member)	\
-	(((char *) &(((type *) NULL)->member)) - ((char *) (type *) NULL))
-#endif
-
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 /* macros */
@@ -148,130 +142,53 @@
 # define ERESTART_RESTARTBLOCK 516
 #endif
 
-#if defined(SPARC) || defined(SPARC64)
-# define PERSONALITY0_WORDSIZE 4
-# if defined(SPARC64)
-#  define SUPPORTED_PERSONALITIES 2
-#  define PERSONALITY1_WORDSIZE 8
-#  ifdef HAVE_M32_MPERS
-#   define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
-#   define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
-#   define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
-#   define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
-#  endif
-# endif
-#endif
-
-#ifdef X86_64
+#if defined X86_64
 # define SUPPORTED_PERSONALITIES 3
-# define PERSONALITY0_WORDSIZE 8
-# define PERSONALITY1_WORDSIZE 4
 # define PERSONALITY2_WORDSIZE 4
-# ifdef HAVE_M32_MPERS
-#  define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
-#  define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
-# endif
-# ifdef HAVE_MX32_MPERS
-#  define PERSONALITY2_INCLUDE_FUNCS "mx32_funcs.h"
-#  define PERSONALITY2_INCLUDE_PRINTERS_DECLS "mx32_printer_decls.h"
-#  define PERSONALITY2_INCLUDE_PRINTERS_DEFS "mx32_printer_defs.h"
-#  define MPERS_mx32_IOCTL_MACROS "ioctl_redefs2.h"
-# endif
-#endif
-
-#ifdef X32
+#elif defined AARCH64 \
+   || defined POWERPC64 \
+   || defined RISCV \
+   || defined SPARC64 \
+   || defined TILE \
+   || defined X32
 # define SUPPORTED_PERSONALITIES 2
-# define PERSONALITY0_WORDSIZE 4
-# define PERSONALITY1_WORDSIZE 4
-# ifdef HAVE_M32_MPERS
-#  define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
-#  define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
-# endif
-#endif
-
-#ifdef ARM
-/* one personality */
-#endif
-
-#ifdef AARCH64
-/* The existing ARM personality, then AArch64 */
-# define SUPPORTED_PERSONALITIES 2
-# define PERSONALITY0_WORDSIZE 8
-# define PERSONALITY1_WORDSIZE 4
-# ifdef HAVE_M32_MPERS
-#  define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
-#  define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
-# endif
-#endif
-
-#ifdef POWERPC64
-# define SUPPORTED_PERSONALITIES 2
-# define PERSONALITY0_WORDSIZE 8
-# define PERSONALITY1_WORDSIZE 4
-# ifdef HAVE_M32_MPERS
-#  define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
-#  define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
-# endif
-#endif
-
-#ifdef TILE
-# define SUPPORTED_PERSONALITIES 2
-# define PERSONALITY0_WORDSIZE 8
-# define PERSONALITY1_WORDSIZE 4
-# ifdef __tilepro__
-#  define DEFAULT_PERSONALITY 1
-# endif
-# ifdef HAVE_M32_MPERS
-#  define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
-#  define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
-#  define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
-# endif
-#endif
-
-#ifndef SUPPORTED_PERSONALITIES
+#else
 # define SUPPORTED_PERSONALITIES 1
 #endif
-#ifndef DEFAULT_PERSONALITY
+
+#if defined TILE && defined __tilepro__
+# define DEFAULT_PERSONALITY 1
+#else
 # define DEFAULT_PERSONALITY 0
 #endif
-#ifndef PERSONALITY0_WORDSIZE
-# define PERSONALITY0_WORDSIZE SIZEOF_LONG
+
+#define PERSONALITY0_WORDSIZE SIZEOF_LONG
+#define PERSONALITY0_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
+#define PERSONALITY0_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
+
+#if SUPPORTED_PERSONALITIES > 1
+# define PERSONALITY1_WORDSIZE 4
 #endif
 
-#ifndef PERSONALITY0_INCLUDE_PRINTERS_DECLS
-# define PERSONALITY0_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
-#endif
-#ifndef PERSONALITY0_INCLUDE_PRINTERS_DEFS
-# define PERSONALITY0_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
-#endif
-
-#ifndef PERSONALITY1_INCLUDE_PRINTERS_DECLS
+#if SUPPORTED_PERSONALITIES > 1 && defined HAVE_M32_MPERS
+# define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
+# define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
+# define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
+# define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
+#else
 # define PERSONALITY1_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
-#endif
-#ifndef PERSONALITY1_INCLUDE_PRINTERS_DEFS
 # define PERSONALITY1_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
-#endif
-
-#ifndef PERSONALITY2_INCLUDE_PRINTERS_DECLS
-# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
-#endif
-#ifndef PERSONALITY2_INCLUDE_PRINTERS_DEFS
-# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
-#endif
-
-#ifndef PERSONALITY1_INCLUDE_FUNCS
 # define PERSONALITY1_INCLUDE_FUNCS "empty.h"
 #endif
-#ifndef PERSONALITY2_INCLUDE_FUNCS
+
+#if SUPPORTED_PERSONALITIES > 2 && defined HAVE_MX32_MPERS
+# define PERSONALITY2_INCLUDE_FUNCS "mx32_funcs.h"
+# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "mx32_printer_decls.h"
+# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "mx32_printer_defs.h"
+# define MPERS_mx32_IOCTL_MACROS "ioctl_redefs2.h"
+#else
+# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
+# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
 # define PERSONALITY2_INCLUDE_FUNCS "empty.h"
 #endif
 
@@ -299,7 +216,7 @@
 	int flags;		/* See below for TCB_ values */
 	int pid;		/* If 0, this tcb is free */
 	int qual_flg;		/* qual_flags[scno] or DEFAULT_QUAL_FLAGS + RAW */
-	int u_error;		/* Error code */
+	unsigned long u_error;	/* Error code */
 	long scno;		/* System call number */
 	long u_arg[MAX_ARGS];	/* System call arguments */
 #if HAVE_STRUCT_TCB_EXT_ARG
@@ -432,6 +349,7 @@
  || defined(BFIN) \
  || defined(M68K) \
  || defined(MICROBLAZE) \
+ || defined(RISCV) \
  || defined(S390) \
  || defined(SH) || defined(SH64) \
  || defined(SPARC) || defined(SPARC64) \
@@ -528,6 +446,7 @@
 extern void get_regs(pid_t pid);
 extern int get_scno(struct tcb *tcp);
 extern const char *syscall_name(long scno);
+extern const char *err_name(unsigned long err);
 
 extern bool is_erestart(struct tcb *);
 extern void temporarily_clear_syserror(struct tcb *);
@@ -594,8 +513,9 @@
 extern int string_to_uint(const char *str);
 extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits);
 
-#define QUOTE_0_TERMINATED			0x01
-#define QUOTE_OMIT_LEADING_TRAILING_QUOTES	0x02
+#define QUOTE_0_TERMINATED                      0x01
+#define QUOTE_OMIT_LEADING_TRAILING_QUOTES      0x02
+#define QUOTE_OMIT_TRAILING_0                   0x08
 
 extern int string_quote(const char *, char *, unsigned int, unsigned int);
 extern int print_quoted_string(const char *, unsigned int, unsigned int);
@@ -617,6 +537,8 @@
 extern void printaddr(long);
 extern void printxvals(const uint64_t, const char *, const struct xlat *, ...)
 	ATTRIBUTE_SENTINEL;
+extern long long getarg_ll(struct tcb *tcp, int argn);
+extern unsigned long long getarg_ull(struct tcb *tcp, int argn);
 extern int printargs(struct tcb *);
 extern int printargs_u(struct tcb *);
 extern int printargs_d(struct tcb *);
@@ -624,15 +546,18 @@
 extern void addflags(const struct xlat *, uint64_t);
 extern int printflags64(const struct xlat *, uint64_t, const char *);
 extern const char *sprintflags(const char *, const struct xlat *, uint64_t);
-extern const char *sprintmode(unsigned int);
 extern const char *sprinttime(time_t);
+extern void print_symbolic_mode_t(unsigned int);
+extern void print_numeric_umode_t(unsigned short);
+extern void print_numeric_long_umask(unsigned long);
 extern void dumpiov_in_msghdr(struct tcb *, long, unsigned long);
 extern void dumpiov_in_mmsghdr(struct tcb *, long);
 extern void dumpiov_upto(struct tcb *, int, long, unsigned long);
 #define dumpiov(tcp, len, addr) \
 	dumpiov_upto((tcp), (len), (addr), (unsigned long) -1L)
 extern void dumpstr(struct tcb *, long, int);
-extern void printstr(struct tcb *, long, long);
+extern void printstr_ex(struct tcb *, long addr, long len,
+	unsigned int user_style);
 extern bool printnum_short(struct tcb *, long, const char *)
 	ATTRIBUTE_FORMAT((printf, 3, 0));
 extern bool printnum_int(struct tcb *, long, const char *)
@@ -702,6 +627,9 @@
 extern void print_seccomp_filter(struct tcb *, unsigned long);
 extern void print_seccomp_fprog(struct tcb *, unsigned long, unsigned short);
 
+struct strace_stat;
+extern void print_struct_stat(struct tcb *tcp, const struct strace_stat *const st);
+
 struct strace_statfs;
 extern void print_struct_statfs(struct tcb *tcp, long);
 extern void print_struct_statfs64(struct tcb *tcp, long, unsigned long);
@@ -735,6 +663,12 @@
 extern void unwind_capture_stacktrace(struct tcb* tcp);
 #endif
 
+static inline void
+printstr(struct tcb *tcp, long addr, long len)
+{
+	printstr_ex(tcp, addr, len, 0);
+}
+
 static inline int
 printflags(const struct xlat *x, unsigned int flags, const char *dflt)
 {
@@ -818,13 +752,25 @@
 #endif
 
 /*
- * Widen without sign-extension a signed integer type to unsigned long long.
+ * Zero-extend a signed integer type to unsigned long long.
  */
-#define widen_to_ull(v) \
-	(sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
+#define zero_extend_signed_to_ull(v) \
+	(sizeof(v) == sizeof(char) ? (unsigned long long) (unsigned char) (v) : \
+	 sizeof(v) == sizeof(short) ? (unsigned long long) (unsigned short) (v) : \
+	 sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
 	 sizeof(v) == sizeof(long) ? (unsigned long long) (unsigned long) (v) : \
 	 (unsigned long long) (v))
 
+/*
+ * Sign-extend an unsigned integer type to long long.
+ */
+#define sign_extend_unsigned_to_ll(v) \
+	(sizeof(v) == sizeof(char) ? (long long) (char) (v) : \
+	 sizeof(v) == sizeof(short) ? (long long) (short) (v) : \
+	 sizeof(v) == sizeof(int) ? (long long) (int) (v) : \
+	 sizeof(v) == sizeof(long) ? (long long) (long) (v) : \
+	 (long long) (v))
+
 extern const struct_sysent sysent0[];
 extern const char *const errnoent0[];
 extern const char *const signalent0[];
@@ -863,10 +809,13 @@
 #endif /* !IN_MPERS_BOOTSTRAP */
 
 /*
- * If you need non-NULL sysent[scno].sys_func and sysent[scno].sys_name
+ * If you need non-NULL sysent[scno].sys_func, non-NULL sysent[scno].sys_name,
+ * and non-indirect sysent[scno].sys_flags.
  */
 #define SCNO_IS_VALID(scno) \
-	((unsigned long)(scno) < nsyscalls && sysent[scno].sys_func)
+	((unsigned long)(scno) < nsyscalls \
+	 && sysent[scno].sys_func \
+	 && !(sysent[scno].sys_flags & TRACE_INDIRECT_SUBCALL))
 
 /* Only ensures that sysent[scno] isn't out of range */
 #define SCNO_IN_RANGE(scno) \
@@ -899,3 +848,5 @@
 #define PRI__d64 PRI__64"d"
 #define PRI__u64 PRI__64"u"
 #define PRI__x64 PRI__64"x"
+
+#endif /* !STRACE_DEFS_H */
diff --git a/dirent.c b/dirent.c
index 75e3635..c277675 100644
--- a/dirent.c
+++ b/dirent.c
@@ -48,8 +48,8 @@
 		return;
 
 	tprintf("{d_ino=%llu, d_off=%llu, d_reclen=%u, d_name=",
-		widen_to_ull(d.d_ino),
-		widen_to_ull(d.d_off), d.d_reclen);
+		zero_extend_signed_to_ull(d.d_ino),
+		zero_extend_signed_to_ull(d.d_off), d.d_reclen);
 	if (d.d_reclen > D_NAME_LEN_MAX)
 		d.d_reclen = D_NAME_LEN_MAX;
 	printpathn(tcp, addr + offsetof(kernel_dirent, d_name), d.d_reclen);
@@ -127,8 +127,9 @@
 
 			tprintf("%s{d_ino=%llu, d_off=%llu, d_reclen=%u"
 				", d_name=", i ? ", " : "",
-				widen_to_ull(d->d_ino),
-				widen_to_ull(d->d_off), d->d_reclen);
+				zero_extend_signed_to_ull(d->d_ino),
+				zero_extend_signed_to_ull(d->d_off),
+				d->d_reclen);
 
 			if (print_quoted_string(d->d_name, d_name_len,
 					        QUOTE_0_TERMINATED) > 0) {
diff --git a/evdev.c b/evdev.c
index b7b6402..b24f9d3 100644
--- a/evdev.c
+++ b/evdev.c
@@ -37,7 +37,7 @@
 
 typedef struct ff_effect struct_ff_effect;
 
-#endif /* HAVE_LINUX_BTRFS_H */
+#endif /* HAVE_LINUX_INPUT_H */
 
 #include MPERS_DEFS
 
diff --git a/fadvise.c b/fadvise.c
index 2001394..34933f7 100644
--- a/fadvise.c
+++ b/fadvise.c
@@ -42,7 +42,7 @@
 
 	printfd(tcp, tcp->u_arg[0]);
 	argn = printllval(tcp, ", %lld", 1);
-	tprintf(", %ld, ", tcp->u_arg[argn++]);
+	tprintf(", %llu, ", getarg_ull(tcp, argn++));
 	printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
 
 	return RVAL_DECODED;
diff --git a/fallocate.c b/fallocate.c
index 0b1cfec..b707279 100644
--- a/fallocate.c
+++ b/fallocate.c
@@ -19,10 +19,10 @@
 	tprints(", ");
 
 	/* offset */
-	argn = printllval(tcp, "%llu, ", 2);
+	argn = printllval(tcp, "%lld, ", 2);
 
 	/* len */
-	printllval(tcp, "%llu", argn);
+	printllval(tcp, "%lld", argn);
 
 	return RVAL_DECODED;
 }
diff --git a/fetch_struct_stat.c b/fetch_struct_stat.c
new file mode 100644
index 0000000..399b78c
--- /dev/null
+++ b/fetch_struct_stat.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#include DEF_MPERS_TYPE(struct_stat)
+
+#include "asm_stat.h"
+
+#if defined MPERS_IS_m32
+# undef HAVE_STRUCT_STAT
+# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+# ifdef HAVE_M32_STRUCT_STAT
+#  define HAVE_STRUCT_STAT 1
+#  ifdef HAVE_M32_STRUCT_STAT_ST_MTIME_NSEC
+#   define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#  endif /* HAVE_M32_STRUCT_STAT_ST_MTIME_NSEC */
+# endif /* HAVE_M32_STRUCT_STAT */
+#elif defined MPERS_IS_mx32
+# undef HAVE_STRUCT_STAT
+# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+# ifdef HAVE_MX32_STRUCT_STAT
+#  define HAVE_STRUCT_STAT 1
+#  ifdef HAVE_MX32_STRUCT_STAT_ST_MTIME_NSEC
+#   define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#  endif /* HAVE_MX32_STRUCT_STAT_ST_MTIME_NSEC */
+# endif /* HAVE_MX32_STRUCT_STAT */
+#else /* !MPERS_IS_m32 && !MPERS_IS_mx32 */
+# define HAVE_STRUCT_STAT 1
+#endif
+
+#ifndef HAVE_STRUCT_STAT
+struct stat {};
+#endif
+
+typedef struct stat struct_stat;
+
+#include MPERS_DEFS
+
+#include "stat.h"
+
+#ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+# define TIME_NSEC(arg) zero_extend_signed_to_ull(arg)
+#else
+# define TIME_NSEC(arg) 0
+#endif
+
+MPERS_PRINTER_DECL(bool, fetch_struct_stat,
+		   struct tcb *tcp, const unsigned long addr,
+		   struct strace_stat *const dst)
+{
+#ifdef HAVE_STRUCT_STAT
+	struct_stat buf;
+	if (umove_or_printaddr(tcp, addr, &buf))
+		return false;
+
+	dst->dev = zero_extend_signed_to_ull(buf.st_dev);
+	dst->ino = zero_extend_signed_to_ull(buf.st_ino);
+	dst->rdev = zero_extend_signed_to_ull(buf.st_rdev);
+	dst->size = zero_extend_signed_to_ull(buf.st_size);
+	dst->blocks = zero_extend_signed_to_ull(buf.st_blocks);
+	dst->blksize = zero_extend_signed_to_ull(buf.st_blksize);
+	dst->mode = zero_extend_signed_to_ull(buf.st_mode);
+	dst->nlink = zero_extend_signed_to_ull(buf.st_nlink);
+	dst->uid = zero_extend_signed_to_ull(buf.st_uid);
+	dst->gid = zero_extend_signed_to_ull(buf.st_gid);
+	dst->atime = sign_extend_unsigned_to_ll(buf.st_atime);
+	dst->ctime = sign_extend_unsigned_to_ll(buf.st_ctime);
+	dst->mtime = sign_extend_unsigned_to_ll(buf.st_mtime);
+	dst->atime_nsec = TIME_NSEC(buf.st_atime_nsec);
+	dst->ctime_nsec = TIME_NSEC(buf.st_ctime_nsec);
+	dst->mtime_nsec = TIME_NSEC(buf.st_mtime_nsec);
+	return true;
+#else /* !HAVE_STRUCT_STAT */
+	printaddr(addr);
+	return false;
+#endif
+}
diff --git a/fetch_struct_stat64.c b/fetch_struct_stat64.c
new file mode 100644
index 0000000..b7281b5
--- /dev/null
+++ b/fetch_struct_stat64.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+
+#include DEF_MPERS_TYPE(struct_stat64)
+
+#include "asm_stat.h"
+
+#if defined MPERS_IS_m32
+# undef HAVE_STRUCT_STAT64
+# undef HAVE_STRUCT_STAT64_ST_MTIME_NSEC
+# ifdef HAVE_M32_STRUCT_STAT64
+#  define HAVE_STRUCT_STAT64 1
+#  ifdef HAVE_M32_STRUCT_STAT64_ST_MTIME_NSEC
+#   define HAVE_STRUCT_STAT64_ST_MTIME_NSEC 1
+#  endif /* HAVE_M32_STRUCT_STAT64_ST_MTIME_NSEC */
+# endif /* HAVE_M32_STRUCT_STAT64 */
+#elif defined MPERS_IS_mx32
+# undef HAVE_STRUCT_STAT64
+# undef HAVE_STRUCT_STAT64_ST_MTIME_NSEC
+# ifdef HAVE_MX32_STRUCT_STAT64
+#  define HAVE_STRUCT_STAT64 1
+#  ifdef HAVE_MX32_STRUCT_STAT64_ST_MTIME_NSEC
+#   define HAVE_STRUCT_STAT64_ST_MTIME_NSEC 1
+#  endif /* HAVE_MX32_STRUCT_STAT64_ST_MTIME_NSEC */
+# endif /* HAVE_MX32_STRUCT_STAT64 */
+#endif /* MPERS_IS_m32 || MPERS_IS_mx32 */
+
+#ifndef HAVE_STRUCT_STAT64
+struct stat64 {};
+#endif
+
+typedef struct stat64 struct_stat64;
+
+#include MPERS_DEFS
+
+#include "stat.h"
+
+#ifdef HAVE_STRUCT_STAT64_ST_MTIME_NSEC
+# define TIME_NSEC(arg) zero_extend_signed_to_ull(arg)
+#else
+# define TIME_NSEC(arg) 0
+#endif
+
+MPERS_PRINTER_DECL(bool, fetch_struct_stat64,
+		   struct tcb *tcp, const unsigned long addr,
+		   struct strace_stat *const dst)
+{
+#ifdef HAVE_STRUCT_STAT64
+	struct_stat64 buf;
+	if (umove_or_printaddr(tcp, addr, &buf))
+		return false;
+
+	dst->dev = zero_extend_signed_to_ull(buf.st_dev);
+	dst->ino = zero_extend_signed_to_ull(buf.st_ino);
+	dst->rdev = zero_extend_signed_to_ull(buf.st_rdev);
+	dst->size = zero_extend_signed_to_ull(buf.st_size);
+	dst->blocks = zero_extend_signed_to_ull(buf.st_blocks);
+	dst->blksize = zero_extend_signed_to_ull(buf.st_blksize);
+	dst->mode = zero_extend_signed_to_ull(buf.st_mode);
+	dst->nlink = zero_extend_signed_to_ull(buf.st_nlink);
+	dst->uid = zero_extend_signed_to_ull(buf.st_uid);
+	dst->gid = zero_extend_signed_to_ull(buf.st_gid);
+	dst->atime = sign_extend_unsigned_to_ll(buf.st_atime);
+	dst->ctime = sign_extend_unsigned_to_ll(buf.st_ctime);
+	dst->mtime = sign_extend_unsigned_to_ll(buf.st_mtime);
+	dst->atime_nsec = TIME_NSEC(buf.st_atime_nsec);
+	dst->ctime_nsec = TIME_NSEC(buf.st_ctime_nsec);
+	dst->mtime_nsec = TIME_NSEC(buf.st_mtime_nsec);
+	return true;
+#else /* !HAVE_STRUCT_STAT64 */
+	printaddr(addr);
+	return false;
+#endif
+}
diff --git a/fetch_struct_statfs.c b/fetch_struct_statfs.c
index 0cfe5ba..ddb248b 100644
--- a/fetch_struct_statfs.c
+++ b/fetch_struct_statfs.c
@@ -47,26 +47,26 @@
 	if (umove_or_printaddr(tcp, addr, &b))
 		return false;
 
-	p->f_type = widen_to_ull(b.f_type);
-	p->f_bsize = widen_to_ull(b.f_bsize);
-	p->f_blocks = widen_to_ull(b.f_blocks);
-	p->f_bfree = widen_to_ull(b.f_bfree);
-	p->f_bavail = widen_to_ull(b.f_bavail);
-	p->f_files = widen_to_ull(b.f_files);
-	p->f_ffree = widen_to_ull(b.f_ffree);
+	p->f_type = zero_extend_signed_to_ull(b.f_type);
+	p->f_bsize = zero_extend_signed_to_ull(b.f_bsize);
+	p->f_blocks = zero_extend_signed_to_ull(b.f_blocks);
+	p->f_bfree = zero_extend_signed_to_ull(b.f_bfree);
+	p->f_bavail = zero_extend_signed_to_ull(b.f_bavail);
+	p->f_files = zero_extend_signed_to_ull(b.f_files);
+	p->f_ffree = zero_extend_signed_to_ull(b.f_ffree);
 #if defined HAVE_STRUCT_STATFS_F_FSID_VAL
-	p->f_fsid[0] = widen_to_ull(b.f_fsid.val[0]);
-	p->f_fsid[1] = widen_to_ull(b.f_fsid.val[1]);
+	p->f_fsid[0] = zero_extend_signed_to_ull(b.f_fsid.val[0]);
+	p->f_fsid[1] = zero_extend_signed_to_ull(b.f_fsid.val[1]);
 #elif defined HAVE_STRUCT_STATFS_F_FSID___VAL
-	p->f_fsid[0] = widen_to_ull(b.f_fsid.__val[0]);
-	p->f_fsid[1] = widen_to_ull(b.f_fsid.__val[1]);
+	p->f_fsid[0] = zero_extend_signed_to_ull(b.f_fsid.__val[0]);
+	p->f_fsid[1] = zero_extend_signed_to_ull(b.f_fsid.__val[1]);
 #endif
-	p->f_namelen = widen_to_ull(b.f_namelen);
+	p->f_namelen = zero_extend_signed_to_ull(b.f_namelen);
 #ifdef HAVE_STRUCT_STATFS_F_FRSIZE
-	p->f_frsize = widen_to_ull(b.f_frsize);
+	p->f_frsize = zero_extend_signed_to_ull(b.f_frsize);
 #endif
 #ifdef HAVE_STRUCT_STATFS_F_FLAGS
-	p->f_flags = widen_to_ull(b.f_flags);
+	p->f_flags = zero_extend_signed_to_ull(b.f_flags);
 #endif
 
 	return true;
@@ -95,26 +95,26 @@
 	if (umove_or_printaddr(tcp, addr, &b))
 		return false;
 
-	p->f_type = widen_to_ull(b.f_type);
-	p->f_bsize = widen_to_ull(b.f_bsize);
-	p->f_blocks = widen_to_ull(b.f_blocks);
-	p->f_bfree = widen_to_ull(b.f_bfree);
-	p->f_bavail = widen_to_ull(b.f_bavail);
-	p->f_files = widen_to_ull(b.f_files);
-	p->f_ffree = widen_to_ull(b.f_ffree);
+	p->f_type = zero_extend_signed_to_ull(b.f_type);
+	p->f_bsize = zero_extend_signed_to_ull(b.f_bsize);
+	p->f_blocks = zero_extend_signed_to_ull(b.f_blocks);
+	p->f_bfree = zero_extend_signed_to_ull(b.f_bfree);
+	p->f_bavail = zero_extend_signed_to_ull(b.f_bavail);
+	p->f_files = zero_extend_signed_to_ull(b.f_files);
+	p->f_ffree = zero_extend_signed_to_ull(b.f_ffree);
 #if defined HAVE_STRUCT_STATFS64_F_FSID_VAL
-	p->f_fsid[0] = widen_to_ull(b.f_fsid.val[0]);
-	p->f_fsid[1] = widen_to_ull(b.f_fsid.val[1]);
+	p->f_fsid[0] = zero_extend_signed_to_ull(b.f_fsid.val[0]);
+	p->f_fsid[1] = zero_extend_signed_to_ull(b.f_fsid.val[1]);
 #elif defined HAVE_STRUCT_STATFS64_F_FSID___VAL
-	p->f_fsid[0] = widen_to_ull(b.f_fsid.__val[0]);
-	p->f_fsid[1] = widen_to_ull(b.f_fsid.__val[1]);
+	p->f_fsid[0] = zero_extend_signed_to_ull(b.f_fsid.__val[0]);
+	p->f_fsid[1] = zero_extend_signed_to_ull(b.f_fsid.__val[1]);
 #endif
-	p->f_namelen = widen_to_ull(b.f_namelen);
+	p->f_namelen = zero_extend_signed_to_ull(b.f_namelen);
 #ifdef HAVE_STRUCT_STATFS64_F_FRSIZE
-	p->f_frsize = widen_to_ull(b.f_frsize);
+	p->f_frsize = zero_extend_signed_to_ull(b.f_frsize);
 #endif
 #ifdef HAVE_STRUCT_STATFS64_F_FLAGS
-	p->f_flags = widen_to_ull(b.f_flags);
+	p->f_flags = zero_extend_signed_to_ull(b.f_flags);
 #endif
 
 	return true;
diff --git a/file.c b/file.c
deleted file mode 100644
index 3ea0b5d..0000000
--- a/file.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
- * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
- * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
- * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "defs.h"
-
-#undef dev_t
-#undef ino_t
-#undef mode_t
-#undef nlink_t
-#undef uid_t
-#undef gid_t
-#undef off_t
-#undef loff_t
-#define dev_t __kernel_dev_t
-#define ino_t __kernel_ino_t
-#define mode_t __kernel_mode_t
-#define nlink_t __kernel_nlink_t
-#define uid_t __kernel_uid_t
-#define gid_t __kernel_gid_t
-#define off_t __kernel_off_t
-#define loff_t __kernel_loff_t
-
-#include "asm_stat.h"
-
-#undef dev_t
-#undef ino_t
-#undef mode_t
-#undef nlink_t
-#undef uid_t
-#undef gid_t
-#undef off_t
-#undef loff_t
-#define dev_t dev_t
-#define ino_t ino_t
-#define mode_t mode_t
-#define nlink_t nlink_t
-#define uid_t uid_t
-#define gid_t gid_t
-#define off_t off_t
-#define loff_t loff_t
-
-/* for S_IFMT */
-#define stat libc_stat
-#define stat64 libc_stat64
-#include <sys/stat.h>
-#undef stat
-#undef stat64
-/* These might be macros. */
-#undef st_atime
-#undef st_mtime
-#undef st_ctime
-
-#if defined MAJOR_IN_SYSMACROS
-# include <sys/sysmacros.h>
-#elif defined MAJOR_IN_MKDEV
-# include <sys/mkdev.h>
-#endif
-
-/* several stats */
-
-#include "printstat.h"
-
-/* all locally defined structures provide these fields */
-#undef HAVE_STRUCT_STAT_ST_ATIME_NSEC
-#define HAVE_STRUCT_STAT_ST_ATIME_NSEC 1
-#undef HAVE_STRUCT_STAT_ST_CTIME_NSEC
-#define HAVE_STRUCT_STAT_ST_CTIME_NSEC 1
-#undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
-#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
-
-#undef STAT32_PERSONALITY
-#if SUPPORTED_PERSONALITIES > 1
-# if defined AARCH64 || defined X86_64 || defined X32
-struct stat32 {
-	unsigned int	st_dev;
-	unsigned int	st_ino;
-	unsigned short	st_mode;
-	unsigned short	st_nlink;
-	unsigned short	st_uid;
-	unsigned short	st_gid;
-	unsigned int	st_rdev;
-	unsigned int	st_size;
-	unsigned int	st_blksize;
-	unsigned int	st_blocks;
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned int	__unused4;
-	unsigned int	__unused5;
-};
-#  define STAT32_PERSONALITY 1
-# elif defined POWERPC64
-struct stat32 {
-	unsigned int	st_dev;
-	unsigned int	st_ino;
-	unsigned int	st_mode;
-	unsigned short	st_nlink;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	st_rdev;
-	unsigned int	st_size;
-	unsigned int	st_blksize;
-	unsigned int	st_blocks;
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned int	__unused4;
-	unsigned int	__unused5;
-};
-#  define STAT32_PERSONALITY 1
-# elif defined SPARC64
-struct stat32 {
-	unsigned short	st_dev;
-	unsigned int	st_ino;
-	unsigned short	st_mode;
-	unsigned short	st_nlink;
-	unsigned short	st_uid;
-	unsigned short	st_gid;
-	unsigned short	st_rdev;
-	unsigned int	st_size;
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned int	st_blksize;
-	unsigned int	st_blocks;
-	unsigned int	__unused4[2];
-};
-#  define STAT32_PERSONALITY 0
-# elif defined SPARC
-#  /* no 64-bit personalities */
-# elif defined TILE
-#  /* no 32-bit stat */
-# else
-#  warning FIXME: check whether struct stat32 definition is needed for this architecture!
-# endif /* X86_64 || X32 || POWERPC64 */
-#endif /* SUPPORTED_PERSONALITIES > 1 */
-
-#ifdef STAT32_PERSONALITY
-# define DO_PRINTSTAT do_printstat32
-# define STRUCT_STAT struct stat32
-# undef HAVE_STRUCT_STAT_ST_FLAGS
-# undef HAVE_STRUCT_STAT_ST_FSTYPE
-# undef HAVE_STRUCT_STAT_ST_GEN
-# include "printstat.h"
-#endif /* STAT32_PERSONALITY */
-
-#if defined(SPARC) || defined(SPARC64)
-
-struct solstat {
-	unsigned	st_dev;
-	unsigned int	st_pad1[3];     /* network id */
-	unsigned	st_ino;
-	unsigned	st_mode;
-	unsigned	st_nlink;
-	unsigned	st_uid;
-	unsigned	st_gid;
-	unsigned	st_rdev;
-	unsigned int	st_pad2[2];
-	unsigned int	st_size;
-	unsigned int	st_pad3;        /* st_size, off_t expansion */
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned int	st_blksize;
-	unsigned int	st_blocks;
-	char		st_fstype[16];
-	unsigned int	st_pad4[8];     /* expansion area */
-};
-
-# define DO_PRINTSTAT	do_printstat_sol
-# define STRUCT_STAT	struct solstat
-# define STAT_MAJOR(x)	(((x) >> 18) & 0x3fff)
-# define STAT_MINOR(x)	((x) & 0x3ffff)
-# undef HAVE_STRUCT_STAT_ST_FLAGS
-# undef HAVE_STRUCT_STAT_ST_FSTYPE
-# undef HAVE_STRUCT_STAT_ST_GEN
-# include "printstat.h"
-#endif /* SPARC || SPARC64 */
-
-static void
-printstat(struct tcb *tcp, long addr)
-{
-	struct stat statbuf;
-
-#ifdef STAT32_PERSONALITY
-	if (current_personality == STAT32_PERSONALITY) {
-		struct stat32 statbuf;
-
-		if (!umove_or_printaddr(tcp, addr, &statbuf))
-			do_printstat32(tcp, &statbuf);
-		return;
-	}
-#endif
-
-#if defined(SPARC) || defined(SPARC64)
-	if (current_personality == 1) {
-		struct solstat statbuf;
-
-		if (!umove_or_printaddr(tcp, addr, &statbuf))
-			do_printstat_sol(tcp, &statbuf);
-		return;
-	}
-#endif /* SPARC || SPARC64 */
-
-	if (!umove_or_printaddr(tcp, addr, &statbuf))
-		do_printstat(tcp, &statbuf);
-}
-
-SYS_FUNC(stat)
-{
-	if (entering(tcp)) {
-		printpath(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		printstat(tcp, tcp->u_arg[1]);
-	}
-	return 0;
-}
-
-SYS_FUNC(fstat)
-{
-	if (entering(tcp)) {
-		printfd(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		printstat(tcp, tcp->u_arg[1]);
-	}
-	return 0;
-}
-
-#if defined STAT32_PERSONALITY && !defined HAVE_STRUCT_STAT64
-# if defined AARCH64 || defined X86_64 || defined X32
-/*
- * Linux x86_64 and x32 have unified `struct stat' but their i386 personality
- * needs `struct stat64'.
- * linux/arch/x86/include/uapi/asm/stat.h defines `struct stat64' only for i386.
- *
- * Similarly, aarch64 has a unified `struct stat' but its arm personality
- * needs `struct stat64' (unlike x86, it shouldn't be packed).
- */
-struct stat64 {
-	unsigned long long	st_dev;
-	unsigned char	__pad0[4];
-	unsigned int	__st_ino;
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned long long	st_rdev;
-	unsigned char	__pad3[4];
-	long long	st_size;
-	unsigned int	st_blksize;
-	unsigned long long	st_blocks;
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned long long	st_ino;
-}
-#  if defined X86_64 || defined X32
-  ATTRIBUTE_PACKED
-#   define STAT64_SIZE	96
-#  else
-#   define STAT64_SIZE	104
-#  endif
-;
-#  define HAVE_STRUCT_STAT64	1
-# else /* !(AARCH64 || X86_64 || X32) */
-#  warning FIXME: check whether struct stat64 definition is needed for this architecture!
-# endif
-#endif /* STAT32_PERSONALITY && !HAVE_STRUCT_STAT64 */
-
-#ifdef HAVE_STRUCT_STAT64
-
-# define DO_PRINTSTAT do_printstat64
-# define STRUCT_STAT struct stat64
-# undef HAVE_STRUCT_STAT_ST_FLAGS
-# undef HAVE_STRUCT_STAT_ST_FSTYPE
-# undef HAVE_STRUCT_STAT_ST_GEN
-# include "printstat.h"
-
-static void
-printstat64(struct tcb *tcp, long addr)
-{
-	struct stat64 statbuf;
-
-# ifdef STAT64_SIZE
-	(void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
-# endif
-
-# ifdef STAT32_PERSONALITY
-	if (current_personality != STAT32_PERSONALITY) {
-		printstat(tcp, addr);
-		return;
-	}
-# endif /* STAT32_PERSONALITY */
-
-	if (!umove_or_printaddr(tcp, addr, &statbuf))
-		do_printstat64(tcp, &statbuf);
-}
-
-SYS_FUNC(stat64)
-{
-	if (entering(tcp)) {
-		printpath(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		printstat64(tcp, tcp->u_arg[1]);
-	}
-	return 0;
-}
-
-SYS_FUNC(fstat64)
-{
-	if (entering(tcp)) {
-		printfd(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		printstat64(tcp, tcp->u_arg[1]);
-	}
-	return 0;
-}
-
-#else
-
-SYS_FUNC(stat64)
-{
-	return sys_stat(tcp);
-}
-
-SYS_FUNC(fstat64)
-{
-	return sys_fstat(tcp);
-}
-
-#endif /* HAVE_STRUCT_STAT64 */
-
-SYS_FUNC(newfstatat)
-{
-	if (entering(tcp)) {
-		print_dirfd(tcp, tcp->u_arg[0]);
-		printpath(tcp, tcp->u_arg[1]);
-		tprints(", ");
-	} else {
-#if defined STAT32_PERSONALITY
-		if (current_personality == STAT32_PERSONALITY)
-			printstat64(tcp, tcp->u_arg[2]);
-		else
-			printstat(tcp, tcp->u_arg[2]);
-#elif defined HAVE_STRUCT_STAT64
-		printstat64(tcp, tcp->u_arg[2]);
-#else
-		printstat(tcp, tcp->u_arg[2]);
-#endif /* STAT32_PERSONALITY || HAVE_STRUCT_STAT64 */
-		tprints(", ");
-		printflags(at_flags, tcp->u_arg[3], "AT_???");
-	}
-	return 0;
-}
-
-#if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
-
-static void
-convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
-{
-	memset(newbuf, 0, sizeof(*newbuf));
-	newbuf->st_dev = oldbuf->st_dev;
-	newbuf->st_ino = oldbuf->st_ino;
-	newbuf->st_mode = oldbuf->st_mode;
-	newbuf->st_nlink = oldbuf->st_nlink;
-	newbuf->st_uid = oldbuf->st_uid;
-	newbuf->st_gid = oldbuf->st_gid;
-	newbuf->st_rdev = oldbuf->st_rdev;
-	newbuf->st_size = oldbuf->st_size;
-	newbuf->st_atime = oldbuf->st_atime;
-	newbuf->st_mtime = oldbuf->st_mtime;
-	newbuf->st_ctime = oldbuf->st_ctime;
-}
-
-static void
-printoldstat(struct tcb *tcp, long addr)
-{
-	struct __old_kernel_stat statbuf;
-	struct stat newstatbuf;
-
-# if defined(SPARC) || defined(SPARC64)
-	if (current_personality == 1) {
-		struct solstat statbuf;
-
-		if (!umove_or_printaddr(tcp, addr, &statbuf))
-			do_printstat_sol(tcp, &statbuf);
-		return;
-	}
-# endif
-
-	if (!umove_or_printaddr(tcp, addr, &statbuf)) {
-		convertoldstat(&statbuf, &newstatbuf);
-		do_printstat(tcp, &newstatbuf);
-	}
-}
-
-SYS_FUNC(oldstat)
-{
-	if (entering(tcp)) {
-		printpath(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		printoldstat(tcp, tcp->u_arg[1]);
-	}
-	return 0;
-}
-
-SYS_FUNC(oldfstat)
-{
-	if (entering(tcp)) {
-		printfd(tcp, tcp->u_arg[0]);
-		tprints(", ");
-	} else {
-		printoldstat(tcp, tcp->u_arg[1]);
-	}
-	return 0;
-}
-
-#endif /* HAVE_STRUCT___OLD_KERNEL_STAT */
-
-#if defined(SPARC) || defined(SPARC64)
-
-SYS_FUNC(xstat)
-{
-	if (entering(tcp)) {
-		tprintf("%ld, ", tcp->u_arg[0]);
-		printpath(tcp, tcp->u_arg[1]);
-		tprints(", ");
-	} else {
-		printstat(tcp, tcp->u_arg[2]);
-	}
-	return 0;
-}
-
-SYS_FUNC(fxstat)
-{
-	if (entering(tcp)) {
-		tprintf("%ld, ", tcp->u_arg[0]);
-		printfd(tcp, tcp->u_arg[1]);
-		tprints(", ");
-	} else {
-		printstat(tcp, tcp->u_arg[2]);
-	}
-	return 0;
-}
-
-#endif /* SPARC || SPARC64 */
diff --git a/flock.h b/flock.h
index b1ab8ff..afa5148 100644
--- a/flock.h
+++ b/flock.h
@@ -25,6 +25,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_FLOCK_H
+#define STRACE_FLOCK_H
+
 #include <linux/fcntl.h>
 
 #if defined HAVE_STRUCT_FLOCK
@@ -42,3 +45,5 @@
 #else
 # error struct flock64 definition not found in <linux/fcntl.h>
 #endif
+
+#endif /* !STRACE_FLOCK_H */
diff --git a/futex.c b/futex.c
index 7090c7d..d1b5a42 100644
--- a/futex.c
+++ b/futex.c
@@ -30,10 +30,6 @@
 
 #include "defs.h"
 
-#ifdef HAVE_LINUX_FUTEX_H
-# include <linux/futex.h>
-#endif
-
 #ifndef FUTEX_PRIVATE_FLAG
 # define FUTEX_PRIVATE_FLAG 128
 #endif
@@ -59,32 +55,40 @@
 	printaddr(uaddr);
 	tprints(", ");
 	printxval(futexops, op, "FUTEX_???");
-	tprintf(", %u", val);
 	switch (cmd) {
 	case FUTEX_WAIT:
+		tprintf(", %u", val);
+		tprints(", ");
+		print_timespec(tcp, timeout);
+		break;
 	case FUTEX_LOCK_PI:
 		tprints(", ");
 		print_timespec(tcp, timeout);
 		break;
 	case FUTEX_WAIT_BITSET:
+		tprintf(", %u", val);
 		tprints(", ");
 		print_timespec(tcp, timeout);
-		tprintf(", %x", val3);
+		tprintf(", %#x", val3);
 		break;
 	case FUTEX_WAKE_BITSET:
-		tprintf(", %x", val3);
+		tprintf(", %u", val);
+		tprintf(", %#x", val3);
 		break;
 	case FUTEX_REQUEUE:
+		tprintf(", %u", val);
 		tprintf(", %u, ", val2);
 		printaddr(uaddr2);
 		break;
 	case FUTEX_CMP_REQUEUE:
 	case FUTEX_CMP_REQUEUE_PI:
+		tprintf(", %u", val);
 		tprintf(", %u, ", val2);
 		printaddr(uaddr2);
 		tprintf(", %u", val3);
 		break;
 	case FUTEX_WAKE_OP:
+		tprintf(", %u", val);
 		tprintf(", %u, ", val2);
 		printaddr(uaddr2);
 		tprints(", {");
@@ -92,23 +96,29 @@
 			tprints("FUTEX_OP_OPARG_SHIFT|");
 		printxval(futexwakeops, (val3 >> 28) & 0x7, "FUTEX_OP_???");
 		tprintf(", %u, ", (val3 >> 12) & 0xfff);
-		if ((val3 >> 24) & 8)
-			tprints("FUTEX_OP_OPARG_SHIFT|");
-		printxval(futexwakecmps, (val3 >> 24) & 0x7, "FUTEX_OP_CMP_???");
+		printxval(futexwakecmps, (val3 >> 24) & 0xf, "FUTEX_OP_CMP_???");
 		tprintf(", %u}", val3 & 0xfff);
 		break;
 	case FUTEX_WAIT_REQUEUE_PI:
+		tprintf(", %u", val);
 		tprints(", ");
 		print_timespec(tcp, timeout);
 		tprints(", ");
 		printaddr(uaddr2);
 		break;
+	case FUTEX_FD:
 	case FUTEX_WAKE:
+		tprintf(", %u", val);
+		break;
 	case FUTEX_UNLOCK_PI:
 	case FUTEX_TRYLOCK_PI:
 		break;
 	default:
-		tprintf(", %lx, %lx, %x", timeout, uaddr2, val3);
+		tprintf(", %u", val);
+		tprintf(", %#lx", timeout);
+		tprints(", ");
+		printaddr(uaddr2);
+		tprintf(", %#x", val3);
 		break;
 	}
 
diff --git a/gcc_compat.h b/gcc_compat.h
index c06d3c1..908df16 100644
--- a/gcc_compat.h
+++ b/gcc_compat.h
@@ -25,8 +25,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef GCC_COMPAT_H_
-#define GCC_COMPAT_H_
+#ifndef STRACE_GCC_COMPAT_H
+#define STRACE_GCC_COMPAT_H
 
 #if defined __GNUC__ && defined __GNUC_MINOR__
 # define GNUC_PREREQ(maj, min)	\
@@ -76,4 +76,4 @@
 # define ATTRIBUTE_ALLOC_SIZE(args)	/* empty */
 #endif
 
-#endif
+#endif /* !STRACE_GCC_COMPAT_H */
diff --git a/generate_mpers_am.sh b/generate_mpers_am.sh
index 1ee4791..833cd29 100755
--- a/generate_mpers_am.sh
+++ b/generate_mpers_am.sh
@@ -1,7 +1,7 @@
 #!/bin/sh -e
 
-list="$(sed -n '/^strace_SOURCES[[:space:]]*=/,/^[[:space:]]*# end of strace_SOURCES/ s/^[[:space:]]*\([[:alnum:]][^.]*\.c\)[[:space:]]*\\$/\1/p' Makefile.am |
-	xargs -r grep -lx '#[[:space:]]*include[[:space:]]\+MPERS_DEFS' |
+list="$(sed -r -n '/^strace_SOURCES[[:space:]]*=/,/^[[:space:]]*# end of strace_SOURCES/ s/^[[:space:]]*([[:alnum:]][^.]*\.c)[[:space:]]*\\$/\1/p' Makefile.am |
+	xargs -r grep -Elx '#[[:space:]]*include[[:space:]]+MPERS_DEFS' |
 	tr '\n' ' ')"
 
 cat > mpers.am <<EOF
@@ -9,5 +9,5 @@
 mpers_source_files = $list
 EOF
 
-sed -n 's/^#[[:space:]]*include[[:space:]]*"xlat\/\([^."]\+\)\.h".*/extern const struct xlat \1[];/p' \
+sed -r -n 's/^#[[:space:]]*include[[:space:]]*"xlat\/([a-z][a-z_0-9]*)\.h".*/extern const struct xlat \1[];/p' \
 	$list > mpers_xlat.h
diff --git a/generate_sen.sh b/generate_sen.sh
index 6c177ab..33d5539 100755
--- a/generate_sen.sh
+++ b/generate_sen.sh
@@ -2,7 +2,7 @@
 
 echo 'enum {'
 echo 'SEN_printargs = 0,'
-    sed -n '/printargs/! s/.*SEN(\([^)]*\)).*/\1/p' |
-    sort -u |
+    sed -r -n '/printargs/! s/.*SEN\(([^)]+)\).*/\1/p' |
+    LC_COLLATE=C sort -u |
     sed 's/.*/SEN_&,/'
 echo '};'
diff --git a/io.c b/io.c
index 58323a7..8a93cb8 100644
--- a/io.c
+++ b/io.c
@@ -85,13 +85,15 @@
 		case IOV_DECODE_STR:
 			if (len > c->data_size)
 				len = c->data_size;
-			c->data_size -= len;
+			if (c->data_size != (unsigned long) -1L)
+				c->data_size -= len;
 			printstr(tcp, iov[0], len);
 			break;
 		case IOV_DECODE_NETLINK:
 			if (len > c->data_size)
 				len = c->data_size;
-			c->data_size -= len;
+			if (c->data_size != (unsigned long) -1L)
+				c->data_size -= len;
 			decode_netlink(tcp, iov[0], iov[1]);
 			break;
 		default:
@@ -150,17 +152,6 @@
 	return RVAL_DECODED;
 }
 
-/* The SH4 ABI does allow long longs in odd-numbered registers, but
-   does not allow them to be split between registers and memory - and
-   there are only four argument registers for normal functions.  As a
-   result pread takes an extra padding argument before the offset.  This
-   was changed late in the 2.4 series (around 2.4.20).  */
-#if defined(SH)
-#define PREAD_OFFSET_ARG 4
-#else
-#define PREAD_OFFSET_ARG 3
-#endif
-
 SYS_FUNC(pread)
 {
 	if (entering(tcp)) {
@@ -172,7 +163,7 @@
 		else
 			printstr(tcp, tcp->u_arg[1], tcp->u_rval);
 		tprintf(", %lu, ", tcp->u_arg[2]);
-		printllval(tcp, "%lld", PREAD_OFFSET_ARG);
+		printllval(tcp, "%lld", 3);
 	}
 	return 0;
 }
@@ -183,7 +174,7 @@
 	tprints(", ");
 	printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
 	tprintf(", %lu, ", tcp->u_arg[2]);
-	printllval(tcp, "%lld", PREAD_OFFSET_ARG);
+	printllval(tcp, "%lld", 3);
 
 	return RVAL_DECODED;
 }
@@ -212,8 +203,8 @@
 # if SUPPORTED_PERSONALITIES > 1
 	if (current_personality == 1) {
 		tprintf("%lld",
-			(widen_to_ull(tcp->u_arg[arg + 1]) << sizeof(long) * 8)
-			| widen_to_ull(tcp->u_arg[arg]));
+			(zero_extend_signed_to_ull(tcp->u_arg[arg + 1]) << sizeof(long) * 8)
+			| zero_extend_signed_to_ull(tcp->u_arg[arg]));
 	} else
 # endif
 	{
@@ -221,8 +212,8 @@
 	}
 #else /* SIZEOF_LONG_LONG > SIZEOF_LONG && !HAVE_STRUCT_TCB_EXT_ARG */
 	tprintf("%lld",
-		(widen_to_ull(tcp->u_arg[arg + 1]) << sizeof(long) * 8)
-		| widen_to_ull(tcp->u_arg[arg]));
+		(zero_extend_signed_to_ull(tcp->u_arg[arg + 1]) << sizeof(long) * 8)
+		| zero_extend_signed_to_ull(tcp->u_arg[arg]));
 #endif
 }
 
diff --git a/ipc_defs.h b/ipc_defs.h
index b6c85c1..e0043ce 100644
--- a/ipc_defs.h
+++ b/ipc_defs.h
@@ -25,6 +25,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_IPC_DEFS_H
+#define STRACE_IPC_DEFS_H
+
 #ifdef HAVE_SYS_IPC_H
 # include <sys/ipc.h>
 #elif defined HAVE_LINUX_IPC_H
@@ -40,3 +43,5 @@
 #define PRINTCTL(flagset, arg, dflt) \
 	if ((arg) & IPC_64) tprints("IPC_64|"); \
 	printxval((flagset), (arg) &~ IPC_64, dflt)
+
+#endif /* !STRACE_IPC_DEFS_H */
diff --git a/ipc_msg.c b/ipc_msg.c
index daa0036..7ef5cda 100644
--- a/ipc_msg.c
+++ b/ipc_msg.c
@@ -44,13 +44,15 @@
 
 SYS_FUNC(msgget)
 {
-	if (tcp->u_arg[0])
-		tprintf("%#lx, ", tcp->u_arg[0]);
+	const int key = (int) tcp->u_arg[0];
+	if (key)
+		tprintf("%#x", key);
 	else
-		tprints("IPC_PRIVATE, ");
+		tprints("IPC_PRIVATE");
+	tprints(", ");
 	if (printflags(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0)
 		tprints("|");
-	tprintf("%#lo", tcp->u_arg[1] & 0777);
+	print_numeric_umode_t(tcp->u_arg[1] & 0777);
 	return RVAL_DECODED;
 }
 
diff --git a/ipc_msgctl.c b/ipc_msgctl.c
index e46f6e2..a7352cb 100644
--- a/ipc_msgctl.c
+++ b/ipc_msgctl.c
@@ -67,7 +67,7 @@
 		printuid("uid=", msqid_ds.msg_perm.uid);
 		printuid(", gid=", msqid_ds.msg_perm.gid);
 		tprints(", mode=");
-		tprints(sprintmode(msqid_ds.msg_perm.mode));
+		print_numeric_umode_t(msqid_ds.msg_perm.mode);
 
 		if (cmd != IPC_STAT) {
 			tprints("}, ...}");
@@ -97,7 +97,7 @@
 SYS_FUNC(msgctl)
 {
 	if (entering(tcp)) {
-		tprintf("%lu, ", tcp->u_arg[0]);
+		tprintf("%d, ", (int) tcp->u_arg[0]);
 		PRINTCTL(msgctl_flags, tcp->u_arg[1], "MSG_???");
 		tprints(", ");
 	} else {
diff --git a/ipc_sem.c b/ipc_sem.c
index ba21b7b..db79746 100644
--- a/ipc_sem.c
+++ b/ipc_sem.c
@@ -57,7 +57,7 @@
 #endif
 
 static void
-tprint_sembuf_array(struct tcb *tcp, const long addr, const unsigned long count)
+tprint_sembuf_array(struct tcb *tcp, const long addr, const unsigned int count)
 {
 #if defined HAVE_SYS_SEM_H || defined HAVE_LINUX_SEM_H
 	struct sembuf sb;
@@ -66,12 +66,12 @@
 #else
 	printaddr(addr);
 #endif
-	tprintf(", %lu", count);
+	tprintf(", %u", count);
 }
 
 SYS_FUNC(semop)
 {
-	tprintf("%lu, ", tcp->u_arg[0]);
+	tprintf("%d, ", (int) tcp->u_arg[0]);
 	if (indirect_ipccall(tcp)) {
 		tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]);
 	} else {
@@ -82,7 +82,7 @@
 
 SYS_FUNC(semtimedop)
 {
-	tprintf("%lu, ", tcp->u_arg[0]);
+	tprintf("%d, ", (int) tcp->u_arg[0]);
 	if (indirect_ipccall(tcp)) {
 		tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]);
 		tprints(", ");
@@ -101,23 +101,28 @@
 
 SYS_FUNC(semget)
 {
-	if (tcp->u_arg[0])
-		tprintf("%#lx", tcp->u_arg[0]);
+	const int key = (int) tcp->u_arg[0];
+	if (key)
+		tprintf("%#x", key);
 	else
 		tprints("IPC_PRIVATE");
-	tprintf(", %lu, ", tcp->u_arg[1]);
+	tprintf(", %d, ", (int) tcp->u_arg[1]);
 	if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
 		tprints("|");
-	tprintf("%#lo", tcp->u_arg[2] & 0777);
+	print_numeric_umode_t(tcp->u_arg[2] & 0777);
 	return RVAL_DECODED;
 }
 
 SYS_FUNC(semctl)
 {
-	tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
+	tprintf("%d, %d, ", (int) tcp->u_arg[0], (int) tcp->u_arg[1]);
 	PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???");
 	tprints(", ");
-	if (indirect_ipccall(tcp)) {
+	if (indirect_ipccall(tcp)
+#ifdef SPARC64
+	    && current_personality != 0
+#endif
+	   ) {
 		printnum_ptr(tcp, tcp->u_arg[3]);
 	} else {
 		tprintf("%#lx", tcp->u_arg[3]);
diff --git a/ipc_shm.c b/ipc_shm.c
index c418884..f9a0537 100644
--- a/ipc_shm.c
+++ b/ipc_shm.c
@@ -43,21 +43,22 @@
 
 SYS_FUNC(shmget)
 {
-	if (tcp->u_arg[0])
-		tprintf("%#lx", tcp->u_arg[0]);
+	const int key = (int) tcp->u_arg[0];
+	if (key)
+		tprintf("%#x", key);
 	else
 		tprints("IPC_PRIVATE");
 	tprintf(", %lu, ", tcp->u_arg[1]);
 	if (printflags(shm_resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
 		tprints("|");
-	tprintf("%#lo", tcp->u_arg[2] & 0777);
+	print_numeric_umode_t(tcp->u_arg[2] & 0777);
 	return RVAL_DECODED;
 }
 
 SYS_FUNC(shmat)
 {
 	if (entering(tcp)) {
-		tprintf("%lu, ", tcp->u_arg[0]);
+		tprintf("%d, ", (int) tcp->u_arg[0]);
 		if (indirect_ipccall(tcp)) {
 			printaddr(tcp->u_arg[3]);
 			tprints(", ");
@@ -72,10 +73,14 @@
 		if (syserror(tcp))
 			return 0;
 		if (indirect_ipccall(tcp)) {
-			unsigned long raddr;
-			if (umove(tcp, tcp->u_arg[2], &raddr) < 0)
+			union {
+				uint64_t r64;
+				uint32_t r32;
+			} u;
+			if (umoven(tcp, tcp->u_arg[2], current_wordsize, &u) < 0)
 				return RVAL_NONE;
-			tcp->u_rval = raddr;
+			tcp->u_rval = (sizeof(u.r32) == current_wordsize)
+				      ? u.r32 : u.r64;
 		}
 		return RVAL_HEX;
 	}
diff --git a/ipc_shmctl.c b/ipc_shmctl.c
index 3498455..12bb806 100644
--- a/ipc_shmctl.c
+++ b/ipc_shmctl.c
@@ -67,7 +67,7 @@
 		printuid("uid=", shmid_ds.shm_perm.uid);
 		printuid(", gid=", shmid_ds.shm_perm.gid);
 		tprints(", mode=");
-		tprints(sprintmode(shmid_ds.shm_perm.mode));
+		print_numeric_umode_t(shmid_ds.shm_perm.mode);
 
 		if (cmd != IPC_STAT) {
 			tprints("}, ...}");
@@ -97,7 +97,7 @@
 SYS_FUNC(shmctl)
 {
 	if (entering(tcp)) {
-		tprintf("%lu, ", tcp->u_arg[0]);
+		tprintf("%d, ", (int) tcp->u_arg[0]);
 		PRINTCTL(shmctl_flags, tcp->u_arg[1], "SHM_???");
 		tprints(", ");
 	} else {
diff --git a/kernel_types.h b/kernel_types.h
index 3dee761..551a1e6 100644
--- a/kernel_types.h
+++ b/kernel_types.h
@@ -26,8 +26,7 @@
  */
 
 #ifndef STRACE_KERNEL_TYPES_H
-
-# define STRACE_KERNEL_TYPES_H
+#define STRACE_KERNEL_TYPES_H
 
 # if defined HAVE___KERNEL_LONG_T && defined HAVE___KERNEL_ULONG_T
 
@@ -55,4 +54,4 @@
 	char		d_name[1];
 } kernel_dirent;
 
-#endif
+#endif /* !STRACE_KERNEL_TYPES_H */
diff --git a/keyctl.c b/keyctl.c
index 456649e..7f047c6 100644
--- a/keyctl.c
+++ b/keyctl.c
@@ -26,11 +26,18 @@
  */
 
 #include "defs.h"
+#include "kernel_types.h"
 
 typedef int32_t key_serial_t;
 
 #include "xlat/key_spec.h"
 
+struct keyctl_dh_params {
+	int32_t private;
+	int32_t prime;
+	int32_t base;
+};
+
 static void
 print_keyring_serial_number(key_serial_t id)
 {
@@ -85,12 +92,13 @@
 }
 
 static void
-keyctl_update_key(struct tcb *tcp, key_serial_t id, long addr, long len)
+keyctl_update_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
+		  kernel_ulong_t len)
 {
 	print_keyring_serial_number(id);
 	tprints(", ");
 	printstr(tcp, addr, len);
-	tprintf(", %lu", len);
+	tprintf(", %llu", zero_extend_signed_to_ull(len));
 }
 
 static void
@@ -102,7 +110,8 @@
 }
 
 static void
-keyctl_read_key(struct tcb *tcp, key_serial_t id, long addr, long len)
+keyctl_read_key(struct tcb *tcp, key_serial_t id, kernel_ulong_t addr,
+		kernel_ulong_t len, bool has_nul)
 {
 	if (entering(tcp)) {
 		print_keyring_serial_number(id);
@@ -111,17 +120,19 @@
 		if (syserror(tcp))
 			printaddr(addr);
 		else {
-			long rval = tcp->u_rval > len ?
-				    len : (tcp->u_rval ? -1 : 0);
-			printstr(tcp, addr, rval);
+			kernel_ulong_t rval = (tcp->u_rval >= 0) &&
+				((kernel_ulong_t) tcp->u_rval > len) ? len :
+				(kernel_ulong_t) tcp->u_rval;
+			printstr_ex(tcp, addr, rval, has_nul ?
+				    QUOTE_OMIT_TRAILING_0 : 0);
 		}
-		tprintf(", %lu", len);
+		tprintf(", %llu", zero_extend_signed_to_ull(len));
 	}
 }
 
 static void
-keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, long addr1,
-		      long addr2, key_serial_t id2)
+keyctl_keyring_search(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr1,
+		      kernel_ulong_t addr2, key_serial_t id2)
 {
 	print_keyring_serial_number(id1);
 	tprints(", ");
@@ -133,31 +144,34 @@
 }
 
 static void
-keyctl_chown_key(struct tcb *tcp, key_serial_t id, int user, int group)
+keyctl_chown_key(struct tcb *tcp, key_serial_t id, unsigned user,
+		 unsigned group)
 {
 	print_keyring_serial_number(id);
-	tprintf(", %d, %d", user, group);
+	printuid(", ", user);
+	printuid(", ", group);
 }
 
 static void
-keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, long addr,
-		       long len, key_serial_t id2)
+keyctl_instantiate_key(struct tcb *tcp, key_serial_t id1, kernel_ulong_t addr,
+		       kernel_ulong_t len, key_serial_t id2)
 {
 	print_keyring_serial_number(id1);
 	tprints(", ");
 	printstr(tcp, addr, len);
-	tprintf(", %lu, ", len);
+	tprintf(", %llu, ", zero_extend_signed_to_ull(len));
 	print_keyring_serial_number(id2);
 }
 
 static void
 keyctl_instantiate_key_iov(struct tcb *tcp, key_serial_t id1,
-			   long addr, long len, key_serial_t id2)
+			   kernel_ulong_t addr, kernel_ulong_t len,
+			   key_serial_t id2)
 {
 	print_keyring_serial_number(id1);
 	tprints(", ");
 	tprint_iov(tcp, len, addr, IOV_DECODE_STR);
-	tprintf(", %lu, ", len);
+	tprintf(", %llu, ", zero_extend_signed_to_ull(len));
 	print_keyring_serial_number(id2);
 }
 
@@ -174,8 +188,16 @@
 keyctl_reject_key(struct tcb *tcp, key_serial_t id1, unsigned timeout,
 		  unsigned error, key_serial_t id2)
 {
+	const char *err_str = err_name(error);
+
 	print_keyring_serial_number(id1);
-	tprintf(", %u, %u, ", timeout, error);
+	tprintf(", %u, ", timeout);
+
+	if (err_str)
+		tprintf("%s, ", err_str);
+	else
+		tprintf("%u, ", error);
+
 	print_keyring_serial_number(id2);
 }
 
@@ -187,9 +209,10 @@
 }
 
 static void
-keyctl_get_persistent(struct tcb *tcp, int uid, key_serial_t id)
+keyctl_get_persistent(struct tcb *tcp, unsigned uid, key_serial_t id)
 {
-	tprintf("%d, ", uid);
+	printuid("", uid);
+	tprints(", ");
 	print_keyring_serial_number(id);
 }
 
@@ -203,105 +226,145 @@
 	printflags(key_perms, perm, "KEY_???");
 }
 
+static void
+print_dh_params(struct tcb *tcp, kernel_ulong_t addr)
+{
+	struct keyctl_dh_params params;
+
+	if (umove_or_printaddr(tcp, addr, &params))
+		return;
+
+	tprints("{private=");
+	print_keyring_serial_number(params.private);
+	tprints(", prime=");
+	print_keyring_serial_number(params.prime);
+	tprints(", base=");
+	print_keyring_serial_number(params.base);
+	tprints("}");
+}
+
+static void
+keyctl_dh_compute(struct tcb *tcp, kernel_ulong_t params, kernel_ulong_t buf,
+		  kernel_ulong_t len)
+{
+	if (entering(tcp)) {
+		print_dh_params(tcp, params);
+		tprints(", ");
+	} else {
+		if (syserror(tcp)) {
+			printaddr(buf);
+		} else {
+			kernel_ulong_t rval = (tcp->u_rval >= 0) &&
+				((kernel_ulong_t) tcp->u_rval > len) ? len :
+				(kernel_ulong_t) tcp->u_rval;
+			printstr(tcp, buf, rval);
+		}
+		tprintf(", %llu", zero_extend_signed_to_ull(len));
+	}
+}
+
 #include "xlat/key_reqkeys.h"
 #include "xlat/keyctl_commands.h"
 
 SYS_FUNC(keyctl)
 {
 	int cmd = tcp->u_arg[0];
+	unsigned long long arg2 = getarg_ull(tcp, 1);
+	unsigned long long arg3 = getarg_ull(tcp, 2);
+	unsigned long long arg4 = getarg_ull(tcp, 3);
+	unsigned long long arg5 = getarg_ull(tcp, 4);
 
 	if (entering(tcp)) {
 		printxval(keyctl_commands, cmd, "KEYCTL_???");
-		tprints(", ");
+
+		/*
+		 * For now, KEYCTL_SESSION_TO_PARENT is the only cmd without
+		 * arguments.
+		 */
+		if (cmd != KEYCTL_SESSION_TO_PARENT)
+			tprints(", ");
 	}
 
 	switch (cmd) {
 	case KEYCTL_GET_KEYRING_ID:
-		keyctl_get_keyring_id(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+		keyctl_get_keyring_id(tcp, arg2, arg3);
 		break;
 
 	case KEYCTL_JOIN_SESSION_KEYRING:
-		printstr(tcp, tcp->u_arg[1], -1);
+		printstr(tcp, arg2, -1);
 		break;
 
 	case KEYCTL_UPDATE:
-		keyctl_update_key(tcp, tcp->u_arg[1],
-				  tcp->u_arg[2], tcp->u_arg[3]);
+		keyctl_update_key(tcp, arg2, arg3, arg4);
 		break;
 
 	case KEYCTL_REVOKE:
 	case KEYCTL_CLEAR:
 	case KEYCTL_INVALIDATE:
 	case KEYCTL_ASSUME_AUTHORITY:
-		print_keyring_serial_number(tcp->u_arg[1]);
+		print_keyring_serial_number(arg2);
 		break;
 
 	case KEYCTL_LINK:
 	case KEYCTL_UNLINK:
-		keyctl_handle_key_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+		keyctl_handle_key_key(tcp, arg2, arg3);
 		break;
 
 	case KEYCTL_DESCRIBE:
 	case KEYCTL_READ:
 	case KEYCTL_GET_SECURITY:
-		keyctl_read_key(tcp, tcp->u_arg[1],
-				tcp->u_arg[2], tcp->u_arg[3]);
+		keyctl_read_key(tcp, arg2, arg3, arg4, cmd != KEYCTL_READ);
 		return 0;
 
 	case KEYCTL_SEARCH:
-		keyctl_keyring_search(tcp, tcp->u_arg[1], tcp->u_arg[2],
-				      tcp->u_arg[3], tcp->u_arg[4]);
+		keyctl_keyring_search(tcp, arg2, arg3, arg4, arg5);
 		break;
 
 	case KEYCTL_CHOWN:
-		keyctl_chown_key(tcp, tcp->u_arg[1],
-				 tcp->u_arg[2], tcp->u_arg[3]);
+		keyctl_chown_key(tcp, arg2, arg3, arg4);
 		break;
 
 	case KEYCTL_SETPERM:
-		keyctl_setperm_key(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+		keyctl_setperm_key(tcp, arg2, arg3);
 		break;
 
 	case KEYCTL_INSTANTIATE:
-		keyctl_instantiate_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
-				       tcp->u_arg[3], tcp->u_arg[4]);
+		keyctl_instantiate_key(tcp, arg2, arg3, arg4, arg5);
 		break;
 
 	case KEYCTL_NEGATE:
-		keyctl_negate_key(tcp, tcp->u_arg[1],
-				  tcp->u_arg[2], tcp->u_arg[3]);
+		keyctl_negate_key(tcp, arg2, arg3, arg4);
 		break;
 
 	case KEYCTL_SET_REQKEY_KEYRING:
-		printxval(key_reqkeys, tcp->u_arg[1], "KEY_REQKEY_DEFL_???");
+		printxval(key_reqkeys, arg2, "KEY_REQKEY_DEFL_???");
 		break;
 
 	case KEYCTL_SET_TIMEOUT:
-		keyctl_set_timeout(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+		keyctl_set_timeout(tcp, arg2, arg3);
 		break;
 
 	case KEYCTL_SESSION_TO_PARENT:
 		break;
 
 	case KEYCTL_REJECT:
-		keyctl_reject_key(tcp, tcp->u_arg[1], tcp->u_arg[2],
-				  tcp->u_arg[3], tcp->u_arg[4]);
+		keyctl_reject_key(tcp, arg2, arg3, arg4, arg5);
 		break;
 
 	case KEYCTL_INSTANTIATE_IOV:
-		keyctl_instantiate_key_iov(tcp, tcp->u_arg[1],
-					   tcp->u_arg[2], tcp->u_arg[3],
-					   tcp->u_arg[4]);
+		keyctl_instantiate_key_iov(tcp, arg2, arg3, arg4, arg5);
 		break;
 
 	case KEYCTL_GET_PERSISTENT:
-		keyctl_get_persistent(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+		keyctl_get_persistent(tcp, arg2, arg3);
 		break;
 
+	case KEYCTL_DH_COMPUTE:
+		keyctl_dh_compute(tcp, arg2, arg3, arg4);
+		return 0;
+
 	default:
-		tprintf("%#lx, %#lx, %#lx, %#lx",
-			tcp->u_arg[1], tcp->u_arg[2],
-			tcp->u_arg[3], tcp->u_arg[4]);
+		tprintf("%#llx, %#llx, %#llx, %#llx", arg2, arg3, arg4, arg5);
 		break;
 	}
 
diff --git a/linux/32/ioctls_inc_align32.h b/linux/32/ioctls_inc_align32.h
index 2222f40..9888eca 100644
--- a/linux/32/ioctls_inc_align32.h
+++ b/linux/32/ioctls_inc_align32.h
@@ -284,6 +284,7 @@
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_FINI", _IOC_WRITE, 0x6445, 0x04 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_PREP", _IOC_WRITE, 0x6444, 0x18 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_INFO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
+{ "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_MADVISE", _IOC_READ|_IOC_WRITE, 0x6448, 0x0c },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_NEW", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_SUBMIT", _IOC_READ|_IOC_WRITE, 0x6446, 0x20 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6440, 0x10 },
@@ -392,10 +393,13 @@
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_BO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_SHADER_BO", _IOC_READ|_IOC_WRITE, 0x6445, 0x18 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_HANG_STATE", _IOC_READ|_IOC_WRITE, 0x6446, 0xa0 },
+{ "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6447, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_MMAP_BO", _IOC_READ|_IOC_WRITE, 0x6444, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_SUBMIT_CL", _IOC_READ|_IOC_WRITE, 0x6440, 0xa0 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_BO", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_SEQNO", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_ATTACH", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_SIGNAL", _IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_AGP_INIT", _IOC_READ|_IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_ALLOCMEM", _IOC_READ|_IOC_WRITE, 0x6440, 0x14 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_BLIT_SYNC", _IOC_WRITE, 0x644f, 0x08 },
@@ -683,6 +687,16 @@
 { "linux/cdrom.h", "DVD_AUTH", 0, 0x5392, 0 },
 { "linux/cdrom.h", "DVD_READ_STRUCT", 0, 0x5390, 0 },
 { "linux/cdrom.h", "DVD_WRITE_STRUCT", 0, 0x5391, 0 },
+{ "linux/cec.h", "CEC_ADAP_G_CAPS", _IOC_READ|_IOC_WRITE, 0x6100, 0x4c },
+{ "linux/cec.h", "CEC_ADAP_G_LOG_ADDRS", _IOC_READ, 0x6103, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_G_PHYS_ADDR", _IOC_READ, 0x6101, 0x02 },
+{ "linux/cec.h", "CEC_ADAP_S_LOG_ADDRS", _IOC_READ|_IOC_WRITE, 0x6104, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_S_PHYS_ADDR", _IOC_WRITE, 0x6102, 0x02 },
+{ "linux/cec.h", "CEC_DQEVENT", _IOC_READ|_IOC_WRITE, 0x6107, 0x50 },
+{ "linux/cec.h", "CEC_G_MODE", _IOC_READ, 0x6108, 0x04 },
+{ "linux/cec.h", "CEC_RECEIVE", _IOC_READ|_IOC_WRITE, 0x6106, 0x38 },
+{ "linux/cec.h", "CEC_S_MODE", _IOC_WRITE, 0x6109, 0x04 },
+{ "linux/cec.h", "CEC_TRANSMIT", _IOC_READ|_IOC_WRITE, 0x6105, 0x38 },
 { "linux/chio.h", "CHIOEXCHANGE", _IOC_WRITE, 0x6302, 0x1c },
 { "linux/chio.h", "CHIOGELEM", _IOC_WRITE, 0x6310, 0x6c },
 { "linux/chio.h", "CHIOGPARAMS", _IOC_READ, 0x6306, 0x14 },
@@ -969,7 +983,11 @@
 { "linux/gigaset_dev.h", "GIGASET_CONFIG", _IOC_READ|_IOC_WRITE, 0x4701, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_REDIR", _IOC_READ|_IOC_WRITE, 0x4700, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_VERSION", _IOC_READ|_IOC_WRITE, 0x4703, 0x10 },
+{ "linux/gpio.h", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb408, 0x40 },
+{ "linux/gpio.h", "GPIOHANDLE_SET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb409, 0x40 },
 { "linux/gpio.h", "GPIO_GET_CHIPINFO_IOCTL", _IOC_READ, 0xb401, 0x44 },
+{ "linux/gpio.h", "GPIO_GET_LINEEVENT_IOCTL", _IOC_READ|_IOC_WRITE, 0xb404, 0x30 },
+{ "linux/gpio.h", "GPIO_GET_LINEHANDLE_IOCTL", _IOC_READ|_IOC_WRITE, 0xb403, 0x16c },
 { "linux/gpio.h", "GPIO_GET_LINEINFO_IOCTL", _IOC_READ|_IOC_WRITE, 0xb402, 0x48 },
 { "linux/gsmmux.h", "GSMIOC_DISABLE_NET", _IOC_NONE, 0x4703, 0x00 },
 { "linux/gsmmux.h", "GSMIOC_ENABLE_NET", _IOC_WRITE, 0x4702, 0x34 },
@@ -1418,30 +1436,14 @@
 { "linux/lightnvm.h", "NVM_INFO", _IOC_READ|_IOC_WRITE, 0x4c20, 0x1000 },
 { "linux/lirc.h", "LIRC_GET_FEATURES", _IOC_READ, 0x6900, 0x04 },
 { "linux/lirc.h", "LIRC_GET_LENGTH", _IOC_READ, 0x690f, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_PULSE", _IOC_READ, 0x690b, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_SPACE", _IOC_READ, 0x690d, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MAX_TIMEOUT", _IOC_READ, 0x6909, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_PULSE", _IOC_READ, 0x690a, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_SPACE", _IOC_READ, 0x690c, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MIN_TIMEOUT", _IOC_READ, 0x6908, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_CARRIER", _IOC_READ, 0x6904, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_DUTY_CYCLE", _IOC_READ, 0x6906, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_MODE", _IOC_READ, 0x6902, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_RESOLUTION", _IOC_READ, 0x6907, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_CARRIER", _IOC_READ, 0x6903, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_DUTY_CYCLE", _IOC_READ, 0x6905, 0x04 },
 { "linux/lirc.h", "LIRC_GET_SEND_MODE", _IOC_READ, 0x6901, 0x04 },
-{ "linux/lirc.h", "LIRC_NOTIFY_DECODE", _IOC_NONE, 0x6920, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_END", _IOC_NONE, 0x6922, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_START", _IOC_NONE, 0x6921, 0x00 },
 { "linux/lirc.h", "LIRC_SET_MEASURE_CARRIER_MODE", _IOC_WRITE, 0x691d, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER", _IOC_WRITE, 0x6914, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER_RANGE", _IOC_WRITE, 0x691f, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE", _IOC_WRITE, 0x6916, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE_RANGE", _IOC_WRITE, 0x691e, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER", _IOC_WRITE, 0x691c, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_PULSE", _IOC_WRITE, 0x691a, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_SPACE", _IOC_WRITE, 0x691b, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_MODE", _IOC_WRITE, 0x6912, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT", _IOC_WRITE, 0x6918, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT_REPORTS", _IOC_WRITE, 0x6919, 0x04 },
@@ -1553,19 +1555,19 @@
 { "linux/ndctl.h", "ND_IOCTL_SMART", _IOC_READ|_IOC_WRITE, 0x4e01, 0x84 },
 { "linux/ndctl.h", "ND_IOCTL_SMART_THRESHOLD", _IOC_READ|_IOC_WRITE, 0x4e02, 0x0c },
 { "linux/ndctl.h", "ND_IOCTL_VENDOR", _IOC_READ|_IOC_WRITE, 0x4e09, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE, 0x4e41, 0x48 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ID", _IOC_NONE, 0x4e40, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_IO_CMD", _IOC_READ|_IOC_WRITE, 0x4e43, 0x48 },
@@ -1739,6 +1741,17 @@
 { "linux/raw.h", "RAW_SETBIND", _IOC_NONE, 0xac00, 0x00 },
 { "linux/reiserfs_fs.h", "REISERFS_IOC_UNPACK", _IOC_WRITE, 0xcd01, 0x04 },
 { "linux/rfkill.h", "RFKILL_IOCTL_NOINPUT", _IOC_NONE, 0x5201, 0x00 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_ACCEPT", _IOC_READ|_IOC_WRITE, 0x6307, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_BIND", _IOC_WRITE, 0x6305, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CLOSE", _IOC_WRITE, 0x6304, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CONNECT", _IOC_WRITE, 0x6308, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CREATE", _IOC_READ|_IOC_WRITE, 0x6303, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_LISTEN", _IOC_WRITE, 0x6306, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_RECEIVE", _IOC_READ|_IOC_WRITE, 0x630a, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_SEND", _IOC_WRITE, 0x6309, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST", _IOC_READ|_IOC_WRITE, 0x6302, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST_SIZE", _IOC_READ|_IOC_WRITE, 0x6301, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_MPORT_GET_LIST", _IOC_READ|_IOC_WRITE, 0x630b, 0x04 },
 { "linux/rio_mport_cdev.h", "RIO_ALLOC_DMA", _IOC_READ|_IOC_WRITE, 0x6d13, 0x18 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_ADD", _IOC_WRITE, 0x6d17, 0x20 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_DEL", _IOC_WRITE, 0x6d18, 0x20 },
@@ -2244,6 +2257,8 @@
 { "linux/vhost.h", "VHOST_SET_VRING_ERR", _IOC_WRITE, 0xaf22, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_KICK", _IOC_WRITE, 0xaf20, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_NUM", _IOC_WRITE, 0xaf10, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_GUEST_CID", _IOC_WRITE, 0xaf60, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_RUNNING", _IOC_WRITE, 0xaf61, 0x04 },
 { "linux/videodev2.h", "VIDIOC_CREATE_BUFS", _IOC_READ|_IOC_WRITE, 0x565c, 0xf8 },
 { "linux/videodev2.h", "VIDIOC_CROPCAP", _IOC_READ|_IOC_WRITE, 0x563a, 0x2c },
 { "linux/videodev2.h", "VIDIOC_DBG_G_CHIP_INFO", _IOC_READ|_IOC_WRITE, 0x5666, 0xc8 },
@@ -2348,7 +2363,6 @@
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_SOCKETS_VERSION", _IOC_NONE, 0x07b4, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION", _IOC_NONE, 0x079f, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION2", _IOC_NONE, 0x07a7, 0x00 },
-{ "linux/vsp1.h", "VIDIOC_VSP1_LUT_CONFIG", _IOC_READ|_IOC_WRITE, 0x56c1, 0x400 },
 { "linux/vt.h", "VT_ACTIVATE", 0, 0x5606, 0 },
 { "linux/vt.h", "VT_DISALLOCATE", 0, 0x5608, 0 },
 { "linux/vt.h", "VT_GETHIFONTMASK", 0, 0x560D, 0 },
@@ -2365,6 +2379,7 @@
 { "linux/vt.h", "VT_UNLOCKSWITCH", 0, 0x560C, 0 },
 { "linux/vt.h", "VT_WAITACTIVE", 0, 0x5607, 0 },
 { "linux/vt.h", "VT_WAITEVENT", 0, 0x560E, 0 },
+{ "linux/vtpm_proxy.h", "VTPM_PROXY_IOC_NEW_DEV", _IOC_READ|_IOC_WRITE, 0xa100, 0x14 },
 { "linux/watchdog.h", "WDIOC_GETBOOTSTATUS", _IOC_READ, 0x5702, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETPRETIMEOUT", _IOC_READ, 0x5709, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETSTATUS", _IOC_READ, 0x5701, 0x04 },
@@ -2771,8 +2786,6 @@
 { "staging/android/ion_test.h", "ION_IOC_TEST_DMA_MAPPING", _IOC_WRITE, 0x49f1, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_KERNEL_MAPPING", _IOC_WRITE, 0x49f2, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_SET_FD", _IOC_NONE, 0x49f0, 0x00 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_CREATE_FENCE", _IOC_READ|_IOC_WRITE, 0x5700, 0x28 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_INC", _IOC_WRITE, 0x5701, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_BRIGHTNESS", _IOC_READ, 0x4603, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_COLOR", _IOC_READ, 0x4605, 0x04 },
 { "video/da8xx-fb.h", "FBIOGET_CONTRAST", _IOC_READ, 0x4601, 0x04 },
@@ -2813,6 +2826,7 @@
 { "xen/evtchn.h", "IOCTL_EVTCHN_BIND_VIRQ", _IOC_NONE, 0x4500, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_NOTIFY", _IOC_NONE, 0x4504, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_RESET", _IOC_NONE, 0x4505, 0x00 },
+{ "xen/evtchn.h", "IOCTL_EVTCHN_RESTRICT_DOMID", _IOC_NONE, 0x4506, 0x02 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_UNBIND", _IOC_NONE, 0x4503, 0x04 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR", _IOC_NONE, 0x4702, 0x18 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GRANT_COPY", _IOC_NONE, 0x4708, 0x08 },
diff --git a/linux/32/ioctls_inc_align64.h b/linux/32/ioctls_inc_align64.h
index 173cc67..da95c40 100644
--- a/linux/32/ioctls_inc_align64.h
+++ b/linux/32/ioctls_inc_align64.h
@@ -284,6 +284,7 @@
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_FINI", _IOC_WRITE, 0x6445, 0x04 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_PREP", _IOC_WRITE, 0x6444, 0x18 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_INFO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
+{ "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_MADVISE", _IOC_READ|_IOC_WRITE, 0x6448, 0x0c },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_NEW", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_SUBMIT", _IOC_READ|_IOC_WRITE, 0x6446, 0x20 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6440, 0x10 },
@@ -392,10 +393,13 @@
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_BO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_SHADER_BO", _IOC_READ|_IOC_WRITE, 0x6445, 0x18 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_HANG_STATE", _IOC_READ|_IOC_WRITE, 0x6446, 0xa0 },
+{ "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6447, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_MMAP_BO", _IOC_READ|_IOC_WRITE, 0x6444, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_SUBMIT_CL", _IOC_READ|_IOC_WRITE, 0x6440, 0xa0 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_BO", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_SEQNO", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_ATTACH", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_SIGNAL", _IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_AGP_INIT", _IOC_READ|_IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_ALLOCMEM", _IOC_READ|_IOC_WRITE, 0x6440, 0x14 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_BLIT_SYNC", _IOC_WRITE, 0x644f, 0x08 },
@@ -683,6 +687,16 @@
 { "linux/cdrom.h", "DVD_AUTH", 0, 0x5392, 0 },
 { "linux/cdrom.h", "DVD_READ_STRUCT", 0, 0x5390, 0 },
 { "linux/cdrom.h", "DVD_WRITE_STRUCT", 0, 0x5391, 0 },
+{ "linux/cec.h", "CEC_ADAP_G_CAPS", _IOC_READ|_IOC_WRITE, 0x6100, 0x4c },
+{ "linux/cec.h", "CEC_ADAP_G_LOG_ADDRS", _IOC_READ, 0x6103, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_G_PHYS_ADDR", _IOC_READ, 0x6101, 0x02 },
+{ "linux/cec.h", "CEC_ADAP_S_LOG_ADDRS", _IOC_READ|_IOC_WRITE, 0x6104, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_S_PHYS_ADDR", _IOC_WRITE, 0x6102, 0x02 },
+{ "linux/cec.h", "CEC_DQEVENT", _IOC_READ|_IOC_WRITE, 0x6107, 0x50 },
+{ "linux/cec.h", "CEC_G_MODE", _IOC_READ, 0x6108, 0x04 },
+{ "linux/cec.h", "CEC_RECEIVE", _IOC_READ|_IOC_WRITE, 0x6106, 0x38 },
+{ "linux/cec.h", "CEC_S_MODE", _IOC_WRITE, 0x6109, 0x04 },
+{ "linux/cec.h", "CEC_TRANSMIT", _IOC_READ|_IOC_WRITE, 0x6105, 0x38 },
 { "linux/chio.h", "CHIOEXCHANGE", _IOC_WRITE, 0x6302, 0x1c },
 { "linux/chio.h", "CHIOGELEM", _IOC_WRITE, 0x6310, 0x6c },
 { "linux/chio.h", "CHIOGPARAMS", _IOC_READ, 0x6306, 0x14 },
@@ -969,7 +983,11 @@
 { "linux/gigaset_dev.h", "GIGASET_CONFIG", _IOC_READ|_IOC_WRITE, 0x4701, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_REDIR", _IOC_READ|_IOC_WRITE, 0x4700, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_VERSION", _IOC_READ|_IOC_WRITE, 0x4703, 0x10 },
+{ "linux/gpio.h", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb408, 0x40 },
+{ "linux/gpio.h", "GPIOHANDLE_SET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb409, 0x40 },
 { "linux/gpio.h", "GPIO_GET_CHIPINFO_IOCTL", _IOC_READ, 0xb401, 0x44 },
+{ "linux/gpio.h", "GPIO_GET_LINEEVENT_IOCTL", _IOC_READ|_IOC_WRITE, 0xb404, 0x30 },
+{ "linux/gpio.h", "GPIO_GET_LINEHANDLE_IOCTL", _IOC_READ|_IOC_WRITE, 0xb403, 0x16c },
 { "linux/gpio.h", "GPIO_GET_LINEINFO_IOCTL", _IOC_READ|_IOC_WRITE, 0xb402, 0x48 },
 { "linux/gsmmux.h", "GSMIOC_DISABLE_NET", _IOC_NONE, 0x4703, 0x00 },
 { "linux/gsmmux.h", "GSMIOC_ENABLE_NET", _IOC_WRITE, 0x4702, 0x34 },
@@ -1418,30 +1436,14 @@
 { "linux/lightnvm.h", "NVM_INFO", _IOC_READ|_IOC_WRITE, 0x4c20, 0x1000 },
 { "linux/lirc.h", "LIRC_GET_FEATURES", _IOC_READ, 0x6900, 0x04 },
 { "linux/lirc.h", "LIRC_GET_LENGTH", _IOC_READ, 0x690f, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_PULSE", _IOC_READ, 0x690b, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_SPACE", _IOC_READ, 0x690d, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MAX_TIMEOUT", _IOC_READ, 0x6909, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_PULSE", _IOC_READ, 0x690a, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_SPACE", _IOC_READ, 0x690c, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MIN_TIMEOUT", _IOC_READ, 0x6908, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_CARRIER", _IOC_READ, 0x6904, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_DUTY_CYCLE", _IOC_READ, 0x6906, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_MODE", _IOC_READ, 0x6902, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_RESOLUTION", _IOC_READ, 0x6907, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_CARRIER", _IOC_READ, 0x6903, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_DUTY_CYCLE", _IOC_READ, 0x6905, 0x04 },
 { "linux/lirc.h", "LIRC_GET_SEND_MODE", _IOC_READ, 0x6901, 0x04 },
-{ "linux/lirc.h", "LIRC_NOTIFY_DECODE", _IOC_NONE, 0x6920, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_END", _IOC_NONE, 0x6922, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_START", _IOC_NONE, 0x6921, 0x00 },
 { "linux/lirc.h", "LIRC_SET_MEASURE_CARRIER_MODE", _IOC_WRITE, 0x691d, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER", _IOC_WRITE, 0x6914, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER_RANGE", _IOC_WRITE, 0x691f, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE", _IOC_WRITE, 0x6916, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE_RANGE", _IOC_WRITE, 0x691e, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER", _IOC_WRITE, 0x691c, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_PULSE", _IOC_WRITE, 0x691a, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_SPACE", _IOC_WRITE, 0x691b, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_MODE", _IOC_WRITE, 0x6912, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT", _IOC_WRITE, 0x6918, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT_REPORTS", _IOC_WRITE, 0x6919, 0x04 },
@@ -1553,19 +1555,19 @@
 { "linux/ndctl.h", "ND_IOCTL_SMART", _IOC_READ|_IOC_WRITE, 0x4e01, 0x84 },
 { "linux/ndctl.h", "ND_IOCTL_SMART_THRESHOLD", _IOC_READ|_IOC_WRITE, 0x4e02, 0x0c },
 { "linux/ndctl.h", "ND_IOCTL_VENDOR", _IOC_READ|_IOC_WRITE, 0x4e09, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE, 0x4e41, 0x48 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ID", _IOC_NONE, 0x4e40, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_IO_CMD", _IOC_READ|_IOC_WRITE, 0x4e43, 0x48 },
@@ -1739,6 +1741,17 @@
 { "linux/raw.h", "RAW_SETBIND", _IOC_NONE, 0xac00, 0x00 },
 { "linux/reiserfs_fs.h", "REISERFS_IOC_UNPACK", _IOC_WRITE, 0xcd01, 0x04 },
 { "linux/rfkill.h", "RFKILL_IOCTL_NOINPUT", _IOC_NONE, 0x5201, 0x00 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_ACCEPT", _IOC_READ|_IOC_WRITE, 0x6307, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_BIND", _IOC_WRITE, 0x6305, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CLOSE", _IOC_WRITE, 0x6304, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CONNECT", _IOC_WRITE, 0x6308, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CREATE", _IOC_READ|_IOC_WRITE, 0x6303, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_LISTEN", _IOC_WRITE, 0x6306, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_RECEIVE", _IOC_READ|_IOC_WRITE, 0x630a, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_SEND", _IOC_WRITE, 0x6309, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST", _IOC_READ|_IOC_WRITE, 0x6302, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST_SIZE", _IOC_READ|_IOC_WRITE, 0x6301, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_MPORT_GET_LIST", _IOC_READ|_IOC_WRITE, 0x630b, 0x04 },
 { "linux/rio_mport_cdev.h", "RIO_ALLOC_DMA", _IOC_READ|_IOC_WRITE, 0x6d13, 0x18 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_ADD", _IOC_WRITE, 0x6d17, 0x20 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_DEL", _IOC_WRITE, 0x6d18, 0x20 },
@@ -2244,6 +2257,8 @@
 { "linux/vhost.h", "VHOST_SET_VRING_ERR", _IOC_WRITE, 0xaf22, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_KICK", _IOC_WRITE, 0xaf20, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_NUM", _IOC_WRITE, 0xaf10, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_GUEST_CID", _IOC_WRITE, 0xaf60, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_RUNNING", _IOC_WRITE, 0xaf61, 0x04 },
 { "linux/videodev2.h", "VIDIOC_CREATE_BUFS", _IOC_READ|_IOC_WRITE, 0x565c, 0xf8 },
 { "linux/videodev2.h", "VIDIOC_CROPCAP", _IOC_READ|_IOC_WRITE, 0x563a, 0x2c },
 { "linux/videodev2.h", "VIDIOC_DBG_G_CHIP_INFO", _IOC_READ|_IOC_WRITE, 0x5666, 0xc8 },
@@ -2348,7 +2363,6 @@
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_SOCKETS_VERSION", _IOC_NONE, 0x07b4, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION", _IOC_NONE, 0x079f, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION2", _IOC_NONE, 0x07a7, 0x00 },
-{ "linux/vsp1.h", "VIDIOC_VSP1_LUT_CONFIG", _IOC_READ|_IOC_WRITE, 0x56c1, 0x400 },
 { "linux/vt.h", "VT_ACTIVATE", 0, 0x5606, 0 },
 { "linux/vt.h", "VT_DISALLOCATE", 0, 0x5608, 0 },
 { "linux/vt.h", "VT_GETHIFONTMASK", 0, 0x560D, 0 },
@@ -2365,6 +2379,7 @@
 { "linux/vt.h", "VT_UNLOCKSWITCH", 0, 0x560C, 0 },
 { "linux/vt.h", "VT_WAITACTIVE", 0, 0x5607, 0 },
 { "linux/vt.h", "VT_WAITEVENT", 0, 0x560E, 0 },
+{ "linux/vtpm_proxy.h", "VTPM_PROXY_IOC_NEW_DEV", _IOC_READ|_IOC_WRITE, 0xa100, 0x14 },
 { "linux/watchdog.h", "WDIOC_GETBOOTSTATUS", _IOC_READ, 0x5702, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETPRETIMEOUT", _IOC_READ, 0x5709, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETSTATUS", _IOC_READ, 0x5701, 0x04 },
@@ -2771,8 +2786,6 @@
 { "staging/android/ion_test.h", "ION_IOC_TEST_DMA_MAPPING", _IOC_WRITE, 0x49f1, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_KERNEL_MAPPING", _IOC_WRITE, 0x49f2, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_SET_FD", _IOC_NONE, 0x49f0, 0x00 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_CREATE_FENCE", _IOC_READ|_IOC_WRITE, 0x5700, 0x28 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_INC", _IOC_WRITE, 0x5701, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_BRIGHTNESS", _IOC_READ, 0x4603, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_COLOR", _IOC_READ, 0x4605, 0x04 },
 { "video/da8xx-fb.h", "FBIOGET_CONTRAST", _IOC_READ, 0x4601, 0x04 },
@@ -2813,6 +2826,7 @@
 { "xen/evtchn.h", "IOCTL_EVTCHN_BIND_VIRQ", _IOC_NONE, 0x4500, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_NOTIFY", _IOC_NONE, 0x4504, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_RESET", _IOC_NONE, 0x4505, 0x00 },
+{ "xen/evtchn.h", "IOCTL_EVTCHN_RESTRICT_DOMID", _IOC_NONE, 0x4506, 0x02 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_UNBIND", _IOC_NONE, 0x4503, 0x04 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR", _IOC_NONE, 0x4702, 0x18 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GRANT_COPY", _IOC_NONE, 0x4708, 0x08 },
diff --git a/linux/32/syscallent.h b/linux/32/syscallent.h
index 9c86485..2295d1e 100644
--- a/linux/32/syscallent.h
+++ b/linux/32/syscallent.h
@@ -1,8 +1,8 @@
 #ifndef sys_ARCH_mmap
 # define sys_ARCH_mmap sys_mmap
 #endif
-[  0] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[  1] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[  0] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[  1] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [  2] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [  3] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
 [  4] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
@@ -80,7 +80,7 @@
 [ 76] = { 6,	TD,		SEN(splice),			"splice"		},
 [ 77] = { 4,	TD,		SEN(tee),			"tee"			},
 [ 78] = { 4,	TD|TF,		SEN(readlinkat),		"readlinkat"		},
-[ 79] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[ 79] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [ 80] = { 2,	TD,		SEN(fstat64),			"fstat64"		},
 [ 81] = { 0,	0,		SEN(sync),			"sync"			},
 [ 82] = { 1,	TD,		SEN(fsync),			"fsync"			},
diff --git a/linux/64/ioctls_inc.h b/linux/64/ioctls_inc.h
index 69cebac..3fc515c 100644
--- a/linux/64/ioctls_inc.h
+++ b/linux/64/ioctls_inc.h
@@ -284,6 +284,7 @@
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_FINI", _IOC_WRITE, 0x6445, 0x04 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_PREP", _IOC_WRITE, 0x6444, 0x18 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_INFO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
+{ "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_MADVISE", _IOC_READ|_IOC_WRITE, 0x6448, 0x0c },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_NEW", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_SUBMIT", _IOC_READ|_IOC_WRITE, 0x6446, 0x20 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6440, 0x10 },
@@ -392,10 +393,13 @@
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_BO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_SHADER_BO", _IOC_READ|_IOC_WRITE, 0x6445, 0x18 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_HANG_STATE", _IOC_READ|_IOC_WRITE, 0x6446, 0xa0 },
+{ "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6447, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_MMAP_BO", _IOC_READ|_IOC_WRITE, 0x6444, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_SUBMIT_CL", _IOC_READ|_IOC_WRITE, 0x6440, 0xa0 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_BO", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_SEQNO", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_ATTACH", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_SIGNAL", _IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_AGP_INIT", _IOC_READ|_IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_ALLOCMEM", _IOC_READ|_IOC_WRITE, 0x6440, 0x20 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_BLIT_SYNC", _IOC_WRITE, 0x644f, 0x08 },
@@ -683,6 +687,16 @@
 { "linux/cdrom.h", "DVD_AUTH", 0, 0x5392, 0 },
 { "linux/cdrom.h", "DVD_READ_STRUCT", 0, 0x5390, 0 },
 { "linux/cdrom.h", "DVD_WRITE_STRUCT", 0, 0x5391, 0 },
+{ "linux/cec.h", "CEC_ADAP_G_CAPS", _IOC_READ|_IOC_WRITE, 0x6100, 0x4c },
+{ "linux/cec.h", "CEC_ADAP_G_LOG_ADDRS", _IOC_READ, 0x6103, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_G_PHYS_ADDR", _IOC_READ, 0x6101, 0x02 },
+{ "linux/cec.h", "CEC_ADAP_S_LOG_ADDRS", _IOC_READ|_IOC_WRITE, 0x6104, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_S_PHYS_ADDR", _IOC_WRITE, 0x6102, 0x02 },
+{ "linux/cec.h", "CEC_DQEVENT", _IOC_READ|_IOC_WRITE, 0x6107, 0x50 },
+{ "linux/cec.h", "CEC_G_MODE", _IOC_READ, 0x6108, 0x04 },
+{ "linux/cec.h", "CEC_RECEIVE", _IOC_READ|_IOC_WRITE, 0x6106, 0x38 },
+{ "linux/cec.h", "CEC_S_MODE", _IOC_WRITE, 0x6109, 0x04 },
+{ "linux/cec.h", "CEC_TRANSMIT", _IOC_READ|_IOC_WRITE, 0x6105, 0x38 },
 { "linux/chio.h", "CHIOEXCHANGE", _IOC_WRITE, 0x6302, 0x1c },
 { "linux/chio.h", "CHIOGELEM", _IOC_WRITE, 0x6310, 0x6c },
 { "linux/chio.h", "CHIOGPARAMS", _IOC_READ, 0x6306, 0x14 },
@@ -969,7 +983,11 @@
 { "linux/gigaset_dev.h", "GIGASET_CONFIG", _IOC_READ|_IOC_WRITE, 0x4701, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_REDIR", _IOC_READ|_IOC_WRITE, 0x4700, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_VERSION", _IOC_READ|_IOC_WRITE, 0x4703, 0x10 },
+{ "linux/gpio.h", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb408, 0x40 },
+{ "linux/gpio.h", "GPIOHANDLE_SET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb409, 0x40 },
 { "linux/gpio.h", "GPIO_GET_CHIPINFO_IOCTL", _IOC_READ, 0xb401, 0x44 },
+{ "linux/gpio.h", "GPIO_GET_LINEEVENT_IOCTL", _IOC_READ|_IOC_WRITE, 0xb404, 0x30 },
+{ "linux/gpio.h", "GPIO_GET_LINEHANDLE_IOCTL", _IOC_READ|_IOC_WRITE, 0xb403, 0x16c },
 { "linux/gpio.h", "GPIO_GET_LINEINFO_IOCTL", _IOC_READ|_IOC_WRITE, 0xb402, 0x48 },
 { "linux/gsmmux.h", "GSMIOC_DISABLE_NET", _IOC_NONE, 0x4703, 0x00 },
 { "linux/gsmmux.h", "GSMIOC_ENABLE_NET", _IOC_WRITE, 0x4702, 0x34 },
@@ -1418,30 +1436,14 @@
 { "linux/lightnvm.h", "NVM_INFO", _IOC_READ|_IOC_WRITE, 0x4c20, 0x1000 },
 { "linux/lirc.h", "LIRC_GET_FEATURES", _IOC_READ, 0x6900, 0x04 },
 { "linux/lirc.h", "LIRC_GET_LENGTH", _IOC_READ, 0x690f, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_PULSE", _IOC_READ, 0x690b, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_SPACE", _IOC_READ, 0x690d, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MAX_TIMEOUT", _IOC_READ, 0x6909, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_PULSE", _IOC_READ, 0x690a, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_SPACE", _IOC_READ, 0x690c, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MIN_TIMEOUT", _IOC_READ, 0x6908, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_CARRIER", _IOC_READ, 0x6904, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_DUTY_CYCLE", _IOC_READ, 0x6906, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_MODE", _IOC_READ, 0x6902, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_RESOLUTION", _IOC_READ, 0x6907, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_CARRIER", _IOC_READ, 0x6903, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_DUTY_CYCLE", _IOC_READ, 0x6905, 0x04 },
 { "linux/lirc.h", "LIRC_GET_SEND_MODE", _IOC_READ, 0x6901, 0x04 },
-{ "linux/lirc.h", "LIRC_NOTIFY_DECODE", _IOC_NONE, 0x6920, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_END", _IOC_NONE, 0x6922, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_START", _IOC_NONE, 0x6921, 0x00 },
 { "linux/lirc.h", "LIRC_SET_MEASURE_CARRIER_MODE", _IOC_WRITE, 0x691d, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER", _IOC_WRITE, 0x6914, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER_RANGE", _IOC_WRITE, 0x691f, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE", _IOC_WRITE, 0x6916, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE_RANGE", _IOC_WRITE, 0x691e, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER", _IOC_WRITE, 0x691c, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_PULSE", _IOC_WRITE, 0x691a, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_SPACE", _IOC_WRITE, 0x691b, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_MODE", _IOC_WRITE, 0x6912, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT", _IOC_WRITE, 0x6918, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT_REPORTS", _IOC_WRITE, 0x6919, 0x04 },
@@ -1553,19 +1555,19 @@
 { "linux/ndctl.h", "ND_IOCTL_SMART", _IOC_READ|_IOC_WRITE, 0x4e01, 0x84 },
 { "linux/ndctl.h", "ND_IOCTL_SMART_THRESHOLD", _IOC_READ|_IOC_WRITE, 0x4e02, 0x0c },
 { "linux/ndctl.h", "ND_IOCTL_VENDOR", _IOC_READ|_IOC_WRITE, 0x4e09, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE, 0x4e41, 0x48 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ID", _IOC_NONE, 0x4e40, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_IO_CMD", _IOC_READ|_IOC_WRITE, 0x4e43, 0x48 },
@@ -1739,6 +1741,17 @@
 { "linux/raw.h", "RAW_SETBIND", _IOC_NONE, 0xac00, 0x00 },
 { "linux/reiserfs_fs.h", "REISERFS_IOC_UNPACK", _IOC_WRITE, 0xcd01, 0x08 },
 { "linux/rfkill.h", "RFKILL_IOCTL_NOINPUT", _IOC_NONE, 0x5201, 0x00 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_ACCEPT", _IOC_READ|_IOC_WRITE, 0x6307, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_BIND", _IOC_WRITE, 0x6305, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CLOSE", _IOC_WRITE, 0x6304, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CONNECT", _IOC_WRITE, 0x6308, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CREATE", _IOC_READ|_IOC_WRITE, 0x6303, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_LISTEN", _IOC_WRITE, 0x6306, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_RECEIVE", _IOC_READ|_IOC_WRITE, 0x630a, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_SEND", _IOC_WRITE, 0x6309, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST", _IOC_READ|_IOC_WRITE, 0x6302, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST_SIZE", _IOC_READ|_IOC_WRITE, 0x6301, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_MPORT_GET_LIST", _IOC_READ|_IOC_WRITE, 0x630b, 0x04 },
 { "linux/rio_mport_cdev.h", "RIO_ALLOC_DMA", _IOC_READ|_IOC_WRITE, 0x6d13, 0x18 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_ADD", _IOC_WRITE, 0x6d17, 0x20 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_DEL", _IOC_WRITE, 0x6d18, 0x20 },
@@ -2244,6 +2257,8 @@
 { "linux/vhost.h", "VHOST_SET_VRING_ERR", _IOC_WRITE, 0xaf22, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_KICK", _IOC_WRITE, 0xaf20, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_NUM", _IOC_WRITE, 0xaf10, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_GUEST_CID", _IOC_WRITE, 0xaf60, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_RUNNING", _IOC_WRITE, 0xaf61, 0x04 },
 { "linux/videodev2.h", "VIDIOC_CREATE_BUFS", _IOC_READ|_IOC_WRITE, 0x565c, 0x100 },
 { "linux/videodev2.h", "VIDIOC_CROPCAP", _IOC_READ|_IOC_WRITE, 0x563a, 0x2c },
 { "linux/videodev2.h", "VIDIOC_DBG_G_CHIP_INFO", _IOC_READ|_IOC_WRITE, 0x5666, 0xc8 },
@@ -2348,7 +2363,6 @@
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_SOCKETS_VERSION", _IOC_NONE, 0x07b4, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION", _IOC_NONE, 0x079f, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION2", _IOC_NONE, 0x07a7, 0x00 },
-{ "linux/vsp1.h", "VIDIOC_VSP1_LUT_CONFIG", _IOC_READ|_IOC_WRITE, 0x56c1, 0x400 },
 { "linux/vt.h", "VT_ACTIVATE", 0, 0x5606, 0 },
 { "linux/vt.h", "VT_DISALLOCATE", 0, 0x5608, 0 },
 { "linux/vt.h", "VT_GETHIFONTMASK", 0, 0x560D, 0 },
@@ -2365,6 +2379,7 @@
 { "linux/vt.h", "VT_UNLOCKSWITCH", 0, 0x560C, 0 },
 { "linux/vt.h", "VT_WAITACTIVE", 0, 0x5607, 0 },
 { "linux/vt.h", "VT_WAITEVENT", 0, 0x560E, 0 },
+{ "linux/vtpm_proxy.h", "VTPM_PROXY_IOC_NEW_DEV", _IOC_READ|_IOC_WRITE, 0xa100, 0x14 },
 { "linux/watchdog.h", "WDIOC_GETBOOTSTATUS", _IOC_READ, 0x5702, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETPRETIMEOUT", _IOC_READ, 0x5709, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETSTATUS", _IOC_READ, 0x5701, 0x04 },
@@ -2771,8 +2786,6 @@
 { "staging/android/ion_test.h", "ION_IOC_TEST_DMA_MAPPING", _IOC_WRITE, 0x49f1, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_KERNEL_MAPPING", _IOC_WRITE, 0x49f2, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_SET_FD", _IOC_NONE, 0x49f0, 0x00 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_CREATE_FENCE", _IOC_READ|_IOC_WRITE, 0x5700, 0x28 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_INC", _IOC_WRITE, 0x5701, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_BRIGHTNESS", _IOC_READ, 0x4603, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_COLOR", _IOC_READ, 0x4605, 0x04 },
 { "video/da8xx-fb.h", "FBIOGET_CONTRAST", _IOC_READ, 0x4601, 0x04 },
@@ -2813,6 +2826,7 @@
 { "xen/evtchn.h", "IOCTL_EVTCHN_BIND_VIRQ", _IOC_NONE, 0x4500, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_NOTIFY", _IOC_NONE, 0x4504, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_RESET", _IOC_NONE, 0x4505, 0x00 },
+{ "xen/evtchn.h", "IOCTL_EVTCHN_RESTRICT_DOMID", _IOC_NONE, 0x4506, 0x02 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_UNBIND", _IOC_NONE, 0x4503, 0x04 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR", _IOC_NONE, 0x4702, 0x18 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GRANT_COPY", _IOC_NONE, 0x4708, 0x10 },
diff --git a/linux/64/syscallent.h b/linux/64/syscallent.h
index 55c011c..5bd6cb0 100644
--- a/linux/64/syscallent.h
+++ b/linux/64/syscallent.h
@@ -1,5 +1,5 @@
-[  0] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[  1] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[  0] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[  1] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [  2] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [  3] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
 [  4] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
diff --git a/linux/alpha/syscallent.h b/linux/alpha/syscallent.h
index eaa316f..eab60a5 100644
--- a/linux/alpha/syscallent.h
+++ b/linux/alpha/syscallent.h
@@ -361,8 +361,8 @@
 [395] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [396] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [397] = { 5,	0,		SEN(tuxcall),			"tuxcall"		},
-[398] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[399] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[398] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[399] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [400] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [401] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [402] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -417,7 +417,7 @@
 [452] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [453] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [454] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[455] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[455] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [456] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [457] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [458] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h
index 18910e4..356468b 100644
--- a/linux/arm/syscallent.h
+++ b/linux/arm/syscallent.h
@@ -268,8 +268,8 @@
 [240] = { 6,	0,		SEN(futex),			"futex"			},
 [241] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [242] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
-[243] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[244] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[243] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[244] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [245] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [246] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [247] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -351,7 +351,7 @@
 [324] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [325] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [326] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[327] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[327] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [328] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [329] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [330] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/asm_stat.h b/linux/asm_stat.h
index c941f22..72a67e1 100644
--- a/linux/asm_stat.h
+++ b/linux/asm_stat.h
@@ -1,2 +1,52 @@
-#include "kernel_types.h"
-#include <asm/stat.h>
+#ifndef STRACE_ASM_STAT_H
+#define STRACE_ASM_STAT_H
+
+# include "kernel_types.h"
+
+# undef dev_t
+# undef gid_t
+# undef ino_t
+# undef loff_t
+# undef mode_t
+# undef nlink_t
+# undef off64_t
+# undef off_t
+# undef time_t
+# undef uid_t
+
+# define dev_t		__kernel_dev_t
+# define gid_t		__kernel_gid_t
+# define ino_t		__kernel_ino_t
+# define loff_t		__kernel_loff_t
+# define mode_t		__kernel_mode_t
+# define nlink_t	__kernel_nlink_t
+# define off64_t	__kernel_off64_t
+# define off_t		__kernel_off_t
+# define time_t		__kernel_time_t
+# define uid_t		__kernel_uid_t
+
+# include <asm/stat.h>
+
+# undef dev_t
+# undef gid_t
+# undef ino_t
+# undef loff_t
+# undef mode_t
+# undef nlink_t
+# undef off64_t
+# undef off_t
+# undef time_t
+# undef uid_t
+
+# define dev_t		dev_t
+# define gid_t		gid_t
+# define ino_t		ino_t
+# define loff_t		loff_t
+# define mode_t		mode_t
+# define nlink_t	nlink_t
+# define off64_t	off64_t
+# define off_t		off_t
+# define time_t		time_t
+# define uid_t		uid_t
+
+#endif /* !STRACE_ASM_STAT_H */
diff --git a/linux/avr32/syscallent.h b/linux/avr32/syscallent.h
index 0b4ceac..fbf9792 100644
--- a/linux/avr32/syscallent.h
+++ b/linux/avr32/syscallent.h
@@ -222,8 +222,8 @@
 [194] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [195] = { 2,	0,		SEN(capget),			"capget"		},
 [196] = { 2,	0,		SEN(capset),			"capset"		},
-[197] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[198] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[197] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[198] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [199] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [200] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [201] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -273,7 +273,7 @@
 [245] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [246] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [247] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[248] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[248] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [249] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [250] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [251] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
@@ -351,3 +351,5 @@
 [323] = { 2,	0,		SEN(membarrier),		"membarrier",		},
 [324] = { 3,	TM,		SEN(mlock2),			"mlock2"		},
 [325] = { 6,	TD,		SEN(copy_file_range),		"copy_file_range"	},
+[326] = { 6,	TD,		SEN(preadv2),			"preadv2"		},
+[327] = { 6,	TD,		SEN(pwritev2),			"pwritev2"		},
diff --git a/linux/bfin/syscallent.h b/linux/bfin/syscallent.h
index dd99fa6..1f90538 100644
--- a/linux/bfin/syscallent.h
+++ b/linux/bfin/syscallent.h
@@ -270,8 +270,8 @@
 [242] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [243] = { 1,	0,		SEN(set_thread_area),		"set_thread_area"	},
 [244] = { 1,	0,		SEN(get_thread_area),		"get_thread_area"	},
-[245] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[246] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[245] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[246] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [247] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [248] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [249] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -325,7 +325,7 @@
 [297] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [298] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [299] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[300] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[300] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [301] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [302] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [303] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/dummy.h b/linux/dummy.h
index 587163c..87d2127 100644
--- a/linux/dummy.h
+++ b/linux/dummy.h
@@ -26,6 +26,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_LINUX_DUMMY_H
+#define STRACE_LINUX_DUMMY_H
+
 #ifndef HAVE_STRUCT___OLD_KERNEL_STAT
 #define	sys_oldfstat		printargs
 #define	sys_oldstat		printargs
@@ -156,3 +159,5 @@
 #define	sys_oldolduname		printargs
 #define	sys_olduname		printargs
 #define	sys_sysfs		printargs
+
+#endif /* !STRACE_LINUX_DUMMY_H */
diff --git a/linux/hppa/syscallent.h b/linux/hppa/syscallent.h
index 4928047..de0e11d 100644
--- a/linux/hppa/syscallent.h
+++ b/linux/hppa/syscallent.h
@@ -217,8 +217,8 @@
 [212] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [213] = { 5,	0,		SEN(printargs),			"set_thread_area"	},
 [214] = { 5,	0,		SEN(printargs),			"get_thread_area"	},
-[215] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[216] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[215] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[216] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [217] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [218] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [219] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -282,7 +282,7 @@
 [277] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [278] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [279] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[280] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[280] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [281] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [282] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [283] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/i386/syscallent.h b/linux/i386/syscallent.h
index d6175fa..307f46a 100644
--- a/linux/i386/syscallent.h
+++ b/linux/i386/syscallent.h
@@ -270,8 +270,8 @@
 [242] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [243] = { 1,	0,		SEN(set_thread_area),		"set_thread_area"	},
 [244] = { 1,	0,		SEN(get_thread_area),		"get_thread_area"	},
-[245] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[246] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[245] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[246] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [247] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [248] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [249] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -325,7 +325,7 @@
 [297] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [298] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [299] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[300] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[300] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [301] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [302] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [303] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/ia64/syscallent.h b/linux/ia64/syscallent.h
index 713cab8..5ba6afb 100644
--- a/linux/ia64/syscallent.h
+++ b/linux/ia64/syscallent.h
@@ -254,8 +254,8 @@
 [1235] = { 3,	TS,		SEN(tgkill),			"tgkill"		},
 [1236] = { 1,	TP|SE,		SEN(exit),			"exit_group"		},
 [1237] = { 3,	0,		SEN(lookup_dcookie),		"lookup_dcookie"	},
-[1238] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[1239] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[1238] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[1239] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [1240] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [1241] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [1242] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
diff --git a/linux/inet_diag.h b/linux/inet_diag.h
index 723a1b1..69012af 100644
--- a/linux/inet_diag.h
+++ b/linux/inet_diag.h
@@ -1,3 +1,6 @@
+#ifndef STRACE_LINUX_INET_DIAG_H
+#define STRACE_LINUX_INET_DIAG_H
+
 #define TCPDIAG_GETSOCK 18
 #define DCCPDIAG_GETSOCK 19
 
@@ -36,3 +39,5 @@
 	uint32_t idiag_uid;
 	uint32_t idiag_inode;
 };
+
+#endif /* !STRACE_LINUX_INET_DIAG_H */
diff --git a/linux/m68k/syscallent.h b/linux/m68k/syscallent.h
index 0f4895c..6299a03 100644
--- a/linux/m68k/syscallent.h
+++ b/linux/m68k/syscallent.h
@@ -266,8 +266,8 @@
 [238] = { 3,	TM,		SEN(madvise),			"madvise"		},
 [239] = { 3,	TD,		SEN(fcntl64),			"fcntl64"		},
 [240] = { 4,	TD,		SEN(readahead),			"readahead"		},
-[241] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[242] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[241] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[242] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [243] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [244] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [245] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -318,7 +318,7 @@
 [290] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [291] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [292] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[293] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[293] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [294] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [295] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [296] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/microblaze/syscallent.h b/linux/microblaze/syscallent.h
index 482e275..6974872 100644
--- a/linux/microblaze/syscallent.h
+++ b/linux/microblaze/syscallent.h
@@ -270,8 +270,8 @@
 [242] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [243] = { 1,	0,		SEN(set_thread_area),		"set_thread_area"	},
 [244] = { 1,	0,		SEN(get_thread_area),		"get_thread_area"	},
-[245] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[246] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[245] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[246] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [247] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [248] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [249] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -325,7 +325,7 @@
 [297] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [298] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [299] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[300] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[300] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [301] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [302] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [303] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/mips/genstub.sh b/linux/mips/genstub.sh
index 5ebb1d4..11f141f 100755
--- a/linux/mips/genstub.sh
+++ b/linux/mips/genstub.sh
@@ -6,5 +6,5 @@
 for n in n32 n64 o32; do
 	in="$srcdir/syscallent-$n.h"
 	out="$dstdir/syscallent-$n-stub.h"
-	sed -n '/^#if/,/^#else/ {s/^\([^{]*{[^,]*,[^,]*,[[:space:]]*\)[^,[:space:]]\+,[[:space:]]*"\([^"]\+".*\)/\1SEN(printargs), "'$n'_\2/; s/^\[.*/&/p}' < "$in" > "$out"
+	sed -r -n '/^#if/,/^#else/ {s/^([^{]*\{[^,]*,[^,]*,[[:space:]]*)[^,[:space:]]+,[[:space:]]*"([^"]+".*)/\1SEN(printargs), "'$n':\2/; s/^\[.*/&/p}' < "$in" > "$out"
 done
diff --git a/linux/mips/syscallent-n32.h b/linux/mips/syscallent-n32.h
index 398b12c..b061355 100644
--- a/linux/mips/syscallent-n32.h
+++ b/linux/mips/syscallent-n32.h
@@ -200,8 +200,8 @@
 [6197] = { 3,	0,		SEN(printargs),			"cacheflush"		},
 [6198] = { 3,	0,		SEN(printargs),			"cachectl"		},
 [6199] = { 4,	0,		SEN(sysmips),			"sysmips"		},
-[6200] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[6201] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[6200] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[6201] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [6202] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [6203] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [6204] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
diff --git a/linux/mips/syscallent-n64.h b/linux/mips/syscallent-n64.h
index 7321f0e..42c1bfd 100644
--- a/linux/mips/syscallent-n64.h
+++ b/linux/mips/syscallent-n64.h
@@ -200,8 +200,8 @@
 [5197] = { 3,	0,		SEN(printargs),			"cacheflush"		},
 [5198] = { 3,	0,		SEN(printargs),			"cachectl"		},
 [5199] = { 4,	0,		SEN(sysmips),			"sysmips"		},
-[5200] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[5201] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[5200] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[5201] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [5202] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [5203] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [5204] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
diff --git a/linux/mips/syscallent-o32.h b/linux/mips/syscallent-o32.h
index cb8afb9..c92005f 100644
--- a/linux/mips/syscallent-o32.h
+++ b/linux/mips/syscallent-o32.h
@@ -241,8 +241,8 @@
 [4238] = { 6,	0,		SEN(futex),			"futex"			},
 [4239] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [4240] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
-[4241] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[4242] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[4241] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[4242] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [4243] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [4244] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [4245] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -293,7 +293,7 @@
 [4290] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [4291] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [4292] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[4293] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[4293] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [4294] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [4295] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [4296] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/netlink_diag.h b/linux/netlink_diag.h
index 276baa7..a52507c 100644
--- a/linux/netlink_diag.h
+++ b/linux/netlink_diag.h
@@ -1,3 +1,6 @@
+#ifndef STRACE_LINUX_NETLINK_DIAG_H
+#define STRACE_LINUX_NETLINK_DIAG_H
+
 struct netlink_diag_req {
 	uint8_t sdiag_family;
 	uint8_t sdiag_protocol;
@@ -22,3 +25,5 @@
 
 #define NDIAG_SHOW_MEMINFO           0x00000001
 #define NDIAG_PROTO_ALL              ((uint8_t) ~0)
+
+#endif /* !STRACE_LINUX_NETLINK_DIAG_H */
diff --git a/linux/powerpc/syscallent.h b/linux/powerpc/syscallent.h
index b6dfb85..b10b83e 100644
--- a/linux/powerpc/syscallent.h
+++ b/linux/powerpc/syscallent.h
@@ -253,8 +253,8 @@
 [224] = { },
 [225] = { 5,	0,		SEN(printargs),			"tuxcall"		},
 [226] = { 4,	TD|TN,		SEN(sendfile64),		"sendfile64"		},
-[227] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[228] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[227] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[228] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [229] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [230] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [231] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -317,7 +317,7 @@
 [288] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [289] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [290] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[291] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[291] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [292] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [293] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [294] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/powerpc64/arch_regs.c b/linux/powerpc64/arch_regs.c
index 9064651..c50855d 100644
--- a/linux/powerpc64/arch_regs.c
+++ b/linux/powerpc64/arch_regs.c
@@ -1,2 +1,3 @@
 #include "powerpc/arch_regs.c"
+#undef ARCH_PC_REG
 #define ARCH_PC_REG ppc_regs.nip
diff --git a/linux/powerpc64/syscallent.h b/linux/powerpc64/syscallent.h
index e0c18af..ba22c3c 100644
--- a/linux/powerpc64/syscallent.h
+++ b/linux/powerpc64/syscallent.h
@@ -248,8 +248,8 @@
 [224] = { },
 [225] = { 5,	0,		SEN(printargs),			"tuxcall"		},
 [226] = { },
-[227] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[228] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[227] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[228] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [229] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [230] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [231] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
diff --git a/linux/riscv/arch_regs.c b/linux/riscv/arch_regs.c
new file mode 100644
index 0000000..40be17d
--- /dev/null
+++ b/linux/riscv/arch_regs.c
@@ -0,0 +1,3 @@
+static struct user_regs_struct riscv_regs;
+#define ARCH_REGS_FOR_GETREGSET riscv_regs
+#define ARCH_PC_REG riscv_regs.pc
diff --git a/linux/riscv/errnoent1.h b/linux/riscv/errnoent1.h
new file mode 100644
index 0000000..2a5c728
--- /dev/null
+++ b/linux/riscv/errnoent1.h
@@ -0,0 +1,2 @@
+/* RISC-V rv32 and rv64 */
+#include "../errnoent.h"
diff --git a/linux/riscv/get_error.c b/linux/riscv/get_error.c
new file mode 100644
index 0000000..be640d0
--- /dev/null
+++ b/linux/riscv/get_error.c
@@ -0,0 +1,10 @@
+static void
+get_error(struct tcb *tcp, const bool check_errno)
+{
+	if (check_errno && is_negated_errno(riscv_regs.a0)) {
+		tcp->u_rval = -1;
+		tcp->u_error = -riscv_regs.a0;
+	} else {
+		tcp->u_rval = riscv_regs.a0;
+	}
+}
diff --git a/linux/riscv/get_scno.c b/linux/riscv/get_scno.c
new file mode 100644
index 0000000..0ca1ed3
--- /dev/null
+++ b/linux/riscv/get_scno.c
@@ -0,0 +1,7 @@
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+	tcp->scno = riscv_regs.a7;
+	return 1;
+}
diff --git a/linux/riscv/get_syscall_args.c b/linux/riscv/get_syscall_args.c
new file mode 100644
index 0000000..746e085
--- /dev/null
+++ b/linux/riscv/get_syscall_args.c
@@ -0,0 +1,12 @@
+/* Return -1 on error or 1 on success (never 0!). */
+static int
+get_syscall_args(struct tcb *tcp)
+{
+	tcp->u_arg[0] = riscv_regs.a0;
+	tcp->u_arg[1] = riscv_regs.a1;
+	tcp->u_arg[2] = riscv_regs.a2;
+	tcp->u_arg[3] = riscv_regs.a3;
+	tcp->u_arg[4] = riscv_regs.a4;
+	tcp->u_arg[5] = riscv_regs.a5;
+	return 1;
+}
diff --git a/linux/riscv/ioctls_arch0.h b/linux/riscv/ioctls_arch0.h
new file mode 100644
index 0000000..9c039fc
--- /dev/null
+++ b/linux/riscv/ioctls_arch0.h
@@ -0,0 +1 @@
+/* Generated by ioctls_gen.sh from definitions found in $linux/arch/riscv/include/ tree. */
diff --git a/linux/riscv/ioctls_arch1.h b/linux/riscv/ioctls_arch1.h
new file mode 100644
index 0000000..41d00f9
--- /dev/null
+++ b/linux/riscv/ioctls_arch1.h
@@ -0,0 +1 @@
+#include "ioctls_arch0.h"
diff --git a/linux/riscv/ioctls_inc0.h b/linux/riscv/ioctls_inc0.h
new file mode 100644
index 0000000..f9939fa
--- /dev/null
+++ b/linux/riscv/ioctls_inc0.h
@@ -0,0 +1 @@
+#include "64/ioctls_inc.h"
diff --git a/linux/riscv/ioctls_inc1.h b/linux/riscv/ioctls_inc1.h
new file mode 100644
index 0000000..4aecf98
--- /dev/null
+++ b/linux/riscv/ioctls_inc1.h
@@ -0,0 +1 @@
+#include "32/ioctls_inc.h"
diff --git a/linux/riscv/signalent1.h b/linux/riscv/signalent1.h
new file mode 100644
index 0000000..39891b8
--- /dev/null
+++ b/linux/riscv/signalent1.h
@@ -0,0 +1,2 @@
+/* RISC-V rv32 and rv64 */
+#include "../signalent.h"
diff --git a/linux/riscv/syscallent.h b/linux/riscv/syscallent.h
new file mode 100644
index 0000000..7c416ef
--- /dev/null
+++ b/linux/riscv/syscallent.h
@@ -0,0 +1 @@
+#include "64/syscallent.h"
diff --git a/linux/riscv/syscallent1.h b/linux/riscv/syscallent1.h
new file mode 100644
index 0000000..22eff67
--- /dev/null
+++ b/linux/riscv/syscallent1.h
@@ -0,0 +1 @@
+#include "32/syscallent.h"
diff --git a/linux/s390/syscallent.h b/linux/s390/syscallent.h
index fb5ddc1..a7004ae 100644
--- a/linux/s390/syscallent.h
+++ b/linux/s390/syscallent.h
@@ -271,8 +271,8 @@
 [240] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [241] = { 3,	TS,		SEN(tgkill),			"tgkill"		},
 [242] = { },
-[243] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[244] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[243] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[244] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [245] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [246] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [247] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -321,7 +321,7 @@
 [290] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [291] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [292] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[293] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[293] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [294] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [295] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [296] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/s390x/arch_regs.c b/linux/s390x/arch_regs.c
index 74aaaf6..62aece7 100644
--- a/linux/s390x/arch_regs.c
+++ b/linux/s390x/arch_regs.c
@@ -1,2 +1 @@
 #include "s390/arch_regs.c"
-#define ARCH_PC_REG s390_regset.psw.addr
diff --git a/linux/s390x/syscallent.h b/linux/s390x/syscallent.h
index bf9c9fa..9d1e944 100644
--- a/linux/s390x/syscallent.h
+++ b/linux/s390x/syscallent.h
@@ -255,8 +255,8 @@
 [240] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [241] = { 3,	TS,		SEN(tgkill),			"tgkill"		},
 [242] = { },
-[243] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[244] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[243] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[244] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [245] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [246] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [247] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
diff --git a/linux/sh/syscallent.h b/linux/sh/syscallent.h
index d2b462d..5a0bef0 100644
--- a/linux/sh/syscallent.h
+++ b/linux/sh/syscallent.h
@@ -270,8 +270,8 @@
 [241] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [242] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [243 ... 244] = { },
-[245] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[246] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[245] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[246] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [247] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [248] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [249] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -325,7 +325,7 @@
 [297] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [298] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [299] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[300] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[300] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [301] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [302] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [303] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
@@ -394,6 +394,20 @@
 [366] = { 6,	0,		SEN(process_vm_writev),		"process_vm_writev"	},
 [367] = { 5,	0,		SEN(kcmp),			"kcmp"			},
 [368] = { 3,	TD,		SEN(finit_module),		"finit_module"		},
+[369] = { 3,	0,		SEN(sched_setattr),		"sched_setattr"		},
+[370] = { 4,	0,		SEN(sched_getattr),		"sched_getattr"		},
+[371] = { 5,	TD|TF,		SEN(renameat2),			"renameat2"		},
+[372] = { 3,	0,		SEN(seccomp),			"seccomp",		},
+[373] = { 3,	0,		SEN(getrandom),			"getrandom",		},
+[374] = { 2,	TD,		SEN(memfd_create),		"memfd_create",		},
+[375] = { 3,	TD,		SEN(bpf),			"bpf",			},
+[376] = { 5,	TD|TF|TP|SE|SI,	SEN(execveat),			"execveat",		},
+[377] = { 1,	TD,		SEN(userfaultfd),		"userfaultfd",		},
+[378] = { 2,	0,		SEN(membarrier),		"membarrier",		},
+[379] = { 3,	TM,		SEN(mlock2),			"mlock2"		},
+[380] = { 6,	TD,		SEN(copy_file_range),		"copy_file_range"	},
+[381] = { 6,	TD,		SEN(preadv2),			"preadv2"		},
+[382] = { 6,	TD,		SEN(pwritev2),			"pwritev2"		},
 
 #define SYS_socket_subcall	400
 #include "subcall.h"
diff --git a/linux/sh64/syscallent.h b/linux/sh64/syscallent.h
index 3504881..5e4ee72 100644
--- a/linux/sh64/syscallent.h
+++ b/linux/sh64/syscallent.h
@@ -296,8 +296,8 @@
 [269] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [270] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [271 ... 272] = { },
-[273] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[274] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[273] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[274] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [275] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [276] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [277] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -323,7 +323,7 @@
 [297] = { 3,	TD,		SEN(fstatfs64),			"fstatfs64"		},
 [298] = { 3,	TS,		SEN(tgkill),			"tgkill"		},
 [299] = { 2,	TF,		SEN(utimes),			"utimes"		},
-[300] = { 4,	TD,		SEN(fadvise64),			"fadvise64_64"		},
+[300] = { 4,	TD,		SEN(fadvise64_64),		"fadvise64_64"		},
 [301] = { },
 [302] = { 6,	TM,		SEN(mbind),			"mbind"			},
 [303] = { 5,	TM,		SEN(get_mempolicy),		"get_mempolicy"		},
@@ -351,7 +351,7 @@
 [325] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [326] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [327] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[328] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[328] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [329] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [330] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [331] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
@@ -403,6 +403,20 @@
 [377] = { 6,	0,		SEN(process_vm_writev),		"process_vm_writev"	},
 [378] = { 5,	0,		SEN(kcmp),			"kcmp"			},
 [379] = { 3,	TD,		SEN(finit_module),		"finit_module"		},
+[380] = { 3,	0,		SEN(sched_setattr),		"sched_setattr"		},
+[381] = { 4,	0,		SEN(sched_getattr),		"sched_getattr"		},
+[382] = { 5,	TD|TF,		SEN(renameat2),			"renameat2"		},
+[383] = { 3,	0,		SEN(seccomp),			"seccomp",		},
+[384] = { 3,	0,		SEN(getrandom),			"getrandom",		},
+[385] = { 2,	TD,		SEN(memfd_create),		"memfd_create",		},
+[386] = { 3,	TD,		SEN(bpf),			"bpf",			},
+[387] = { 5,	TD|TF|TP|SE|SI,	SEN(execveat),			"execveat",		},
+[388] = { 1,	TD,		SEN(userfaultfd),		"userfaultfd",		},
+[389] = { 2,	0,		SEN(membarrier),		"membarrier",		},
+[390] = { 3,	TM,		SEN(mlock2),			"mlock2"		},
+[391] = { 6,	TD,		SEN(copy_file_range),		"copy_file_range"	},
+[392] = { 6,	TD,		SEN(preadv2),			"preadv2"		},
+[393] = { 6,	TD,		SEN(pwritev2),			"pwritev2"		},
 
 #define SYS_socket_subcall	400
 #include "subcall.h"
diff --git a/linux/sock_diag.h b/linux/sock_diag.h
index e5dd066..ba0c114 100644
--- a/linux/sock_diag.h
+++ b/linux/sock_diag.h
@@ -1,6 +1,11 @@
+#ifndef STRACE_LINUX_SOCK_DIAG_H
+#define STRACE_LINUX_SOCK_DIAG_H
+
 #define SOCK_DIAG_BY_FAMILY 20
 
 struct sock_diag_req {
 	uint8_t	sdiag_family;
 	uint8_t	sdiag_protocol;
 };
+
+#endif /* !STRACE_LINUX_SOCK_DIAG_H */
diff --git a/linux/sparc/arch_sigreturn.c b/linux/sparc/arch_sigreturn.c
index 9e86efa..0c0e511 100644
--- a/linux/sparc/arch_sigreturn.c
+++ b/linux/sparc/arch_sigreturn.c
@@ -1,12 +1,22 @@
+#ifndef SIZEOF_STRUCT_SPARC_STACKF
+# define SIZEOF_STRUCT_SPARC_STACKF	sizeof(struct sparc_stackf)
+#endif
+#ifndef SIZEOF_STRUCT_PT_REGS
+# define SIZEOF_STRUCT_PT_REGS		sizeof(struct pt_regs)
+#endif
+#ifndef PERSONALITY_WORDSIZE
+# define PERSONALITY_WORDSIZE		PERSONALITY0_WORDSIZE
+#endif
+
 static void
 arch_sigreturn(struct tcb *tcp)
 {
-	long fp = sparc_regs.u_regs[U_REG_FP] + sizeof(struct sparc_stackf);
+	long fp = sparc_regs.u_regs[U_REG_FP] +
+		  SIZEOF_STRUCT_SPARC_STACKF + SIZEOF_STRUCT_PT_REGS;
 	struct {
-		struct pt_regs si_regs;
-		int si_mask;
-		void *fpu_save;
-		long insns[2] ATTRIBUTE_ALIGNED(8);
+		unsigned int mask;
+		char fpu_save[PERSONALITY_WORDSIZE];
+		char insns[PERSONALITY_WORDSIZE * 2] ATTRIBUTE_ALIGNED(8);
 		unsigned int extramask[NSIG / 8 / sizeof(int) - 1];
 	} frame;
 
@@ -15,9 +25,13 @@
 	} else {
 		unsigned int mask[NSIG / 8 / sizeof(int)];
 
-		mask[0] = frame.si_mask;
+		mask[0] = frame.mask;
 		memcpy(mask + 1, frame.extramask, sizeof(frame.extramask));
 		tprintsigmask_addr("{mask=", mask);
 		tprints("}");
 	}
 }
+
+#undef PERSONALITY_WORDSIZE
+#undef SIZEOF_STRUCT_PT_REGS
+#undef SIZEOF_STRUCT_SPARC_STACKF
diff --git a/linux/sparc/syscallent.h b/linux/sparc/syscallent.h
index ec86f7e..69f5f47 100644
--- a/linux/sparc/syscallent.h
+++ b/linux/sparc/syscallent.h
@@ -266,8 +266,8 @@
 [265] = { 1,	0,		SEN(timer_delete),		"timer_delete"		},
 [266] = { 3,	0,		SEN(timer_create),		"timer_create"		},
 [267] = { },
-[268] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[269] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[268] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[269] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [270] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [271] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
 [272] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
@@ -287,7 +287,7 @@
 [286] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [287] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [288] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[289] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[289] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [290] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [291] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [292] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/sparc64/arch_regs.c b/linux/sparc64/arch_regs.c
index 072a355..c1c2fae 100644
--- a/linux/sparc64/arch_regs.c
+++ b/linux/sparc64/arch_regs.c
@@ -1,2 +1,3 @@
 #include "sparc/arch_regs.c"
+#undef ARCH_PC_REG
 #define ARCH_PC_REG sparc_regs.tpc
diff --git a/linux/sparc64/arch_sigreturn.c b/linux/sparc64/arch_sigreturn.c
index aeec981..feac9da 100644
--- a/linux/sparc64/arch_sigreturn.c
+++ b/linux/sparc64/arch_sigreturn.c
@@ -1 +1,19 @@
+#define arch_sigreturn	sparc64_arch_sigreturn
 #include "sparc/arch_sigreturn.c"
+#undef arch_sigreturn
+
+#define SIZEOF_STRUCT_SPARC_STACKF	sizeof(struct sparc_stackf32)
+#define SIZEOF_STRUCT_PT_REGS		sizeof(struct pt_regs32)
+#define PERSONALITY_WORDSIZE		PERSONALITY1_WORDSIZE
+#define arch_sigreturn	sparc32_arch_sigreturn
+#include "sparc/arch_sigreturn.c"
+#undef arch_sigreturn
+
+static void
+arch_sigreturn(struct tcb *tcp)
+{
+	if (current_personality == 1)
+		sparc32_arch_sigreturn(tcp);
+	else
+		sparc64_arch_sigreturn(tcp);
+}
diff --git a/linux/sparc64/get_scno.c b/linux/sparc64/get_scno.c
index 68d5917..4abe2a1 100644
--- a/linux/sparc64/get_scno.c
+++ b/linux/sparc64/get_scno.c
@@ -12,11 +12,11 @@
 	switch (trap) {
 	case 0x91d02010:
 		/* Linux/SPARC syscall trap. */
-		update_personality(tcp, 0);
+		update_personality(tcp, 1);
 		break;
 	case 0x91d0206d:
 		/* Linux/SPARC64 syscall trap. */
-		update_personality(tcp, 1);
+		update_personality(tcp, 0);
 		break;
 	}
 
diff --git a/linux/sparc64/get_syscall_args.c b/linux/sparc64/get_syscall_args.c
index 821c331..8d29785 100644
--- a/linux/sparc64/get_syscall_args.c
+++ b/linux/sparc64/get_syscall_args.c
@@ -1 +1,27 @@
-#include "sparc/get_syscall_args.c"
+/* Return -1 on error or 1 on success (never 0!). */
+static int
+get_syscall_args(struct tcb *tcp)
+{
+	if (tcp->currpers == 1) {
+		/*
+		 * Zero-extend from 32 bits.
+		 * Use widen_to_long(tcp->u_arg[N]) in syscall handlers
+		 * if you need to use *sign-extended* parameter.
+		 */
+		tcp->u_arg[0] = (long) (uint32_t) sparc_regs.u_regs[U_REG_O0 + 0];
+		tcp->u_arg[1] = (long) (uint32_t) sparc_regs.u_regs[U_REG_O0 + 1];
+		tcp->u_arg[2] = (long) (uint32_t) sparc_regs.u_regs[U_REG_O0 + 2];
+		tcp->u_arg[3] = (long) (uint32_t) sparc_regs.u_regs[U_REG_O0 + 3];
+		tcp->u_arg[4] = (long) (uint32_t) sparc_regs.u_regs[U_REG_O0 + 4];
+		tcp->u_arg[5] = (long) (uint32_t) sparc_regs.u_regs[U_REG_O0 + 5];
+	} else {
+		tcp->u_arg[0] = sparc_regs.u_regs[U_REG_O0 + 0];
+		tcp->u_arg[1] = sparc_regs.u_regs[U_REG_O0 + 1];
+		tcp->u_arg[2] = sparc_regs.u_regs[U_REG_O0 + 2];
+		tcp->u_arg[3] = sparc_regs.u_regs[U_REG_O0 + 3];
+		tcp->u_arg[4] = sparc_regs.u_regs[U_REG_O0 + 4];
+		tcp->u_arg[5] = sparc_regs.u_regs[U_REG_O0 + 5];
+	}
+
+	return 1;
+}
diff --git a/linux/sparc64/ioctls_arch0.h b/linux/sparc64/ioctls_arch0.h
index 96bd895..0e5f1a0 100644
--- a/linux/sparc64/ioctls_arch0.h
+++ b/linux/sparc64/ioctls_arch0.h
@@ -1 +1,129 @@
-#include "sparc/ioctls_arch0.h"
+/* Generated by ioctls_gen.sh from definitions found in $linux/arch/sparc/include/ tree. */
+{ "asm/apc.h", "APCIOCGBPORT", _IOC_READ, 0x4104, 0x04 },
+{ "asm/apc.h", "APCIOCGCPWR", _IOC_READ, 0x4102, 0x04 },
+{ "asm/apc.h", "APCIOCGFANCTL", _IOC_READ, 0x4100, 0x04 },
+{ "asm/apc.h", "APCIOCSBPORT", _IOC_WRITE, 0x4105, 0x04 },
+{ "asm/apc.h", "APCIOCSCPWR", _IOC_WRITE, 0x4103, 0x04 },
+{ "asm/apc.h", "APCIOCSFANCTL", _IOC_WRITE, 0x4101, 0x04 },
+{ "asm/display7seg.h", "D7SIOCRD", _IOC_READ, 0x7045, 0x04 },
+{ "asm/display7seg.h", "D7SIOCTM", _IOC_NONE, 0x7047, 0x00 },
+{ "asm/display7seg.h", "D7SIOCWR", _IOC_WRITE, 0x7046, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_CPU_TEMPERATURE", _IOC_READ, 0x7040, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_CPU_VOLTAGE", _IOC_READ, 0x7041, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_ETHERNET_TEMPERATURE", _IOC_READ, 0x7047, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_FAN_STATUS", _IOC_READ, 0x7042, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_GLOBALADDRESS", _IOC_READ, 0x7049, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_MTHRBD_TEMPERATURE", _IOC_READ, 0x7048, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_SCSI_TEMPERATURE", _IOC_READ, 0x7046, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_SHUTDOWN_TEMPERATURE", _IOC_READ, 0x7044, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_VOLTAGE_STATUS", _IOC_READ, 0x7045, 0x04 },
+{ "asm/envctrl.h", "ENVCTRL_RD_WARNING_TEMPERATURE", _IOC_READ, 0x7043, 0x04 },
+{ "asm/fbio.h", "FBIOGATTR", _IOC_READ, 0x4606, 0x58 },
+{ "asm/fbio.h", "FBIOGCURMAX", _IOC_READ, 0x461c, 0x04 },
+{ "asm/fbio.h", "FBIOGCURPOS", _IOC_WRITE, 0x461b, 0x04 },
+{ "asm/fbio.h", "FBIOGCURSOR", _IOC_READ|_IOC_WRITE, 0x4619, 0x48 },
+{ "asm/fbio.h", "FBIOGETCMAP", _IOC_WRITE, 0x4604, 0x20 },
+{ "asm/fbio.h", "FBIOGTYPE", _IOC_READ, 0x4600, 0x18 },
+{ "asm/fbio.h", "FBIOGVIDEO", _IOC_READ, 0x4608, 0x04 },
+{ "asm/fbio.h", "FBIOPUTCMAP", _IOC_WRITE, 0x4603, 0x20 },
+{ "asm/fbio.h", "FBIOSATTR", _IOC_WRITE, 0x4605, 0x58 },
+{ "asm/fbio.h", "FBIOSCURPOS", _IOC_WRITE, 0x461a, 0x04 },
+{ "asm/fbio.h", "FBIOSCURSOR", _IOC_WRITE, 0x4618, 0x48 },
+{ "asm/fbio.h", "FBIOSVIDEO", _IOC_WRITE, 0x4607, 0x04 },
+{ "asm/fbio.h", "FBIO_WID_ALLOC", _IOC_READ|_IOC_WRITE, 0x461e, 0x0c },
+{ "asm/fbio.h", "FBIO_WID_FREE", _IOC_WRITE, 0x461f, 0x0c },
+{ "asm/fbio.h", "FBIO_WID_GET", _IOC_READ|_IOC_WRITE, 0x4621, 0x10 },
+{ "asm/fbio.h", "FBIO_WID_PUT", _IOC_WRITE, 0x4620, 0x10 },
+{ "asm/fbio.h", "LEO_CLUTALLOC", _IOC_READ|_IOC_WRITE, 0x4c35, 0x0c },
+{ "asm/fbio.h", "LEO_CLUTFREE", _IOC_WRITE, 0x4c36, 0x0c },
+{ "asm/fbio.h", "LEO_CLUTPOST", _IOC_WRITE, 0x4c38, 0x28 },
+{ "asm/fbio.h", "LEO_CLUTREAD", _IOC_WRITE, 0x4c37, 0x28 },
+{ "asm/fbio.h", "LEO_GETGAMMA", _IOC_READ, 0x4c45, 0x04 },
+{ "asm/fbio.h", "LEO_SETGAMMA", _IOC_WRITE, 0x4c44, 0x04 },
+{ "asm/ioctls.h", "FIOASYNC", _IOC_WRITE, 0x667d, 0x04 },
+{ "asm/ioctls.h", "FIOCLEX", _IOC_NONE, 0x6601, 0x00 },
+{ "asm/ioctls.h", "FIONBIO", _IOC_WRITE, 0x667e, 0x04 },
+{ "asm/ioctls.h", "FIONCLEX", _IOC_NONE, 0x6602, 0x00 },
+{ "asm/ioctls.h", "FIONREAD", _IOC_READ, 0x667f, 0x04 },
+{ "asm/ioctls.h", "FIOQSIZE", _IOC_READ, 0x6680, 0x08 },
+{ "asm/ioctls.h", "TCFLSH", _IOC_NONE, 0x5407, 0x00 },
+{ "asm/ioctls.h", "TCGETA", _IOC_READ, 0x5401, 0x12 },
+{ "asm/ioctls.h", "TCGETS", _IOC_READ, 0x5408, 0x24 },
+{ "asm/ioctls.h", "TCGETS2", _IOC_READ, 0x540c, 0x2c },
+{ "asm/ioctls.h", "TCSBRK", _IOC_NONE, 0x5405, 0x00 },
+{ "asm/ioctls.h", "TCSBRKP", 0, 0x5425, 0 },
+{ "asm/ioctls.h", "TCSETA", _IOC_WRITE, 0x5402, 0x12 },
+{ "asm/ioctls.h", "TCSETAF", _IOC_WRITE, 0x5404, 0x12 },
+{ "asm/ioctls.h", "TCSETAW", _IOC_WRITE, 0x5403, 0x12 },
+{ "asm/ioctls.h", "TCSETS", _IOC_WRITE, 0x5409, 0x24 },
+{ "asm/ioctls.h", "TCSETS2", _IOC_WRITE, 0x540d, 0x2c },
+{ "asm/ioctls.h", "TCSETSF", _IOC_WRITE, 0x540b, 0x24 },
+{ "asm/ioctls.h", "TCSETSF2", _IOC_WRITE, 0x540f, 0x2c },
+{ "asm/ioctls.h", "TCSETSW", _IOC_WRITE, 0x540a, 0x24 },
+{ "asm/ioctls.h", "TCSETSW2", _IOC_WRITE, 0x540e, 0x2c },
+{ "asm/ioctls.h", "TCXONC", _IOC_NONE, 0x5406, 0x00 },
+{ "asm/ioctls.h", "TIOCCBRK", _IOC_NONE, 0x747a, 0x00 },
+{ "asm/ioctls.h", "TIOCCONS", _IOC_NONE, 0x7424, 0x00 },
+{ "asm/ioctls.h", "TIOCEXCL", _IOC_NONE, 0x740d, 0x00 },
+{ "asm/ioctls.h", "TIOCGDEV", _IOC_READ, 0x5432, 0x04 },
+{ "asm/ioctls.h", "TIOCGETD", _IOC_READ, 0x7400, 0x04 },
+{ "asm/ioctls.h", "TIOCGEXCL", _IOC_READ, 0x5440, 0x04 },
+{ "asm/ioctls.h", "TIOCGICOUNT", 0, 0x545D, 0 },
+{ "asm/ioctls.h", "TIOCGLCKTRMIOS", 0, 0x5456, 0 },
+{ "asm/ioctls.h", "TIOCGPGRP", _IOC_READ, 0x7483, 0x04 },
+{ "asm/ioctls.h", "TIOCGPKT", _IOC_READ, 0x5438, 0x04 },
+{ "asm/ioctls.h", "TIOCGPTLCK", _IOC_READ, 0x5439, 0x04 },
+{ "asm/ioctls.h", "TIOCGPTN", _IOC_READ, 0x7486, 0x04 },
+{ "asm/ioctls.h", "TIOCGRS485", _IOC_READ, 0x5441, 0x20 },
+{ "asm/ioctls.h", "TIOCGSERIAL", 0, 0x541E, 0 },
+{ "asm/ioctls.h", "TIOCGSID", _IOC_READ, 0x7485, 0x04 },
+{ "asm/ioctls.h", "TIOCGSOFTCAR", _IOC_READ, 0x7464, 0x04 },
+{ "asm/ioctls.h", "TIOCGWINSZ", _IOC_READ, 0x7468, 0x08 },
+{ "asm/ioctls.h", "TIOCLINUX", 0, 0x541C, 0 },
+{ "asm/ioctls.h", "TIOCMBIC", _IOC_WRITE, 0x746b, 0x04 },
+{ "asm/ioctls.h", "TIOCMBIS", _IOC_WRITE, 0x746c, 0x04 },
+{ "asm/ioctls.h", "TIOCMGET", _IOC_READ, 0x746a, 0x04 },
+{ "asm/ioctls.h", "TIOCMIWAIT", 0, 0x545C, 0 },
+{ "asm/ioctls.h", "TIOCMSET", _IOC_WRITE, 0x746d, 0x04 },
+{ "asm/ioctls.h", "TIOCNOTTY", _IOC_NONE, 0x7471, 0x00 },
+{ "asm/ioctls.h", "TIOCNXCL", _IOC_NONE, 0x740e, 0x00 },
+{ "asm/ioctls.h", "TIOCOUTQ", _IOC_READ, 0x7473, 0x04 },
+{ "asm/ioctls.h", "TIOCPKT", _IOC_WRITE, 0x7470, 0x04 },
+{ "asm/ioctls.h", "TIOCSBRK", _IOC_NONE, 0x747b, 0x00 },
+{ "asm/ioctls.h", "TIOCSCTTY", _IOC_NONE, 0x7484, 0x00 },
+{ "asm/ioctls.h", "TIOCSERCONFIG", 0, 0x5453, 0 },
+{ "asm/ioctls.h", "TIOCSERGETLSR", 0, 0x5459, 0 },
+{ "asm/ioctls.h", "TIOCSERGETMULTI", 0, 0x545A, 0 },
+{ "asm/ioctls.h", "TIOCSERGSTRUCT", 0, 0x5458, 0 },
+{ "asm/ioctls.h", "TIOCSERGWILD", 0, 0x5454, 0 },
+{ "asm/ioctls.h", "TIOCSERSETMULTI", 0, 0x545B, 0 },
+{ "asm/ioctls.h", "TIOCSERSWILD", 0, 0x5455, 0 },
+{ "asm/ioctls.h", "TIOCSETD", _IOC_WRITE, 0x7401, 0x04 },
+{ "asm/ioctls.h", "TIOCSIG", _IOC_WRITE, 0x7488, 0x04 },
+{ "asm/ioctls.h", "TIOCSLCKTRMIOS", 0, 0x5457, 0 },
+{ "asm/ioctls.h", "TIOCSPGRP", _IOC_WRITE, 0x7482, 0x04 },
+{ "asm/ioctls.h", "TIOCSPTLCK", _IOC_WRITE, 0x7487, 0x04 },
+{ "asm/ioctls.h", "TIOCSRS485", _IOC_READ|_IOC_WRITE, 0x5442, 0x20 },
+{ "asm/ioctls.h", "TIOCSSERIAL", 0, 0x541F, 0 },
+{ "asm/ioctls.h", "TIOCSSOFTCAR", _IOC_WRITE, 0x7465, 0x04 },
+{ "asm/ioctls.h", "TIOCSTART", _IOC_NONE, 0x746e, 0x00 },
+{ "asm/ioctls.h", "TIOCSTI", _IOC_WRITE, 0x7472, 0x01 },
+{ "asm/ioctls.h", "TIOCSTOP", _IOC_NONE, 0x746f, 0x00 },
+{ "asm/ioctls.h", "TIOCSWINSZ", _IOC_WRITE, 0x7467, 0x08 },
+{ "asm/ioctls.h", "TIOCVHANGUP", _IOC_NONE, 0x5437, 0x00 },
+{ "asm/openpromio.h", "OPIOCGET", _IOC_READ|_IOC_WRITE, 0x4f01, 0x20 },
+{ "asm/openpromio.h", "OPIOCGETCHILD", _IOC_READ|_IOC_WRITE, 0x4f06, 0x04 },
+{ "asm/openpromio.h", "OPIOCGETNEXT", _IOC_READ|_IOC_WRITE, 0x4f05, 0x04 },
+{ "asm/openpromio.h", "OPIOCGETOPTNODE", _IOC_READ, 0x4f04, 0x04 },
+{ "asm/openpromio.h", "OPIOCNEXTPROP", _IOC_READ|_IOC_WRITE, 0x4f03, 0x20 },
+{ "asm/openpromio.h", "OPIOCSET", _IOC_WRITE, 0x4f02, 0x20 },
+{ "asm/sockios.h", "FIOGETOWN", 0, 0x8903, 0 },
+{ "asm/sockios.h", "FIOSETOWN", 0, 0x8901, 0 },
+{ "asm/sockios.h", "SIOCATMARK", 0, 0x8905, 0 },
+{ "asm/sockios.h", "SIOCGPGRP", 0, 0x8904, 0 },
+{ "asm/sockios.h", "SIOCGSTAMP", 0, 0x8906, 0 },
+{ "asm/sockios.h", "SIOCGSTAMPNS", 0, 0x8907, 0 },
+{ "asm/sockios.h", "SIOCSPGRP", 0, 0x8902, 0 },
+{ "asm/watchdog.h", "WIOCGSTAT", _IOC_READ, 0x570c, 0x04 },
+{ "asm/watchdog.h", "WIOCSTART", _IOC_NONE, 0x570a, 0x00 },
+{ "asm/watchdog.h", "WIOCSTOP", _IOC_NONE, 0x570b, 0x00 },
diff --git a/linux/sparc64/ioctls_arch1.h b/linux/sparc64/ioctls_arch1.h
index 6128dc9..96bd895 100644
--- a/linux/sparc64/ioctls_arch1.h
+++ b/linux/sparc64/ioctls_arch1.h
@@ -1,129 +1 @@
-/* Generated by ioctls_gen.sh from definitions found in $linux/arch/sparc/include/ tree. */
-{ "asm/apc.h", "APCIOCGBPORT", _IOC_READ, 0x4104, 0x04 },
-{ "asm/apc.h", "APCIOCGCPWR", _IOC_READ, 0x4102, 0x04 },
-{ "asm/apc.h", "APCIOCGFANCTL", _IOC_READ, 0x4100, 0x04 },
-{ "asm/apc.h", "APCIOCSBPORT", _IOC_WRITE, 0x4105, 0x04 },
-{ "asm/apc.h", "APCIOCSCPWR", _IOC_WRITE, 0x4103, 0x04 },
-{ "asm/apc.h", "APCIOCSFANCTL", _IOC_WRITE, 0x4101, 0x04 },
-{ "asm/display7seg.h", "D7SIOCRD", _IOC_READ, 0x7045, 0x04 },
-{ "asm/display7seg.h", "D7SIOCTM", _IOC_NONE, 0x7047, 0x00 },
-{ "asm/display7seg.h", "D7SIOCWR", _IOC_WRITE, 0x7046, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_CPU_TEMPERATURE", _IOC_READ, 0x7040, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_CPU_VOLTAGE", _IOC_READ, 0x7041, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_ETHERNET_TEMPERATURE", _IOC_READ, 0x7047, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_FAN_STATUS", _IOC_READ, 0x7042, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_GLOBALADDRESS", _IOC_READ, 0x7049, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_MTHRBD_TEMPERATURE", _IOC_READ, 0x7048, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_SCSI_TEMPERATURE", _IOC_READ, 0x7046, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_SHUTDOWN_TEMPERATURE", _IOC_READ, 0x7044, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_VOLTAGE_STATUS", _IOC_READ, 0x7045, 0x04 },
-{ "asm/envctrl.h", "ENVCTRL_RD_WARNING_TEMPERATURE", _IOC_READ, 0x7043, 0x04 },
-{ "asm/fbio.h", "FBIOGATTR", _IOC_READ, 0x4606, 0x58 },
-{ "asm/fbio.h", "FBIOGCURMAX", _IOC_READ, 0x461c, 0x04 },
-{ "asm/fbio.h", "FBIOGCURPOS", _IOC_WRITE, 0x461b, 0x04 },
-{ "asm/fbio.h", "FBIOGCURSOR", _IOC_READ|_IOC_WRITE, 0x4619, 0x48 },
-{ "asm/fbio.h", "FBIOGETCMAP", _IOC_WRITE, 0x4604, 0x20 },
-{ "asm/fbio.h", "FBIOGTYPE", _IOC_READ, 0x4600, 0x18 },
-{ "asm/fbio.h", "FBIOGVIDEO", _IOC_READ, 0x4608, 0x04 },
-{ "asm/fbio.h", "FBIOPUTCMAP", _IOC_WRITE, 0x4603, 0x20 },
-{ "asm/fbio.h", "FBIOSATTR", _IOC_WRITE, 0x4605, 0x58 },
-{ "asm/fbio.h", "FBIOSCURPOS", _IOC_WRITE, 0x461a, 0x04 },
-{ "asm/fbio.h", "FBIOSCURSOR", _IOC_WRITE, 0x4618, 0x48 },
-{ "asm/fbio.h", "FBIOSVIDEO", _IOC_WRITE, 0x4607, 0x04 },
-{ "asm/fbio.h", "FBIO_WID_ALLOC", _IOC_READ|_IOC_WRITE, 0x461e, 0x0c },
-{ "asm/fbio.h", "FBIO_WID_FREE", _IOC_WRITE, 0x461f, 0x0c },
-{ "asm/fbio.h", "FBIO_WID_GET", _IOC_READ|_IOC_WRITE, 0x4621, 0x10 },
-{ "asm/fbio.h", "FBIO_WID_PUT", _IOC_WRITE, 0x4620, 0x10 },
-{ "asm/fbio.h", "LEO_CLUTALLOC", _IOC_READ|_IOC_WRITE, 0x4c35, 0x0c },
-{ "asm/fbio.h", "LEO_CLUTFREE", _IOC_WRITE, 0x4c36, 0x0c },
-{ "asm/fbio.h", "LEO_CLUTPOST", _IOC_WRITE, 0x4c38, 0x28 },
-{ "asm/fbio.h", "LEO_CLUTREAD", _IOC_WRITE, 0x4c37, 0x28 },
-{ "asm/fbio.h", "LEO_GETGAMMA", _IOC_READ, 0x4c45, 0x04 },
-{ "asm/fbio.h", "LEO_SETGAMMA", _IOC_WRITE, 0x4c44, 0x04 },
-{ "asm/ioctls.h", "FIOASYNC", _IOC_WRITE, 0x667d, 0x04 },
-{ "asm/ioctls.h", "FIOCLEX", _IOC_NONE, 0x6601, 0x00 },
-{ "asm/ioctls.h", "FIONBIO", _IOC_WRITE, 0x667e, 0x04 },
-{ "asm/ioctls.h", "FIONCLEX", _IOC_NONE, 0x6602, 0x00 },
-{ "asm/ioctls.h", "FIONREAD", _IOC_READ, 0x667f, 0x04 },
-{ "asm/ioctls.h", "FIOQSIZE", _IOC_READ, 0x6680, 0x08 },
-{ "asm/ioctls.h", "TCFLSH", _IOC_NONE, 0x5407, 0x00 },
-{ "asm/ioctls.h", "TCGETA", _IOC_READ, 0x5401, 0x12 },
-{ "asm/ioctls.h", "TCGETS", _IOC_READ, 0x5408, 0x38 },
-{ "asm/ioctls.h", "TCGETS2", _IOC_READ, 0x540c, 0x40 },
-{ "asm/ioctls.h", "TCSBRK", _IOC_NONE, 0x5405, 0x00 },
-{ "asm/ioctls.h", "TCSBRKP", 0, 0x5425, 0 },
-{ "asm/ioctls.h", "TCSETA", _IOC_WRITE, 0x5402, 0x12 },
-{ "asm/ioctls.h", "TCSETAF", _IOC_WRITE, 0x5404, 0x12 },
-{ "asm/ioctls.h", "TCSETAW", _IOC_WRITE, 0x5403, 0x12 },
-{ "asm/ioctls.h", "TCSETS", _IOC_WRITE, 0x5409, 0x38 },
-{ "asm/ioctls.h", "TCSETS2", _IOC_WRITE, 0x540d, 0x40 },
-{ "asm/ioctls.h", "TCSETSF", _IOC_WRITE, 0x540b, 0x38 },
-{ "asm/ioctls.h", "TCSETSF2", _IOC_WRITE, 0x540f, 0x40 },
-{ "asm/ioctls.h", "TCSETSW", _IOC_WRITE, 0x540a, 0x38 },
-{ "asm/ioctls.h", "TCSETSW2", _IOC_WRITE, 0x540e, 0x40 },
-{ "asm/ioctls.h", "TCXONC", _IOC_NONE, 0x5406, 0x00 },
-{ "asm/ioctls.h", "TIOCCBRK", _IOC_NONE, 0x747a, 0x00 },
-{ "asm/ioctls.h", "TIOCCONS", _IOC_NONE, 0x7424, 0x00 },
-{ "asm/ioctls.h", "TIOCEXCL", _IOC_NONE, 0x740d, 0x00 },
-{ "asm/ioctls.h", "TIOCGDEV", _IOC_READ, 0x5432, 0x04 },
-{ "asm/ioctls.h", "TIOCGETD", _IOC_READ, 0x7400, 0x04 },
-{ "asm/ioctls.h", "TIOCGEXCL", _IOC_READ, 0x5440, 0x04 },
-{ "asm/ioctls.h", "TIOCGICOUNT", 0, 0x545D, 0 },
-{ "asm/ioctls.h", "TIOCGLCKTRMIOS", 0, 0x5456, 0 },
-{ "asm/ioctls.h", "TIOCGPGRP", _IOC_READ, 0x7483, 0x04 },
-{ "asm/ioctls.h", "TIOCGPKT", _IOC_READ, 0x5438, 0x04 },
-{ "asm/ioctls.h", "TIOCGPTLCK", _IOC_READ, 0x5439, 0x04 },
-{ "asm/ioctls.h", "TIOCGPTN", _IOC_READ, 0x7486, 0x04 },
-{ "asm/ioctls.h", "TIOCGRS485", _IOC_READ, 0x5441, 0x20 },
-{ "asm/ioctls.h", "TIOCGSERIAL", 0, 0x541E, 0 },
-{ "asm/ioctls.h", "TIOCGSID", _IOC_READ, 0x7485, 0x04 },
-{ "asm/ioctls.h", "TIOCGSOFTCAR", _IOC_READ, 0x7464, 0x04 },
-{ "asm/ioctls.h", "TIOCGWINSZ", _IOC_READ, 0x7468, 0x08 },
-{ "asm/ioctls.h", "TIOCLINUX", 0, 0x541C, 0 },
-{ "asm/ioctls.h", "TIOCMBIC", _IOC_WRITE, 0x746b, 0x04 },
-{ "asm/ioctls.h", "TIOCMBIS", _IOC_WRITE, 0x746c, 0x04 },
-{ "asm/ioctls.h", "TIOCMGET", _IOC_READ, 0x746a, 0x04 },
-{ "asm/ioctls.h", "TIOCMIWAIT", 0, 0x545C, 0 },
-{ "asm/ioctls.h", "TIOCMSET", _IOC_WRITE, 0x746d, 0x04 },
-{ "asm/ioctls.h", "TIOCNOTTY", _IOC_NONE, 0x7471, 0x00 },
-{ "asm/ioctls.h", "TIOCNXCL", _IOC_NONE, 0x740e, 0x00 },
-{ "asm/ioctls.h", "TIOCOUTQ", _IOC_READ, 0x7473, 0x04 },
-{ "asm/ioctls.h", "TIOCPKT", _IOC_WRITE, 0x7470, 0x04 },
-{ "asm/ioctls.h", "TIOCSBRK", _IOC_NONE, 0x747b, 0x00 },
-{ "asm/ioctls.h", "TIOCSCTTY", _IOC_NONE, 0x7484, 0x00 },
-{ "asm/ioctls.h", "TIOCSERCONFIG", 0, 0x5453, 0 },
-{ "asm/ioctls.h", "TIOCSERGETLSR", 0, 0x5459, 0 },
-{ "asm/ioctls.h", "TIOCSERGETMULTI", 0, 0x545A, 0 },
-{ "asm/ioctls.h", "TIOCSERGSTRUCT", 0, 0x5458, 0 },
-{ "asm/ioctls.h", "TIOCSERGWILD", 0, 0x5454, 0 },
-{ "asm/ioctls.h", "TIOCSERSETMULTI", 0, 0x545B, 0 },
-{ "asm/ioctls.h", "TIOCSERSWILD", 0, 0x5455, 0 },
-{ "asm/ioctls.h", "TIOCSETD", _IOC_WRITE, 0x7401, 0x04 },
-{ "asm/ioctls.h", "TIOCSIG", _IOC_WRITE, 0x7488, 0x04 },
-{ "asm/ioctls.h", "TIOCSLCKTRMIOS", 0, 0x5457, 0 },
-{ "asm/ioctls.h", "TIOCSPGRP", _IOC_WRITE, 0x7482, 0x04 },
-{ "asm/ioctls.h", "TIOCSPTLCK", _IOC_WRITE, 0x7487, 0x04 },
-{ "asm/ioctls.h", "TIOCSRS485", _IOC_READ|_IOC_WRITE, 0x5442, 0x20 },
-{ "asm/ioctls.h", "TIOCSSERIAL", 0, 0x541F, 0 },
-{ "asm/ioctls.h", "TIOCSSOFTCAR", _IOC_WRITE, 0x7465, 0x04 },
-{ "asm/ioctls.h", "TIOCSTART", _IOC_NONE, 0x746e, 0x00 },
-{ "asm/ioctls.h", "TIOCSTI", _IOC_WRITE, 0x7472, 0x01 },
-{ "asm/ioctls.h", "TIOCSTOP", _IOC_NONE, 0x746f, 0x00 },
-{ "asm/ioctls.h", "TIOCSWINSZ", _IOC_WRITE, 0x7467, 0x08 },
-{ "asm/ioctls.h", "TIOCVHANGUP", _IOC_NONE, 0x5437, 0x00 },
-{ "asm/openpromio.h", "OPIOCGET", _IOC_READ|_IOC_WRITE, 0x4f01, 0x20 },
-{ "asm/openpromio.h", "OPIOCGETCHILD", _IOC_READ|_IOC_WRITE, 0x4f06, 0x04 },
-{ "asm/openpromio.h", "OPIOCGETNEXT", _IOC_READ|_IOC_WRITE, 0x4f05, 0x04 },
-{ "asm/openpromio.h", "OPIOCGETOPTNODE", _IOC_READ, 0x4f04, 0x04 },
-{ "asm/openpromio.h", "OPIOCNEXTPROP", _IOC_READ|_IOC_WRITE, 0x4f03, 0x20 },
-{ "asm/openpromio.h", "OPIOCSET", _IOC_WRITE, 0x4f02, 0x20 },
-{ "asm/sockios.h", "FIOGETOWN", 0, 0x8903, 0 },
-{ "asm/sockios.h", "FIOSETOWN", 0, 0x8901, 0 },
-{ "asm/sockios.h", "SIOCATMARK", 0, 0x8905, 0 },
-{ "asm/sockios.h", "SIOCGPGRP", 0, 0x8904, 0 },
-{ "asm/sockios.h", "SIOCGSTAMP", 0, 0x8906, 0 },
-{ "asm/sockios.h", "SIOCGSTAMPNS", 0, 0x8907, 0 },
-{ "asm/sockios.h", "SIOCSPGRP", 0, 0x8902, 0 },
-{ "asm/watchdog.h", "WIOCGSTAT", _IOC_READ, 0x570c, 0x04 },
-{ "asm/watchdog.h", "WIOCSTART", _IOC_NONE, 0x570a, 0x00 },
-{ "asm/watchdog.h", "WIOCSTOP", _IOC_NONE, 0x570b, 0x00 },
+#include "sparc/ioctls_arch0.h"
diff --git a/linux/sparc64/ioctls_inc0.h b/linux/sparc64/ioctls_inc0.h
index 63b70e4..f9939fa 100644
--- a/linux/sparc64/ioctls_inc0.h
+++ b/linux/sparc64/ioctls_inc0.h
@@ -1 +1 @@
-#include "sparc/ioctls_inc0.h"
+#include "64/ioctls_inc.h"
diff --git a/linux/sparc64/ioctls_inc1.h b/linux/sparc64/ioctls_inc1.h
index f9939fa..63b70e4 100644
--- a/linux/sparc64/ioctls_inc1.h
+++ b/linux/sparc64/ioctls_inc1.h
@@ -1 +1 @@
-#include "64/ioctls_inc.h"
+#include "sparc/ioctls_inc0.h"
diff --git a/linux/sparc64/syscallent.h b/linux/sparc64/syscallent.h
index 8bf5c3a..0f24596 100644
--- a/linux/sparc64/syscallent.h
+++ b/linux/sparc64/syscallent.h
@@ -11,18 +11,18 @@
 [ 10] = { 1,	TF,		SEN(unlink),			"unlink"		},
 [ 11] = { 2,	TF|TP|SE|SI,	SEN(execv),			"execv"			},
 [ 12] = { 1,	TF,		SEN(chdir),			"chdir"			},
-[ 13] = { 3,	TF,		SEN(chown16),			"chown"			},
+[ 13] = { 3,	TF,		SEN(chown),			"chown"			},
 [ 14] = { 3,	TF,		SEN(mknod),			"mknod"			},
 [ 15] = { 2,	TF,		SEN(chmod),			"chmod"			},
-[ 16] = { 3,	TF,		SEN(chown16),			"lchown"		},
+[ 16] = { 3,	TF,		SEN(chown),			"lchown"		},
 [ 17] = { 1,	TM|SI,		SEN(brk),			"brk"			},
 [ 18] = { 4,	0,		SEN(printargs),			"perfctr"		},
 [ 19] = { 3,	TD,		SEN(lseek),			"lseek"			},
 [ 20] = { 0,	NF,		SEN(getpid),			"getpid"		},
 [ 21] = { 2,	0,		SEN(capget),			"capget"		},
 [ 22] = { 2,	0,		SEN(capset),			"capset"		},
-[ 23] = { 1,	0,		SEN(setuid16),			"setuid"		},
-[ 24] = { 0,	NF,		SEN(getuid16),			"getuid"		},
+[ 23] = { 1,	0,		SEN(setuid),			"setuid"		},
+[ 24] = { 0,	NF,		SEN(getuid),			"getuid"		},
 [ 25] = { 4,	TD,		SEN(vmsplice),			"vmsplice"		},
 [ 26] = { 4,	0,		SEN(ptrace),			"ptrace"		},
 [ 27] = { 1,	0,		SEN(alarm),			"alarm"			},
@@ -43,11 +43,11 @@
 [ 43] = { 1,	0,		SEN(times),			"times"			},
 [ 44] = { },
 [ 45] = { 2,	TF,		SEN(umount2),			"umount2"		},
-[ 46] = { 1,	0,		SEN(setgid16),			"setgid"		},
-[ 47] = { 0,	NF,		SEN(getgid16),			"getgid"		},
+[ 46] = { 1,	0,		SEN(setgid),			"setgid"		},
+[ 47] = { 0,	NF,		SEN(getgid),			"getgid"		},
 [ 48] = { 2,	TS,		SEN(signal),			"signal"		},
-[ 49] = { 0,	NF,		SEN(geteuid16),			"geteuid"		},
-[ 50] = { 0,	NF,		SEN(getegid16),			"getegid"		},
+[ 49] = { 0,	NF,		SEN(geteuid),			"geteuid"		},
+[ 50] = { 0,	NF,		SEN(getegid),			"getegid"		},
 [ 51] = { 1,	TF,		SEN(acct),			"acct"			},
 [ 52] = { 2,	0,		SEN(printargs),			"memory_ordering"	},
 [ 53] = { },
@@ -75,8 +75,8 @@
 [ 76] = { 0,	0,		SEN(vhangup),			"vhangup"		},
 [ 77] = { },
 [ 78] = { 3,	TM,		SEN(mincore),			"mincore"		},
-[ 79] = { 2,	0,		SEN(getgroups16),		"getgroups"		},
-[ 80] = { 2,	0,		SEN(setgroups16),		"setgroups"		},
+[ 79] = { 2,	0,		SEN(getgroups),			"getgroups"		},
+[ 80] = { 2,	0,		SEN(setgroups),			"setgroups"		},
 [ 81] = { 0,	0,		SEN(getpgrp),			"getpgrp"		},
 [ 82] = { },
 [ 83] = { 3,	0,		SEN(setitimer),			"setitimer"		},
@@ -119,11 +119,11 @@
 [120] = { 3,	TD,		SEN(readv),			"readv"			},
 [121] = { 3,	TD,		SEN(writev),			"writev"		},
 [122] = { 2,	0,		SEN(settimeofday),		"settimeofday"		},
-[123] = { 3,	TD,		SEN(fchown16),			"fchown"		},
+[123] = { 3,	TD,		SEN(fchown),			"fchown"		},
 [124] = { 2,	TD,		SEN(fchmod),			"fchmod"		},
 [125] = { 6,	TN,		SEN(recvfrom),			"recvfrom"		},
-[126] = { 2,	0,		SEN(setreuid16),		"setreuid"		},
-[127] = { 2,	0,		SEN(setregid16),		"setregid"		},
+[126] = { 2,	0,		SEN(setreuid),			"setreuid"		},
+[127] = { 2,	0,		SEN(setregid),			"setregid"		},
 [128] = { 2,	TF,		SEN(rename),			"rename"		},
 [129] = { 2,	TF,		SEN(truncate),			"truncate"		},
 [130] = { 2,	TD,		SEN(ftruncate),			"ftruncate"		},
@@ -206,7 +206,7 @@
 [207] = { 3,	0,		SEN(syslog),			"syslog"		},
 [208] = { 3,	0,		SEN(lookup_dcookie),		"lookup_dcookie"	},
 [209] = { 4,	TD,		SEN(fadvise64),			"fadvise64"		},
-[210] = { 4,	TD,		SEN(fadvise64),			"fadvise64_64"		},
+[210] = { 4,	TD,		SEN(fadvise64_64),		"fadvise64_64"		},
 [211] = { 3,	TS,		SEN(tgkill),			"tgkill"		},
 [212] = { 3,	TP,		SEN(waitpid),			"waitpid"		},
 [213] = { 1,	TF,		SEN(swapoff),			"swapoff"		},
@@ -224,8 +224,8 @@
 [225] = { 2,	0,		SEN(bdflush),			"bdflush"		},
 [226] = { 3,	0,		SEN(sysfs),			"sysfs"			},
 [227] = { 5,	0,		SEN(afs_syscall),		"afs_syscall"		},
-[228] = { 1,	NF,		SEN(setfsuid16),		"setfsuid"		},
-[229] = { 1,	NF,		SEN(setfsgid16),		"setfsgid"		},
+[228] = { 1,	NF,		SEN(setfsuid),			"setfsuid"		},
+[229] = { 1,	NF,		SEN(setfsgid),			"setfsgid"		},
 [230] = { 5,	TD,		SEN(select),			"_newselect"		},
 [231] = { },
 [232] = { 6,	TD,		SEN(splice),			"splice"		},
@@ -264,8 +264,8 @@
 [265] = { 1,	0,		SEN(timer_delete),		"timer_delete"		},
 [266] = { 3,	0,		SEN(timer_create),		"timer_create"		},
 [267] = { },
-[268] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[269] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[268] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[269] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [270] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [271] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
 [272] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
@@ -285,7 +285,7 @@
 [286] = { 4,	TD|TF,		SEN(mknodat),			"mknodat"		},
 [287] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [288] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[289] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[289] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [290] = { 3,	TD|TF,		SEN(unlinkat),			"unlinkat"		},
 [291] = { 4,	TD|TF,		SEN(renameat),			"renameat"		},
 [292] = { 5,	TD|TF,		SEN(linkat),			"linkat"		},
diff --git a/linux/sparc64/syscallent1.h b/linux/sparc64/syscallent1.h
index 5f73f3c..776b5f1 100644
--- a/linux/sparc64/syscallent1.h
+++ b/linux/sparc64/syscallent1.h
@@ -1,3 +1 @@
-#define sys_mmap_4koff sys_mmap_pgoff
 #include "../sparc/syscallent.h"
-#undef sys_mmap_4koff
diff --git a/linux/subcall.h b/linux/subcall.h
index 6d86751..169e5ea 100644
--- a/linux/subcall.h
+++ b/linux/subcall.h
@@ -31,7 +31,6 @@
 
 #define IS	TRACE_INDIRECT_SUBCALL
 
-[SYS_socket_subcall +  0] = { 6,	0,	SEN(printargs),		"socket_subcall"	},
 [SYS_socket_subcall +  1] = { 3,	IS|TN,	SEN(socket),		"socket"		},
 [SYS_socket_subcall +  2] = { 3,	IS|TN,	SEN(bind),		"bind"			},
 [SYS_socket_subcall +  3] = { 3,	IS|TN,	SEN(connect),		"connect"		},
@@ -56,27 +55,14 @@
 #define SYS_socket_nsubcalls	21
 #define SYS_ipc_subcall	((SYS_socket_subcall) + (SYS_socket_nsubcalls))
 
-[SYS_ipc_subcall +  0] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
 [SYS_ipc_subcall +  1] = { 4,	IS|TI,		SEN(semop),		"semop"			},
 [SYS_ipc_subcall +  2] = { 3,	IS|TI,		SEN(semget),		"semget"		},
 [SYS_ipc_subcall +  3] = { 4,	IS|TI,		SEN(semctl),		"semctl"		},
 [SYS_ipc_subcall +  4] = { 5,	IS|TI,		SEN(semtimedop),	"semtimedop"		},
-[SYS_ipc_subcall +  5] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall +  6] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall +  7] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall +  8] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall +  9] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall + 10] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
 [SYS_ipc_subcall + 11] = { 4,	IS|TI,		SEN(msgsnd),		"msgsnd"		},
 [SYS_ipc_subcall + 12] = { 5,	IS|TI,		SEN(msgrcv),		"msgrcv"		},
 [SYS_ipc_subcall + 13] = { 2,	IS|TI,		SEN(msgget),		"msgget"		},
 [SYS_ipc_subcall + 14] = { 4,	IS|TI,		SEN(msgctl),		"msgctl"		},
-[SYS_ipc_subcall + 15] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall + 16] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall + 17] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall + 18] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall + 19] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
-[SYS_ipc_subcall + 20] = { 6,	0,		SEN(printargs),		"ipc_subcall"		},
 [SYS_ipc_subcall + 21] = { 4,	IS|TI|TM|SI,	SEN(shmat),		"shmat"			},
 [SYS_ipc_subcall + 22] = { 4,	IS|TI|TM|SI,	SEN(shmdt),		"shmdt"			},
 [SYS_ipc_subcall + 23] = { 3,	IS|TI,		SEN(shmget),		"shmget"		},
diff --git a/linux/syscall.h b/linux/syscall.h
index 1b7cbc5..6bf8b42 100644
--- a/linux/syscall.h
+++ b/linux/syscall.h
@@ -26,6 +26,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_LINUX_SYSCALL_H
+#define STRACE_LINUX_SYSCALL_H
+
 #include "dummy.h"
 #include "sys_func.h"
 #include "sen.h"
@@ -42,3 +45,5 @@
 extern SYS_FUNC(setreuid16);
 extern SYS_FUNC(setuid16);
 #endif
+
+#endif /* !STRACE_LINUX_SYSCALL_H */
diff --git a/linux/unix_diag.h b/linux/unix_diag.h
index b37d465..0c3da5b 100644
--- a/linux/unix_diag.h
+++ b/linux/unix_diag.h
@@ -1,3 +1,6 @@
+#ifndef STRACE_LINUX_UNIX_DIAG_H
+#define STRACE_LINUX_UNIX_DIAG_H
+
 struct unix_diag_req {
 	uint8_t	 sdiag_family;
 	uint8_t	 sdiag_protocol;
@@ -22,3 +25,5 @@
 
 #define UNIX_DIAG_NAME 0
 #define UNIX_DIAG_PEER 2
+
+#endif /* !STRACE_LINUX_UNIX_DIAG_H */
diff --git a/linux/x32/arch_regs.c b/linux/x32/arch_regs.c
index 8140bc0..62c70be 100644
--- a/linux/x32/arch_regs.c
+++ b/linux/x32/arch_regs.c
@@ -1,2 +1 @@
 #include "x86_64/arch_regs.c"
-#define ARCH_PC_REG (x86_io.iov_len == sizeof(i386_regs) ? i386_regs.eip : x86_64_regs.rip)
diff --git a/linux/x32/asm_stat.h b/linux/x32/asm_stat.h
index 6713ac4..865aa4a 100644
--- a/linux/x32/asm_stat.h
+++ b/linux/x32/asm_stat.h
@@ -1,47 +1 @@
-/*
- * This is a replacement for x32 <asm/stat.h> which
- * appears to be wrong in older kernel headers.
- */
-
-#ifndef STRACE_ASM_STAT_H
-
-# define STRACE_ASM_STAT_H
-
-# include "kernel_types.h"
-
-struct stat {
-	kernel_ulong_t	st_dev;
-	kernel_ulong_t	st_ino;
-	kernel_ulong_t	st_nlink;
-	unsigned int	st_mode;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned int	pad0__;
-	kernel_ulong_t	st_rdev;
-	kernel_long_t	st_size;
-	kernel_long_t	st_blksize;
-	kernel_long_t	st_blocks;
-	kernel_ulong_t	st_atime;
-	kernel_ulong_t	st_atime_nsec;
-	kernel_ulong_t	st_mtime;
-	kernel_ulong_t	st_mtime_nsec;
-	kernel_ulong_t	st_ctime;
-	kernel_ulong_t	st_ctime_nsec;
-	kernel_long_t	pad1__[3];
-};
-
-struct __old_kernel_stat {
-	unsigned short st_dev;
-	unsigned short st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-	unsigned short st_rdev;
-	unsigned int  st_size;
-	unsigned int  st_atime;
-	unsigned int  st_mtime;
-	unsigned int  st_ctime;
-};
-
-#endif /* !STRACE_ASM_STAT_H */
+#include "x86_64/asm_stat.h"
diff --git a/linux/x32/ioctls_inc0.h b/linux/x32/ioctls_inc0.h
index 0c36e25..f41bd6e 100644
--- a/linux/x32/ioctls_inc0.h
+++ b/linux/x32/ioctls_inc0.h
@@ -284,6 +284,7 @@
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_FINI", _IOC_WRITE, 0x6445, 0x04 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_CPU_PREP", _IOC_WRITE, 0x6444, 0x18 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_INFO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
+{ "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_MADVISE", _IOC_READ|_IOC_WRITE, 0x6448, 0x0c },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_NEW", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GEM_SUBMIT", _IOC_READ|_IOC_WRITE, 0x6446, 0x20 },
 { "drm/msm_drm.h", "DRM_IOCTL_MSM_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6440, 0x10 },
@@ -392,10 +393,13 @@
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_BO", _IOC_READ|_IOC_WRITE, 0x6443, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_CREATE_SHADER_BO", _IOC_READ|_IOC_WRITE, 0x6445, 0x18 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_HANG_STATE", _IOC_READ|_IOC_WRITE, 0x6446, 0xa0 },
+{ "drm/vc4_drm.h", "DRM_IOCTL_VC4_GET_PARAM", _IOC_READ|_IOC_WRITE, 0x6447, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_MMAP_BO", _IOC_READ|_IOC_WRITE, 0x6444, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_SUBMIT_CL", _IOC_READ|_IOC_WRITE, 0x6440, 0xa0 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_BO", _IOC_READ|_IOC_WRITE, 0x6442, 0x10 },
 { "drm/vc4_drm.h", "DRM_IOCTL_VC4_WAIT_SEQNO", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_ATTACH", _IOC_READ|_IOC_WRITE, 0x6441, 0x10 },
+{ "drm/vgem_drm.h", "DRM_IOCTL_VGEM_FENCE_SIGNAL", _IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_AGP_INIT", _IOC_READ|_IOC_WRITE, 0x6442, 0x08 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_ALLOCMEM", _IOC_READ|_IOC_WRITE, 0x6440, 0x14 },
 { "drm/via_drm.h", "DRM_IOCTL_VIA_BLIT_SYNC", _IOC_WRITE, 0x644f, 0x08 },
@@ -683,6 +687,16 @@
 { "linux/cdrom.h", "DVD_AUTH", 0, 0x5392, 0 },
 { "linux/cdrom.h", "DVD_READ_STRUCT", 0, 0x5390, 0 },
 { "linux/cdrom.h", "DVD_WRITE_STRUCT", 0, 0x5391, 0 },
+{ "linux/cec.h", "CEC_ADAP_G_CAPS", _IOC_READ|_IOC_WRITE, 0x6100, 0x4c },
+{ "linux/cec.h", "CEC_ADAP_G_LOG_ADDRS", _IOC_READ, 0x6103, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_G_PHYS_ADDR", _IOC_READ, 0x6101, 0x02 },
+{ "linux/cec.h", "CEC_ADAP_S_LOG_ADDRS", _IOC_READ|_IOC_WRITE, 0x6104, 0x5c },
+{ "linux/cec.h", "CEC_ADAP_S_PHYS_ADDR", _IOC_WRITE, 0x6102, 0x02 },
+{ "linux/cec.h", "CEC_DQEVENT", _IOC_READ|_IOC_WRITE, 0x6107, 0x50 },
+{ "linux/cec.h", "CEC_G_MODE", _IOC_READ, 0x6108, 0x04 },
+{ "linux/cec.h", "CEC_RECEIVE", _IOC_READ|_IOC_WRITE, 0x6106, 0x38 },
+{ "linux/cec.h", "CEC_S_MODE", _IOC_WRITE, 0x6109, 0x04 },
+{ "linux/cec.h", "CEC_TRANSMIT", _IOC_READ|_IOC_WRITE, 0x6105, 0x38 },
 { "linux/chio.h", "CHIOEXCHANGE", _IOC_WRITE, 0x6302, 0x1c },
 { "linux/chio.h", "CHIOGELEM", _IOC_WRITE, 0x6310, 0x6c },
 { "linux/chio.h", "CHIOGPARAMS", _IOC_READ, 0x6306, 0x14 },
@@ -969,7 +983,11 @@
 { "linux/gigaset_dev.h", "GIGASET_CONFIG", _IOC_READ|_IOC_WRITE, 0x4701, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_REDIR", _IOC_READ|_IOC_WRITE, 0x4700, 0x04 },
 { "linux/gigaset_dev.h", "GIGASET_VERSION", _IOC_READ|_IOC_WRITE, 0x4703, 0x10 },
+{ "linux/gpio.h", "GPIOHANDLE_GET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb408, 0x40 },
+{ "linux/gpio.h", "GPIOHANDLE_SET_LINE_VALUES_IOCTL", _IOC_READ|_IOC_WRITE, 0xb409, 0x40 },
 { "linux/gpio.h", "GPIO_GET_CHIPINFO_IOCTL", _IOC_READ, 0xb401, 0x44 },
+{ "linux/gpio.h", "GPIO_GET_LINEEVENT_IOCTL", _IOC_READ|_IOC_WRITE, 0xb404, 0x30 },
+{ "linux/gpio.h", "GPIO_GET_LINEHANDLE_IOCTL", _IOC_READ|_IOC_WRITE, 0xb403, 0x16c },
 { "linux/gpio.h", "GPIO_GET_LINEINFO_IOCTL", _IOC_READ|_IOC_WRITE, 0xb402, 0x48 },
 { "linux/gsmmux.h", "GSMIOC_DISABLE_NET", _IOC_NONE, 0x4703, 0x00 },
 { "linux/gsmmux.h", "GSMIOC_ENABLE_NET", _IOC_WRITE, 0x4702, 0x34 },
@@ -1418,30 +1436,14 @@
 { "linux/lightnvm.h", "NVM_INFO", _IOC_READ|_IOC_WRITE, 0x4c20, 0x1000 },
 { "linux/lirc.h", "LIRC_GET_FEATURES", _IOC_READ, 0x6900, 0x04 },
 { "linux/lirc.h", "LIRC_GET_LENGTH", _IOC_READ, 0x690f, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_PULSE", _IOC_READ, 0x690b, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MAX_FILTER_SPACE", _IOC_READ, 0x690d, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MAX_TIMEOUT", _IOC_READ, 0x6909, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_PULSE", _IOC_READ, 0x690a, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_MIN_FILTER_SPACE", _IOC_READ, 0x690c, 0x04 },
 { "linux/lirc.h", "LIRC_GET_MIN_TIMEOUT", _IOC_READ, 0x6908, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_CARRIER", _IOC_READ, 0x6904, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_REC_DUTY_CYCLE", _IOC_READ, 0x6906, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_MODE", _IOC_READ, 0x6902, 0x04 },
 { "linux/lirc.h", "LIRC_GET_REC_RESOLUTION", _IOC_READ, 0x6907, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_CARRIER", _IOC_READ, 0x6903, 0x04 },
-{ "linux/lirc.h", "LIRC_GET_SEND_DUTY_CYCLE", _IOC_READ, 0x6905, 0x04 },
 { "linux/lirc.h", "LIRC_GET_SEND_MODE", _IOC_READ, 0x6901, 0x04 },
-{ "linux/lirc.h", "LIRC_NOTIFY_DECODE", _IOC_NONE, 0x6920, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_END", _IOC_NONE, 0x6922, 0x00 },
-{ "linux/lirc.h", "LIRC_SETUP_START", _IOC_NONE, 0x6921, 0x00 },
 { "linux/lirc.h", "LIRC_SET_MEASURE_CARRIER_MODE", _IOC_WRITE, 0x691d, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER", _IOC_WRITE, 0x6914, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_CARRIER_RANGE", _IOC_WRITE, 0x691f, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE", _IOC_WRITE, 0x6916, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_DUTY_CYCLE_RANGE", _IOC_WRITE, 0x691e, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER", _IOC_WRITE, 0x691c, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_PULSE", _IOC_WRITE, 0x691a, 0x04 },
-{ "linux/lirc.h", "LIRC_SET_REC_FILTER_SPACE", _IOC_WRITE, 0x691b, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_MODE", _IOC_WRITE, 0x6912, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT", _IOC_WRITE, 0x6918, 0x04 },
 { "linux/lirc.h", "LIRC_SET_REC_TIMEOUT_REPORTS", _IOC_WRITE, 0x6919, 0x04 },
@@ -1553,19 +1555,19 @@
 { "linux/ndctl.h", "ND_IOCTL_SMART", _IOC_READ|_IOC_WRITE, 0x4e01, 0x84 },
 { "linux/ndctl.h", "ND_IOCTL_SMART_THRESHOLD", _IOC_READ|_IOC_WRITE, 0x4e02, 0x0c },
 { "linux/ndctl.h", "ND_IOCTL_VENDOR", _IOC_READ|_IOC_WRITE, 0x4e09, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
-{ "linux/nilfs2_fs.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CHANGE_CPMODE", _IOC_WRITE, 0x6e80, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_CLEAN_SEGMENTS", _IOC_WRITE, 0x6e88, 0x78 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_DELETE_CHECKPOINT", _IOC_WRITE, 0x6e81, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_BDESCS", _IOC_READ|_IOC_WRITE, 0x6e87, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPINFO", _IOC_READ, 0x6e82, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_CPSTAT", _IOC_READ, 0x6e83, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUINFO", _IOC_READ, 0x6e84, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_SUSTAT", _IOC_READ, 0x6e85, 0x30 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_GET_VINFO", _IOC_READ|_IOC_WRITE, 0x6e86, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_RESIZE", _IOC_WRITE, 0x6e8b, 0x08 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_ALLOC_RANGE", _IOC_WRITE, 0x6e8c, 0x10 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SET_SUINFO", _IOC_WRITE, 0x6e8d, 0x18 },
+{ "linux/nilfs2_api.h", "NILFS_IOCTL_SYNC", _IOC_READ, 0x6e8a, 0x08 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ADMIN_CMD", _IOC_READ|_IOC_WRITE, 0x4e41, 0x48 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_ID", _IOC_NONE, 0x4e40, 0x00 },
 { "linux/nvme_ioctl.h", "NVME_IOCTL_IO_CMD", _IOC_READ|_IOC_WRITE, 0x4e43, 0x48 },
@@ -1739,6 +1741,17 @@
 { "linux/raw.h", "RAW_SETBIND", _IOC_NONE, 0xac00, 0x00 },
 { "linux/reiserfs_fs.h", "REISERFS_IOC_UNPACK", _IOC_WRITE, 0xcd01, 0x04 },
 { "linux/rfkill.h", "RFKILL_IOCTL_NOINPUT", _IOC_NONE, 0x5201, 0x00 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_ACCEPT", _IOC_READ|_IOC_WRITE, 0x6307, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_BIND", _IOC_WRITE, 0x6305, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CLOSE", _IOC_WRITE, 0x6304, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CONNECT", _IOC_WRITE, 0x6308, 0x08 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_CREATE", _IOC_READ|_IOC_WRITE, 0x6303, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_LISTEN", _IOC_WRITE, 0x6306, 0x02 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_RECEIVE", _IOC_READ|_IOC_WRITE, 0x630a, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_CHAN_SEND", _IOC_WRITE, 0x6309, 0x10 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST", _IOC_READ|_IOC_WRITE, 0x6302, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_EP_GET_LIST_SIZE", _IOC_READ|_IOC_WRITE, 0x6301, 0x04 },
+{ "linux/rio_cm_cdev.h", "RIO_CM_MPORT_GET_LIST", _IOC_READ|_IOC_WRITE, 0x630b, 0x04 },
 { "linux/rio_mport_cdev.h", "RIO_ALLOC_DMA", _IOC_READ|_IOC_WRITE, 0x6d13, 0x18 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_ADD", _IOC_WRITE, 0x6d17, 0x20 },
 { "linux/rio_mport_cdev.h", "RIO_DEV_DEL", _IOC_WRITE, 0x6d18, 0x20 },
@@ -2244,6 +2257,8 @@
 { "linux/vhost.h", "VHOST_SET_VRING_ERR", _IOC_WRITE, 0xaf22, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_KICK", _IOC_WRITE, 0xaf20, 0x08 },
 { "linux/vhost.h", "VHOST_SET_VRING_NUM", _IOC_WRITE, 0xaf10, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_GUEST_CID", _IOC_WRITE, 0xaf60, 0x08 },
+{ "linux/vhost.h", "VHOST_VSOCK_SET_RUNNING", _IOC_WRITE, 0xaf61, 0x04 },
 { "linux/videodev2.h", "VIDIOC_CREATE_BUFS", _IOC_READ|_IOC_WRITE, 0x565c, 0xf8 },
 { "linux/videodev2.h", "VIDIOC_CROPCAP", _IOC_READ|_IOC_WRITE, 0x563a, 0x2c },
 { "linux/videodev2.h", "VIDIOC_DBG_G_CHIP_INFO", _IOC_READ|_IOC_WRITE, 0x5666, 0xc8 },
@@ -2348,7 +2363,6 @@
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_SOCKETS_VERSION", _IOC_NONE, 0x07b4, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION", _IOC_NONE, 0x079f, 0x00 },
 { "linux/vmw_vmci_defs.h", "IOCTL_VMCI_VERSION2", _IOC_NONE, 0x07a7, 0x00 },
-{ "linux/vsp1.h", "VIDIOC_VSP1_LUT_CONFIG", _IOC_READ|_IOC_WRITE, 0x56c1, 0x400 },
 { "linux/vt.h", "VT_ACTIVATE", 0, 0x5606, 0 },
 { "linux/vt.h", "VT_DISALLOCATE", 0, 0x5608, 0 },
 { "linux/vt.h", "VT_GETHIFONTMASK", 0, 0x560D, 0 },
@@ -2365,6 +2379,7 @@
 { "linux/vt.h", "VT_UNLOCKSWITCH", 0, 0x560C, 0 },
 { "linux/vt.h", "VT_WAITACTIVE", 0, 0x5607, 0 },
 { "linux/vt.h", "VT_WAITEVENT", 0, 0x560E, 0 },
+{ "linux/vtpm_proxy.h", "VTPM_PROXY_IOC_NEW_DEV", _IOC_READ|_IOC_WRITE, 0xa100, 0x14 },
 { "linux/watchdog.h", "WDIOC_GETBOOTSTATUS", _IOC_READ, 0x5702, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETPRETIMEOUT", _IOC_READ, 0x5709, 0x04 },
 { "linux/watchdog.h", "WDIOC_GETSTATUS", _IOC_READ, 0x5701, 0x04 },
@@ -2771,8 +2786,6 @@
 { "staging/android/ion_test.h", "ION_IOC_TEST_DMA_MAPPING", _IOC_WRITE, 0x49f1, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_KERNEL_MAPPING", _IOC_WRITE, 0x49f2, 0x20 },
 { "staging/android/ion_test.h", "ION_IOC_TEST_SET_FD", _IOC_NONE, 0x49f0, 0x00 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_CREATE_FENCE", _IOC_READ|_IOC_WRITE, 0x5700, 0x28 },
-{ "staging/android/sw_sync.h", "SW_SYNC_IOC_INC", _IOC_WRITE, 0x5701, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_BRIGHTNESS", _IOC_READ, 0x4603, 0x04 },
 { "video/da8xx-fb.h", "FBIGET_COLOR", _IOC_READ, 0x4605, 0x04 },
 { "video/da8xx-fb.h", "FBIOGET_CONTRAST", _IOC_READ, 0x4601, 0x04 },
@@ -2813,6 +2826,7 @@
 { "xen/evtchn.h", "IOCTL_EVTCHN_BIND_VIRQ", _IOC_NONE, 0x4500, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_NOTIFY", _IOC_NONE, 0x4504, 0x04 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_RESET", _IOC_NONE, 0x4505, 0x00 },
+{ "xen/evtchn.h", "IOCTL_EVTCHN_RESTRICT_DOMID", _IOC_NONE, 0x4506, 0x02 },
 { "xen/evtchn.h", "IOCTL_EVTCHN_UNBIND", _IOC_NONE, 0x4503, 0x04 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR", _IOC_NONE, 0x4702, 0x18 },
 { "xen/gntdev.h", "IOCTL_GNTDEV_GRANT_COPY", _IOC_NONE, 0x4708, 0x08 },
diff --git a/linux/x32/syscallent.h b/linux/x32/syscallent.h
index d07ff1c..10443d3 100644
--- a/linux/x32/syscallent.h
+++ b/linux/x32/syscallent.h
@@ -204,8 +204,8 @@
 [203] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [204] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [205] = { 1,	0,		SEN(printargs),			"64:set_thread_area"	},
-[206] = { 2,	0,		SEN(printargs),			"64:io_setup"		},
-[207] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[206] = { 2,	TM,		SEN(printargs),			"64:io_setup"		},
+[207] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [208] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [209] = { 3,	0,		SEN(printargs),			"64:io_submit"		},
 [210] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -219,7 +219,7 @@
 [218] = { 1,	0,		SEN(set_tid_address),		"set_tid_address"	},
 [219] = { 0,	0,		SEN(restart_syscall),		"restart_syscall"	},
 [220] = { 4,	TI,		SEN(semtimedop),		"semtimedop"		},
-[221] = { 4,	TD,		SEN(fadvise64_64),		"fadvise64"		},
+[221] = { 4,	TD,		SEN(fadvise64),			"fadvise64"		},
 [222] = { 3,	0,		SEN(printargs),			"64:timer_create"	},
 [223] = { 4,	0,		SEN(timer_settime),		"timer_settime"		},
 [224] = { 2,	0,		SEN(timer_gettime),		"timer_gettime"		},
@@ -363,6 +363,6 @@
 [540] = { 6,	0,		SEN(process_vm_writev),		"process_vm_writev"	},
 [541] = { 5,	TN,		SEN(setsockopt),		"setsockopt"		},
 [542] = { 5,	TN,		SEN(getsockopt),		"getsockopt"		},
-[543] = { 2,	0,		SEN(io_setup),			"io_setup"		},
+[543] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
 [544] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [545] = { 5,	TD|TF|TP|SE|SI,	SEN(execveat),			"execveat",		},
diff --git a/linux/x86_64/asm_stat.h b/linux/x86_64/asm_stat.h
new file mode 100644
index 0000000..a563f08
--- /dev/null
+++ b/linux/x86_64/asm_stat.h
@@ -0,0 +1,39 @@
+#ifndef STRACE_X86_64_ASM_STAT_H
+#define STRACE_X86_64_ASM_STAT_H
+
+# if defined __x86_64__ && defined __ILP32__
+#  define stat redirect_kernel_stat
+# endif
+
+# include "linux/asm_stat.h"
+
+# if defined __x86_64__ && defined __ILP32__
+#  undef stat
+/*
+ * This is a replacement for x32 <asm/stat.h> which
+ * appears to be wrong in older kernel headers.
+ */
+struct stat {
+	kernel_ulong_t	st_dev;
+	kernel_ulong_t	st_ino;
+	kernel_ulong_t	st_nlink;
+	unsigned int	st_mode;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned int	pad0__;
+	kernel_ulong_t	st_rdev;
+	kernel_long_t	st_size;
+	kernel_long_t	st_blksize;
+	kernel_long_t	st_blocks;
+	kernel_ulong_t	st_atime;
+	kernel_ulong_t	st_atime_nsec;
+	kernel_ulong_t	st_mtime;
+	kernel_ulong_t	st_mtime_nsec;
+	kernel_ulong_t	st_ctime;
+	kernel_ulong_t	st_ctime_nsec;
+	kernel_long_t	pad1__[3];
+};
+
+# endif /* __x86_64__ && __ILP32__ */
+
+#endif /* !STRACE_X86_64_ASM_STAT_H */
diff --git a/linux/x86_64/syscallent.h b/linux/x86_64/syscallent.h
index 265d55f..6e814ea 100644
--- a/linux/x86_64/syscallent.h
+++ b/linux/x86_64/syscallent.h
@@ -204,8 +204,8 @@
 [203] = { 3,	0,		SEN(sched_setaffinity),		"sched_setaffinity"	},
 [204] = { 3,	0,		SEN(sched_getaffinity),		"sched_getaffinity"	},
 [205] = { 1,	0,		SEN(set_thread_area),		"set_thread_area"	},
-[206] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[207] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[206] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[207] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [208] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [209] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [210] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
diff --git a/linux/xtensa/syscallent.h b/linux/xtensa/syscallent.h
index ffb7d43..74eb5c3 100644
--- a/linux/xtensa/syscallent.h
+++ b/linux/xtensa/syscallent.h
@@ -229,8 +229,8 @@
 [236] = { 2,	0,		SEN(mq_notify),			"mq_notify"		},
 [237] = { 3,	0,		SEN(mq_getsetattr),		"mq_getsetattr"		},
 [238] = { },
-[239] = { 2,	0,		SEN(io_setup),			"io_setup"		},
-[240] = { 1,	0,		SEN(io_destroy),		"io_destroy"		},
+[239] = { 2,	TM,		SEN(io_setup),			"io_setup"		},
+[240] = { 1,	TM,		SEN(io_destroy),		"io_destroy"		},
 [241] = { 3,	0,		SEN(io_submit),			"io_submit"		},
 [242] = { 5,	0,		SEN(io_getevents),		"io_getevents"		},
 [243] = { 3,	0,		SEN(io_cancel),			"io_cancel"		},
@@ -288,7 +288,7 @@
 [296] = { 4,	TD|TF,		SEN(utimensat),			"utimensat"		},
 [297] = { 5,	TD|TF,		SEN(fchownat),			"fchownat"		},
 [298] = { 3,	TD|TF,		SEN(futimesat),			"futimesat"		},
-[299] = { 4,	TD|TF,		SEN(newfstatat),		"fstatat64"		},
+[299] = { 4,	TD|TF,		SEN(fstatat64),			"fstatat64"		},
 [300] = { 3,	TD|TF,		SEN(fchmodat),			"fchmodat"		},
 [301] = { 3,	TD|TF,		SEN(faccessat),			"faccessat"		},
 [302 ... 303] = { },
diff --git a/lseek.c b/lseek.c
index 8d05dc1..1846abe 100644
--- a/lseek.c
+++ b/lseek.c
@@ -110,8 +110,8 @@
 	if (entering(tcp)) {
 		printfd(tcp, tcp->u_arg[0]);
 		tprintf(", %lld, ",
-			(widen_to_ull(tcp->u_arg[1]) << 32)
-			| widen_to_ull(tcp->u_arg[2]));
+			(zero_extend_signed_to_ull(tcp->u_arg[1]) << 32)
+			| zero_extend_signed_to_ull(tcp->u_arg[2]));
 	} else {
 		printnum_int64(tcp, tcp->u_arg[3], "%" PRIu64);
 		tprints(", ");
diff --git a/m4/mpers.m4 b/m4/mpers.m4
index 1fe8a8e..277a384 100644
--- a/m4/mpers.m4
+++ b/m4/mpers.m4
@@ -1,6 +1,6 @@
 #!/usr/bin/m4
 #
-# Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
+# Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
 # Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
 # All rights reserved.
 #
@@ -26,8 +26,59 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+AC_DEFUN([st_MPERS_LOAD_AC_CV], [
+
+pushdef([var], [ac_cv_$1])
+pushdef([saved], [saved_ac_cv_$1])
+pushdef([mpers], [ac_cv_]mpers_name[_$1])
+
+AS_IF([test -n "${var+set}"], [saved="${var}"; unset var])
+AS_IF([test -n "${mpers+set}"], [var="${mpers}"])
+
+popdef([mpers])
+popdef([saved])
+popdef([var])
+
+])
+
+AC_DEFUN([st_MPERS_SAVE_AC_CV], [
+
+pushdef([var], [ac_cv_$1])
+pushdef([saved], [saved_ac_cv_$1])
+pushdef([mpers], [ac_cv_]mpers_name[_$1])
+
+AS_IF([test -n "${var+set}"], [mpers="${var}"])
+AS_IF([test -n "${saved+set}"], [var="${saved}"; unset saved])
+
+popdef([mpers])
+popdef([saved])
+popdef([var])
+
+])
+
+AC_DEFUN([st_MPERS_STRUCT_STAT], [
+
+st_MPERS_LOAD_AC_CV([type_struct_stat$1])
+AC_CHECK_TYPE([struct stat$1],
+	      AC_DEFINE([HAVE_]MPERS_NAME[_STRUCT_STAT$1], [1],
+			[Define to 1 if MPERS_NAME has the type 'struct stat$1'.]),,
+[#include <sys/types.h>
+#include <asm/stat.h>])
+st_MPERS_SAVE_AC_CV([type_struct_stat$1])
+
+st_MPERS_LOAD_AC_CV([member_struct_stat$1_st_mtime_nsec])
+AC_CHECK_MEMBER([struct stat$1.st_mtime_nsec],
+		AC_DEFINE([HAVE_]MPERS_NAME[_STRUCT_STAT$1_ST_MTIME_NSEC], [1],
+			  [Define to 1 if 'st_mtime_nsec' is a member of MPERS_NAME 'struct stat$1'.]),,
+[#include <sys/types.h>
+#include <asm/stat.h>])
+st_MPERS_SAVE_AC_CV([member_struct_stat$1_st_mtime_nsec])
+
+])
+
 AC_DEFUN([st_MPERS],[
 
+pushdef([mpers_name], [$1])
 pushdef([MPERS_NAME], translit([$1], [a-z], [A-Z]))
 pushdef([HAVE_MPERS], [HAVE_]MPERS_NAME[_MPERS])
 pushdef([HAVE_RUNTIME], [HAVE_]MPERS_NAME[_RUNTIME])
@@ -73,6 +124,8 @@
 		if test $st_cv_mpers = yes; then
 			AC_DEFINE(HAVE_MPERS, [1],
 				  [Define to 1 if you have CFLAG mpers support])
+			st_MPERS_STRUCT_STAT([])
+			st_MPERS_STRUCT_STAT([64])
 		fi
 	fi
 	CFLAGS="$saved_CFLAGS"
@@ -84,7 +137,7 @@
 	;;
 esac
 
-AM_CONDITIONAL(HAVE_RUNTIME, [test "$st_cv_runtime" = yes])
+AM_CONDITIONAL(HAVE_RUNTIME, [test "$st_cv_mpers$st_cv_runtime" = yesyes])
 AM_CONDITIONAL(HAVE_MPERS, [test "$st_cv_mpers" = yes])
 
 popdef([st_cv_mpers])
@@ -94,5 +147,6 @@
 popdef([HAVE_RUNTIME])
 popdef([HAVE_MPERS])
 popdef([MPERS_NAME])
+popdef([mpers_name])
 
 ])
diff --git a/maint/ioctls_sym.sh b/maint/ioctls_sym.sh
index 20b1730..7a67339 100755
--- a/maint/ioctls_sym.sh
+++ b/maint/ioctls_sym.sh
@@ -190,6 +190,17 @@
 #undef FBIOPUTCMAP
 __EOF__
 			;;
+		*linux/atm_zatm.h)
+			cat <<'__EOF__'
+#include <linux/atm.h>
+#ifndef _LINUX_TIME_H
+# define _LINUX_TIME_H
+#endif
+#ifndef _UAPI_LINUX_TIME_H
+# define _UAPI_LINUX_TIME_H
+#endif
+__EOF__
+			;;
 		*linux/atm?*.h)
 			echo '#include <linux/atm.h>'
 			;;
@@ -297,7 +308,7 @@
 		*video/sstfb.h)
 			echo 'struct fb_info;'
 			;;
-		*xen/gntdev.h)
+		*xen/evtchn.h|*xen/gntdev.h)
 			cat <<'__EOF__'
 typedef uint32_t grant_ref_t;
 typedef uint16_t domid_t;
diff --git a/make-dsc b/make-dsc
index 951c5a9..f0e958a 100755
--- a/make-dsc
+++ b/make-dsc
@@ -8,7 +8,7 @@
 Binary: $(sed '/^Package:[[:space:]]*/!d;s///' debian/control |
 	tr '\n' ' ' | sed 's/ ./,&/g')
 $(sed '/^Architecture:[[:space:]]*/!d;q' debian/control)
-Version: $(sed -n '1s/^[^(]*(\([^)]\+\)).*/\1/p' debian/changelog)
+Version: $(sed -r -n '1s/^[^(]*\(([^)]+)\).*/\1/p' debian/changelog)
 $(sed '/^Maintainer:[[:space:]]*/!d;q' debian/control)
 $(sed '/^Homepage:[[:space:]]*/!d;q' debian/control)
 $(sed '/^Standards-Version:[[:space:]]*/!d;q' debian/control)
diff --git a/mknod.c b/mknod.c
index d78fa07..9b90311 100644
--- a/mknod.c
+++ b/mknod.c
@@ -35,23 +35,17 @@
 
 #include <fcntl.h>
 #include <sys/stat.h>
-
-#ifdef MAJOR_IN_SYSMACROS
-# include <sys/sysmacros.h>
-#endif
-
-#ifdef MAJOR_IN_MKDEV
-# include <sys/mkdev.h>
-#endif
+#include <sys/sysmacros.h>
 
 static void
 decode_mknod(struct tcb *tcp, int offset)
 {
-	int mode = tcp->u_arg[offset + 1];
+	unsigned short mode = tcp->u_arg[offset + 1];
 	unsigned int dev;
 
 	printpath(tcp, tcp->u_arg[offset]);
-	tprintf(", %s", sprintmode(mode));
+	tprints(", ");
+	print_symbolic_mode_t(mode);
 	switch (mode & S_IFMT) {
 	case S_IFCHR:
 	case S_IFBLK:
diff --git a/mpers.awk b/mpers.awk
index 809acf8..2283b96 100644
--- a/mpers.awk
+++ b/mpers.awk
@@ -146,7 +146,7 @@
 			if ("parent" in array[item] && \
 				array_get(item, "parent") == what_idx) {
 				returned = what_is(item)
-				printf("%s", array_get(item, "name"))
+				printf("%s", array[item]["name"])
 				if ("" != returned) {
 					printf("[%s]", returned)
 				}
diff --git a/mpers.sh b/mpers.sh
index 559d1f4..36913e7 100755
--- a/mpers.sh
+++ b/mpers.sh
@@ -40,8 +40,8 @@
 BITS_DIR="mpers${ARCH_FLAG}"
 
 mkdir -p ${BITS_DIR}
-set -- $(sed -n \
-	's/^#[[:space:]]*include[[:space:]]\+DEF_MPERS_TYPE(\([^)[:space:]]*\))$/\1/p' \
+set -- $(sed -r -n \
+	's/^#[[:space:]]*include[[:space:]]+DEF_MPERS_TYPE\(([^)[:space:]]*)\)$/\1/p' \
 		"${PARSER_FILE}")
 for m_type; do
 	f_h="${BITS_DIR}/${m_type}.h"
@@ -53,8 +53,8 @@
 	sed -e '
 		/DEF_MPERS_TYPE('"${m_type}"')$/n
 		/DEF_MPERS_TYPE/d
-		/^[[:space:]]*#[[:space:]]*include[[:space:]]\+\"xlat\//d
-		/^#[[:space:]]*include[[:space:]]\+MPERS_DEFS$/ {s//'"${m_type} ${VAR_NAME}"';/;q}
+		/^[[:space:]]*#[[:space:]]*include[[:space:]]*"xlat\//d
+		/^#[[:space:]]*include[[:space:]][[:space:]]*MPERS_DEFS$/ {s//'"${m_type} ${VAR_NAME}"';/;q}
 		' "${PARSER_FILE}" > "${f_c}"
 	$CPP $CPPFLAGS "${f_c}" > "${f_i}"
 	grep -F -q "${m_type}.h" "${f_i}" ||
@@ -62,12 +62,12 @@
 	sed -i -e '/DEF_MPERS_TYPE/d' "${f_c}"
 	$CC $CFLAGS $ARCH_FLAG "${f_c}" -o "${f_o}"
 	readelf --debug-dump=info "${f_o}" > "${f_d1}"
-	sed -n '
-		/^[[:space:]]*<1>/,/^[[:space:]]*<1><[^>]\+>: Abbrev Number: 0/!d
-		/^[[:space:]]*<[^>]\+><[^>]\+>: Abbrev Number: 0/d
-		s/^[[:space:]]*<[[:xdigit:]]\+>[[:space:]]\+//
-		s/^[[:space:]]*\(\(<[[:xdigit:]]\+>\)\{2\}\):[[:space:]]\+/\1\n/
-		s/[[:space:]]\+$//
+	sed -r -n '
+		/^[[:space:]]*<1>/,/^[[:space:]]*<1><[^>]+>: Abbrev Number: 0/!d
+		/^[[:space:]]*<[^>]*><[^>]*>: Abbrev Number: 0/d
+		s/^[[:space:]]*<[[:xdigit:]]+>[[:space:]]+//
+		s/^[[:space:]]*((<[[:xdigit:]]+>){2}):[[:space:]]+/\1\n/
+		s/[[:space:]]+$//
 		p' "${f_d1}" > "${f_d2}"
 	gawk -v VAR_NAME="$VAR_NAME" -v ARCH_FLAG="${ARCH_FLAG#-}" \
 		-f "$MPERS_AWK" "${f_d2}" > "${f_h}"
diff --git a/mpers_test.sh b/mpers_test.sh
index 72b5f5d..907460b 100755
--- a/mpers_test.sh
+++ b/mpers_test.sh
@@ -121,7 +121,7 @@
 #define MPERS_${mpers_name}_sample_struct ${mpers_name}_sample_struct
 EOF
 
-CFLAGS="$CPPFLAGS -I${srcdir}" \
+CFLAGS="$CPPFLAGS -I${srcdir} -DMPERS_IS_${mpers_name}" \
 CPPFLAGS="$CPPFLAGS -I${srcdir} -DIN_MPERS -DMPERS_IS_${mpers_name}" \
 "$mpers_sh" "-$mpers_name" "$sample"
 cmp "$expected" "$mpers_dir"/sample_struct.h > /dev/null
diff --git a/mpers_type.h b/mpers_type.h
index 4ce569b..ac840ad 100644
--- a/mpers_type.h
+++ b/mpers_type.h
@@ -26,6 +26,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_MPERS_TYPE_H
+#define STRACE_MPERS_TYPE_H
+
 #ifdef IN_MPERS
 # define STRINGIFY(a) #a
 # define DEF_MPERS_TYPE(args) STRINGIFY(args.h)
@@ -45,3 +48,5 @@
 #  define MPERS_DEFS "native_defs.h"
 # endif
 #endif
+
+#endif /* !STRACE_MPERS_TYPE_H */
diff --git a/mq.c b/mq.c
index e12eef7..1df2aa1 100644
--- a/mq.c
+++ b/mq.c
@@ -37,7 +37,9 @@
 	tprint_open_modes(tcp->u_arg[1]);
 	if (tcp->u_arg[1] & O_CREAT) {
 		/* mode */
-		tprintf(", %#lo, ", tcp->u_arg[2]);
+		tprints(", ");
+		print_numeric_umode_t(tcp->u_arg[2]);
+		tprints(", ");
 		printmqattr(tcp, tcp->u_arg[3]);
 	}
 	return RVAL_DECODED;
diff --git a/msghdr.h b/msghdr.h
index 41a07d7..41dfd8c 100644
--- a/msghdr.h
+++ b/msghdr.h
@@ -1,5 +1,5 @@
-#ifndef MSGHDR_H_
-# define MSGHDR_H_
+#ifndef STRACE_MSGHDR_H
+#define STRACE_MSGHDR_H
 
 /* For definitions of struct msghdr and struct mmsghdr. */
 # include <sys/socket.h>
@@ -14,4 +14,4 @@
 struct tcb;
 extern void print_struct_msghdr(struct tcb *, const struct msghdr *, const int *, unsigned long);
 
-#endif /* MSGHDR_H_ */
+#endif /* !STRACE_MSGHDR_H */
diff --git a/native_printer_decls.h b/native_printer_decls.h
index 14456ad..b0b480b 100644
--- a/native_printer_decls.h
+++ b/native_printer_decls.h
@@ -1,4 +1,4 @@
-/* Generated by Makefile from block.c.mpers.i btrfs.c.mpers.i dirent.c.mpers.i evdev.c.mpers.i fetch_seccomp_fprog.c.mpers.i fetch_struct_flock.c.mpers.i fetch_struct_mmsghdr.c.mpers.i fetch_struct_msghdr.c.mpers.i fetch_struct_statfs.c.mpers.i hdio.c.mpers.i ipc_msgctl.c.mpers.i ipc_shmctl.c.mpers.i mtd.c.mpers.i print_mq_attr.c.mpers.i print_msgbuf.c.mpers.i print_sigevent.c.mpers.i print_time.c.mpers.i print_timex.c.mpers.i printrusage.c.mpers.i printsiginfo.c.mpers.i rtc.c.mpers.i sigaltstack.c.mpers.i sysinfo.c.mpers.i times.c.mpers.i utime.c.mpers.i v4l2.c.mpers.i; do not edit. */
+/* Generated by Makefile from block.c.mpers.i btrfs.c.mpers.i dirent.c.mpers.i evdev.c.mpers.i fetch_seccomp_fprog.c.mpers.i fetch_struct_flock.c.mpers.i fetch_struct_mmsghdr.c.mpers.i fetch_struct_msghdr.c.mpers.i fetch_struct_stat.c.mpers.i fetch_struct_stat64.c.mpers.i fetch_struct_statfs.c.mpers.i hdio.c.mpers.i ipc_msgctl.c.mpers.i ipc_shmctl.c.mpers.i mtd.c.mpers.i print_mq_attr.c.mpers.i print_msgbuf.c.mpers.i print_sigevent.c.mpers.i print_time.c.mpers.i print_timex.c.mpers.i printrusage.c.mpers.i printsiginfo.c.mpers.i rtc.c.mpers.i sigaltstack.c.mpers.i sysinfo.c.mpers.i times.c.mpers.i utime.c.mpers.i v4l2.c.mpers.i; do not edit. */
 extern int block_ioctl(struct tcb *tcp, const unsigned int code, const long arg);
 extern int btrfs_ioctl(struct tcb *tcp, const unsigned int code, const long arg);
 extern int evdev_ioctl(struct tcb *tcp, const unsigned int code, const long arg);
@@ -8,6 +8,8 @@
 extern int fetch_struct_mmsghdr(struct tcb *tcp, const unsigned long addr, void *p);
 extern unsigned int sizeof_struct_mmsghdr(void);
 extern int fetch_struct_msghdr(struct tcb *tcp, const unsigned long addr, void *p);
+extern _Bool fetch_struct_stat(struct tcb *tcp, const unsigned long addr, struct strace_stat *const dst);
+extern _Bool fetch_struct_stat64(struct tcb *tcp, const unsigned long addr, struct strace_stat *const dst);
 extern _Bool fetch_struct_statfs(struct tcb *tcp, const long addr, struct strace_statfs *p);
 extern _Bool fetch_struct_statfs64(struct tcb *tcp, const long addr, const unsigned long size, struct strace_statfs *p);
 extern int hdio_ioctl(struct tcb *tcp, const unsigned int code, const long arg);
diff --git a/native_printer_defs.h b/native_printer_defs.h
index 470ca1f..5d64250 100644
--- a/native_printer_defs.h
+++ b/native_printer_defs.h
@@ -1,4 +1,4 @@
-/* Generated by Makefile from block.c.mpers.i btrfs.c.mpers.i dirent.c.mpers.i evdev.c.mpers.i fetch_seccomp_fprog.c.mpers.i fetch_struct_flock.c.mpers.i fetch_struct_mmsghdr.c.mpers.i fetch_struct_msghdr.c.mpers.i fetch_struct_statfs.c.mpers.i hdio.c.mpers.i ipc_msgctl.c.mpers.i ipc_shmctl.c.mpers.i mtd.c.mpers.i print_mq_attr.c.mpers.i print_msgbuf.c.mpers.i print_sigevent.c.mpers.i print_time.c.mpers.i print_timex.c.mpers.i printrusage.c.mpers.i printsiginfo.c.mpers.i rtc.c.mpers.i sigaltstack.c.mpers.i sysinfo.c.mpers.i times.c.mpers.i utime.c.mpers.i v4l2.c.mpers.i; do not edit. */
+/* Generated by Makefile from block.c.mpers.i btrfs.c.mpers.i dirent.c.mpers.i evdev.c.mpers.i fetch_seccomp_fprog.c.mpers.i fetch_struct_flock.c.mpers.i fetch_struct_mmsghdr.c.mpers.i fetch_struct_msghdr.c.mpers.i fetch_struct_stat.c.mpers.i fetch_struct_stat64.c.mpers.i fetch_struct_statfs.c.mpers.i hdio.c.mpers.i ipc_msgctl.c.mpers.i ipc_shmctl.c.mpers.i mtd.c.mpers.i print_mq_attr.c.mpers.i print_msgbuf.c.mpers.i print_sigevent.c.mpers.i print_time.c.mpers.i print_timex.c.mpers.i printrusage.c.mpers.i printsiginfo.c.mpers.i rtc.c.mpers.i sigaltstack.c.mpers.i sysinfo.c.mpers.i times.c.mpers.i utime.c.mpers.i v4l2.c.mpers.i; do not edit. */
 .block_ioctl = block_ioctl,
 .btrfs_ioctl = btrfs_ioctl,
 .evdev_ioctl = evdev_ioctl,
@@ -8,6 +8,8 @@
 .fetch_struct_mmsghdr = fetch_struct_mmsghdr,
 .sizeof_struct_mmsghdr = sizeof_struct_mmsghdr,
 .fetch_struct_msghdr = fetch_struct_msghdr,
+.fetch_struct_stat = fetch_struct_stat,
+.fetch_struct_stat64 = fetch_struct_stat64,
 .fetch_struct_statfs = fetch_struct_statfs,
 .fetch_struct_statfs64 = fetch_struct_statfs64,
 .hdio_ioctl = hdio_ioctl,
diff --git a/net.c b/net.c
index 017764c..b039463 100644
--- a/net.c
+++ b/net.c
@@ -702,7 +702,7 @@
 
 	tprintf("{gr_interface=%u, gr_group=", greq.gr_interface);
 	print_sockaddr(tcp, &greq.gr_group, sizeof(greq.gr_group));
-	tprintf("}");
+	tprints("}");
 
 }
 #endif /* MCAST_JOIN_GROUP */
diff --git a/oldstat.c b/oldstat.c
new file mode 100644
index 0000000..a5dd177
--- /dev/null
+++ b/oldstat.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
+ * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
+ * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
+ * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
+ * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include "asm_stat.h"
+#include "stat.h"
+
+#ifdef HAVE_STRUCT___OLD_KERNEL_STAT
+
+static void
+print_old_kernel_stat(struct tcb *tcp, const unsigned long addr)
+{
+	struct __old_kernel_stat buf;
+	if (umove_or_printaddr(tcp, addr, &buf))
+		return;
+
+	struct strace_stat st = {
+		.dev = zero_extend_signed_to_ull(buf.st_dev),
+		.ino = zero_extend_signed_to_ull(buf.st_ino),
+		.rdev = zero_extend_signed_to_ull(buf.st_rdev),
+		.size = zero_extend_signed_to_ull(buf.st_size),
+		.mode = zero_extend_signed_to_ull(buf.st_mode),
+		.nlink = zero_extend_signed_to_ull(buf.st_nlink),
+		.uid = zero_extend_signed_to_ull(buf.st_uid),
+		.gid = zero_extend_signed_to_ull(buf.st_gid),
+		.atime = sign_extend_unsigned_to_ll(buf.st_atime),
+		.ctime = sign_extend_unsigned_to_ll(buf.st_ctime),
+		.mtime = sign_extend_unsigned_to_ll(buf.st_mtime)
+	};
+
+	print_struct_stat(tcp, &st);
+}
+
+SYS_FUNC(oldstat)
+{
+	if (entering(tcp)) {
+		printpath(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		print_old_kernel_stat(tcp, tcp->u_arg[1]);
+	}
+	return 0;
+}
+
+SYS_FUNC(oldfstat)
+{
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		print_old_kernel_stat(tcp, tcp->u_arg[1]);
+	}
+	return 0;
+}
+
+#endif /* HAVE_STRUCT___OLD_KERNEL_STAT */
diff --git a/open.c b/open.c
index 90dd10f..6128fb0 100644
--- a/open.c
+++ b/open.c
@@ -115,6 +115,13 @@
 	tprints(sprint_open_modes(flags) + sizeof("flags"));
 }
 
+#ifdef O_TMPFILE
+/* The kernel & C libraries often inline O_DIRECTORY. */
+# define STRACE_O_TMPFILE (O_TMPFILE & ~O_DIRECTORY)
+#else /* !O_TMPFILE */
+# define STRACE_O_TMPFILE 0
+#endif
+
 static int
 decode_open(struct tcb *tcp, int offset)
 {
@@ -122,9 +129,10 @@
 	tprints(", ");
 	/* flags */
 	tprint_open_modes(tcp->u_arg[offset + 1]);
-	if (tcp->u_arg[offset + 1] & O_CREAT) {
+	if (tcp->u_arg[offset + 1] & (O_CREAT | STRACE_O_TMPFILE)) {
 		/* mode */
-		tprintf(", %#lo", tcp->u_arg[offset + 2]);
+		tprints(", ");
+		print_numeric_umode_t(tcp->u_arg[offset + 2]);
 	}
 
 	return RVAL_DECODED | RVAL_FD;
@@ -144,7 +152,8 @@
 SYS_FUNC(creat)
 {
 	printpath(tcp, tcp->u_arg[0]);
-	tprintf(", %#lo", tcp->u_arg[1]);
+	tprints(", ");
+	print_numeric_umode_t(tcp->u_arg[1]);
 
 	return RVAL_DECODED | RVAL_FD;
 }
diff --git a/pathtrace.c b/pathtrace.c
index 74dc3a0..398fb28 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -174,6 +174,7 @@
 	case SEN_faccessat:
 	case SEN_fchmodat:
 	case SEN_fchownat:
+	case SEN_fstatat64:
 	case SEN_futimesat:
 	case SEN_inotify_add_watch:
 	case SEN_mkdirat:
diff --git a/print_struct_stat.c b/print_struct_stat.c
new file mode 100644
index 0000000..7b23ec8
--- /dev/null
+++ b/print_struct_stat.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1999-2003 Ulrich Drepper <drepper@redhat.com>
+ * Copyright (c) 2004 David S. Miller <davem@nuts.davemloft.net>
+ * Copyright (c) 2003-2005 Roland McGrath <roland@redhat.com>
+ * Copyright (c) 2007 Jan Kratochvil <jan.kratochvil@redhat.com>
+ * Copyright (c) 2009 Denys Vlasenko <dvlasenk@redhat.com>
+ * Copyright (c) 2009-2010 Andreas Schwab <schwab@linux-m68k.org>
+ * Copyright (c) 2012 H.J. Lu <hongjiu.lu@intel.com>
+ * Copyright (c) 2005-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "defs.h"
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include "stat.h"
+
+void
+print_struct_stat(struct tcb *tcp, const struct strace_stat *const st)
+{
+	tprints("{");
+	if (!abbrev(tcp)) {
+		tprintf("st_dev=makedev(%u, %u), st_ino=%llu, st_mode=",
+			(unsigned int) major(st->dev),
+			(unsigned int) minor(st->dev),
+			st->ino);
+		print_symbolic_mode_t(st->mode);
+		tprintf(", st_nlink=%llu, st_uid=%llu, st_gid=%llu",
+			st->nlink, st->uid, st->gid);
+		tprintf(", st_blksize=%llu", st->blksize);
+		tprintf(", st_blocks=%llu", st->blocks);
+	} else {
+		tprints("st_mode=");
+		print_symbolic_mode_t(st->mode);
+	}
+
+	switch (st->mode & S_IFMT) {
+	case S_IFCHR: case S_IFBLK:
+		tprintf(", st_rdev=makedev(%u, %u)",
+			(unsigned int) major(st->rdev),
+			(unsigned int) minor(st->rdev));
+		break;
+	default:
+		tprintf(", st_size=%llu", st->size);
+		break;
+	}
+
+	if (!abbrev(tcp)) {
+		tprints(", st_atime=");
+		tprints(sprinttime(st->atime));
+		if (st->atime_nsec)
+			tprintf(".%09llu", st->atime_nsec);
+		tprints(", st_mtime=");
+		tprints(sprinttime(st->mtime));
+		if (st->mtime_nsec)
+			tprintf(".%09llu", st->mtime_nsec);
+		tprints(", st_ctime=");
+		tprints(sprinttime(st->ctime));
+		if (st->ctime_nsec)
+			tprintf(".%09llu", st->ctime_nsec);
+	} else {
+		tprints(", ...");
+	}
+	tprints("}");
+}
diff --git a/printers.h b/printers.h
index 07ba17d..5e3c84b 100644
--- a/printers.h
+++ b/printers.h
@@ -1,4 +1,4 @@
-/* Generated by Makefile from block.c.mpers.i btrfs.c.mpers.i dirent.c.mpers.i evdev.c.mpers.i fetch_seccomp_fprog.c.mpers.i fetch_struct_flock.c.mpers.i fetch_struct_mmsghdr.c.mpers.i fetch_struct_msghdr.c.mpers.i fetch_struct_statfs.c.mpers.i hdio.c.mpers.i ipc_msgctl.c.mpers.i ipc_shmctl.c.mpers.i mtd.c.mpers.i print_mq_attr.c.mpers.i print_msgbuf.c.mpers.i print_sigevent.c.mpers.i print_time.c.mpers.i print_timex.c.mpers.i printrusage.c.mpers.i printsiginfo.c.mpers.i rtc.c.mpers.i sigaltstack.c.mpers.i sysinfo.c.mpers.i times.c.mpers.i utime.c.mpers.i v4l2.c.mpers.i; do not edit. */
+/* Generated by Makefile from block.c.mpers.i btrfs.c.mpers.i dirent.c.mpers.i evdev.c.mpers.i fetch_seccomp_fprog.c.mpers.i fetch_struct_flock.c.mpers.i fetch_struct_mmsghdr.c.mpers.i fetch_struct_msghdr.c.mpers.i fetch_struct_stat.c.mpers.i fetch_struct_stat64.c.mpers.i fetch_struct_statfs.c.mpers.i hdio.c.mpers.i ipc_msgctl.c.mpers.i ipc_shmctl.c.mpers.i mtd.c.mpers.i print_mq_attr.c.mpers.i print_msgbuf.c.mpers.i print_sigevent.c.mpers.i print_time.c.mpers.i print_timex.c.mpers.i printrusage.c.mpers.i printsiginfo.c.mpers.i rtc.c.mpers.i sigaltstack.c.mpers.i sysinfo.c.mpers.i times.c.mpers.i utime.c.mpers.i v4l2.c.mpers.i; do not edit. */
 typedef struct {
  int (*block_ioctl)(struct tcb *tcp, const unsigned int code, const long arg);
 #define block_ioctl MPERS_PRINTER_NAME(block_ioctl)
@@ -27,6 +27,12 @@
  int (*fetch_struct_msghdr)(struct tcb *tcp, const unsigned long addr, void *p);
 #define fetch_struct_msghdr MPERS_PRINTER_NAME(fetch_struct_msghdr)
 
+ _Bool (*fetch_struct_stat)(struct tcb *tcp, const unsigned long addr, struct strace_stat *const dst);
+#define fetch_struct_stat MPERS_PRINTER_NAME(fetch_struct_stat)
+
+ _Bool (*fetch_struct_stat64)(struct tcb *tcp, const unsigned long addr, struct strace_stat *const dst);
+#define fetch_struct_stat64 MPERS_PRINTER_NAME(fetch_struct_stat64)
+
  _Bool (*fetch_struct_statfs)(struct tcb *tcp, const long addr, struct strace_statfs *p);
 #define fetch_struct_statfs MPERS_PRINTER_NAME(fetch_struct_statfs)
 
diff --git a/printmode.c b/printmode.c
index ad87507..1babed6 100644
--- a/printmode.c
+++ b/printmode.c
@@ -36,27 +36,38 @@
 
 #include "xlat/modetypes.h"
 
-const char *
-sprintmode(unsigned int mode)
+void
+print_symbolic_mode_t(const unsigned int mode)
 {
-	static char buf[sizeof("S_IFSOCK|S_ISUID|S_ISGID|S_ISVTX|%o")
-			+ sizeof(int)*3
-			+ /*paranoia:*/ 8];
-	const char *s;
+	const char *ifmt;
 
-	if ((mode & S_IFMT) == 0)
-		s = "";
-	else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
-		sprintf(buf, "%#o", mode);
-		return buf;
+	if (mode & S_IFMT) {
+		ifmt = xlookup(modetypes, mode & S_IFMT);
+		if (!ifmt) {
+			tprintf("%#03o", mode);
+			return;
+		}
+	} else {
+		ifmt = NULL;
 	}
-	s = buf + sprintf(buf, "%s%s%s%s", s,
-		(mode & S_ISUID) ? "|S_ISUID" : "",
-		(mode & S_ISGID) ? "|S_ISGID" : "",
-		(mode & S_ISVTX) ? "|S_ISVTX" : "");
-	mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
-	if (mode)
-		sprintf((char*)s, "|%#o", mode);
-	s = (*buf == '|') ? buf + 1 : buf;
-	return *s ? s : "0";
+
+	tprintf("%s%s%s%s%s%#03o",
+		ifmt ? ifmt : "",
+		ifmt ? "|" : "",
+		(mode & S_ISUID) ? "S_ISUID|" : "",
+		(mode & S_ISGID) ? "S_ISGID|" : "",
+		(mode & S_ISVTX) ? "S_ISVTX|" : "",
+		mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX));
+}
+
+void
+print_numeric_umode_t(const unsigned short mode)
+{
+	tprintf("%#03ho", mode);
+}
+
+void
+print_numeric_long_umask(const unsigned long mode)
+{
+	tprintf("%#03lo", mode);
 }
diff --git a/printrusage.c b/printrusage.c
index acf67eb..548af82 100644
--- a/printrusage.c
+++ b/printrusage.c
@@ -45,27 +45,27 @@
 		return;
 
 	tprintf("{ru_utime={%llu, %llu}, ru_stime={%llu, %llu}, ",
-		widen_to_ull(ru.ru_utime.tv_sec),
-		widen_to_ull(ru.ru_utime.tv_usec),
-		widen_to_ull(ru.ru_stime.tv_sec),
-		widen_to_ull(ru.ru_stime.tv_usec));
+		zero_extend_signed_to_ull(ru.ru_utime.tv_sec),
+		zero_extend_signed_to_ull(ru.ru_utime.tv_usec),
+		zero_extend_signed_to_ull(ru.ru_stime.tv_sec),
+		zero_extend_signed_to_ull(ru.ru_stime.tv_usec));
 	if (abbrev(tcp))
 		tprints("...}");
 	else {
-		tprintf("ru_maxrss=%llu, ", widen_to_ull(ru.ru_maxrss));
-		tprintf("ru_ixrss=%llu, ", widen_to_ull(ru.ru_ixrss));
-		tprintf("ru_idrss=%llu, ", widen_to_ull(ru.ru_idrss));
-		tprintf("ru_isrss=%llu, ", widen_to_ull(ru.ru_isrss));
-		tprintf("ru_minflt=%llu, ", widen_to_ull(ru.ru_minflt));
-		tprintf("ru_majflt=%llu, ", widen_to_ull(ru.ru_majflt));
-		tprintf("ru_nswap=%llu, ", widen_to_ull(ru.ru_nswap));
-		tprintf("ru_inblock=%llu, ", widen_to_ull(ru.ru_inblock));
-		tprintf("ru_oublock=%llu, ", widen_to_ull(ru.ru_oublock));
-		tprintf("ru_msgsnd=%llu, ", widen_to_ull(ru.ru_msgsnd));
-		tprintf("ru_msgrcv=%llu, ", widen_to_ull(ru.ru_msgrcv));
-		tprintf("ru_nsignals=%llu, ", widen_to_ull(ru.ru_nsignals));
-		tprintf("ru_nvcsw=%llu, ", widen_to_ull(ru.ru_nvcsw));
-		tprintf("ru_nivcsw=%llu}", widen_to_ull(ru.ru_nivcsw));
+		tprintf("ru_maxrss=%llu, ", zero_extend_signed_to_ull(ru.ru_maxrss));
+		tprintf("ru_ixrss=%llu, ", zero_extend_signed_to_ull(ru.ru_ixrss));
+		tprintf("ru_idrss=%llu, ", zero_extend_signed_to_ull(ru.ru_idrss));
+		tprintf("ru_isrss=%llu, ", zero_extend_signed_to_ull(ru.ru_isrss));
+		tprintf("ru_minflt=%llu, ", zero_extend_signed_to_ull(ru.ru_minflt));
+		tprintf("ru_majflt=%llu, ", zero_extend_signed_to_ull(ru.ru_majflt));
+		tprintf("ru_nswap=%llu, ", zero_extend_signed_to_ull(ru.ru_nswap));
+		tprintf("ru_inblock=%llu, ", zero_extend_signed_to_ull(ru.ru_inblock));
+		tprintf("ru_oublock=%llu, ", zero_extend_signed_to_ull(ru.ru_oublock));
+		tprintf("ru_msgsnd=%llu, ", zero_extend_signed_to_ull(ru.ru_msgsnd));
+		tprintf("ru_msgrcv=%llu, ", zero_extend_signed_to_ull(ru.ru_msgrcv));
+		tprintf("ru_nsignals=%llu, ", zero_extend_signed_to_ull(ru.ru_nsignals));
+		tprintf("ru_nvcsw=%llu, ", zero_extend_signed_to_ull(ru.ru_nvcsw));
+		tprintf("ru_nivcsw=%llu}", zero_extend_signed_to_ull(ru.ru_nivcsw));
 	}
 }
 
diff --git a/printsiginfo.c b/printsiginfo.c
index 699460f..1f4a825 100644
--- a/printsiginfo.c
+++ b/printsiginfo.c
@@ -172,8 +172,8 @@
 			else
 				printsignal(sip->si_status);
 			tprintf(", si_utime=%llu, si_stime=%llu",
-				widen_to_ull(sip->si_utime),
-				widen_to_ull(sip->si_stime));
+				zero_extend_signed_to_ull(sip->si_utime),
+				zero_extend_signed_to_ull(sip->si_stime));
 			break;
 		case SIGILL: case SIGFPE:
 		case SIGSEGV: case SIGBUS:
diff --git a/printsiginfo.h b/printsiginfo.h
index cb2d99d..7ad7238 100644
--- a/printsiginfo.h
+++ b/printsiginfo.h
@@ -1 +1,6 @@
+#ifndef STRACE_PRINTSIGINFO_H
+#define STRACE_PRINTSIGINFO_H
+
 extern void printsiginfo(const siginfo_t *);
+
+#endif /* !STRACE_PRINTSIGINFO_H */
diff --git a/printstat.h b/printstat.h
deleted file mode 100644
index 5bf745c..0000000
--- a/printstat.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 1999-2003 Ulrich Drepper <drepper@redhat.com>
- * Copyright (c) 2004 David S. Miller <davem@nuts.davemloft.net>
- * Copyright (c) 2003-2005 Roland McGrath <roland@redhat.com>
- * Copyright (c) 2007 Jan Kratochvil <jan.kratochvil@redhat.com>
- * Copyright (c) 2009 Denys Vlasenko <dvlasenk@redhat.com>
- * Copyright (c) 2009-2010 Andreas Schwab <schwab@linux-m68k.org>
- * Copyright (c) 2012 H.J. Lu <hongjiu.lu@intel.com>
- * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DO_PRINTSTAT
-# define DO_PRINTSTAT do_printstat
-#endif
-
-#ifndef STRUCT_STAT
-# define STRUCT_STAT struct stat
-#endif
-
-#ifndef STAT_MAJOR
-# define STAT_MAJOR(x) major(x)
-#endif
-
-#ifndef STAT_MINOR
-# define STAT_MINOR(x) minor(x)
-#endif
-
-static void
-DO_PRINTSTAT(struct tcb *tcp, const STRUCT_STAT *statbuf)
-{
-	if (!abbrev(tcp)) {
-		tprintf("{st_dev=makedev(%u, %u), st_ino=%llu, st_mode=%s, ",
-			(unsigned int) STAT_MAJOR(statbuf->st_dev),
-			(unsigned int) STAT_MINOR(statbuf->st_dev),
-			widen_to_ull(statbuf->st_ino),
-			sprintmode(statbuf->st_mode));
-		tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
-			(unsigned int) statbuf->st_nlink,
-			(unsigned int) statbuf->st_uid,
-			(unsigned int) statbuf->st_gid);
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
-		tprintf("st_blksize=%u, ", (unsigned int) statbuf->st_blksize);
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
-		tprintf("st_blocks=%llu, ", widen_to_ull(statbuf->st_blocks));
-#endif
-	} else {
-		tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
-	}
-
-	switch (statbuf->st_mode & S_IFMT) {
-	case S_IFCHR: case S_IFBLK:
-#ifdef HAVE_STRUCT_STAT_ST_RDEV
-		tprintf("st_rdev=makedev(%u, %u), ",
-			(unsigned int) STAT_MAJOR(statbuf->st_rdev),
-			(unsigned int) STAT_MINOR(statbuf->st_rdev));
-#else /* !HAVE_STRUCT_STAT_ST_RDEV */
-		tprintf("st_size=makedev(%u, %u), ",
-			(unsigned int) STAT_MAJOR(statbuf->st_size),
-			(unsigned int) STAT_MINOR(statbuf->st_size));
-#endif /* !HAVE_STRUCT_STAT_ST_RDEV */
-		break;
-	default:
-		tprintf("st_size=%llu, ", widen_to_ull(statbuf->st_size));
-		break;
-	}
-
-	if (!abbrev(tcp)) {
-		const bool cast = sizeof(statbuf->st_atime) == sizeof(int);
-
-		tprints("st_atime=");
-		tprints(sprinttime(cast ? (time_t) (int) statbuf->st_atime:
-					  (time_t) statbuf->st_atime));
-#ifdef HAVE_STRUCT_STAT_ST_ATIME_NSEC
-		if (statbuf->st_atime_nsec)
-			tprintf(".%09lu", (unsigned long) statbuf->st_atime_nsec);
-#endif
-		tprints(", st_mtime=");
-		tprints(sprinttime(cast ? (time_t) (int) statbuf->st_mtime:
-					  (time_t) statbuf->st_mtime));
-#ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
-		if (statbuf->st_mtime_nsec)
-			tprintf(".%09lu", (unsigned long) statbuf->st_mtime_nsec);
-#endif
-		tprints(", st_ctime=");
-		tprints(sprinttime(cast ? (time_t) (int) statbuf->st_ctime:
-					  (time_t) statbuf->st_ctime));
-#ifdef HAVE_STRUCT_STAT_ST_CTIME_NSEC
-		if (statbuf->st_ctime_nsec)
-			tprintf(".%09lu", (unsigned long) statbuf->st_ctime_nsec);
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_FLAGS
-		tprintf(", st_flags=%u", (unsigned int) statbuf->st_flags);
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_FSTYPE
-		tprintf(", st_fstype=%.*s",
-			(int) sizeof statbuf->st_fstype, statbuf->st_fstype);
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_GEN
-		tprintf(", st_gen=%u", (unsigned int) statbuf->st_gen);
-#endif
-		tprints("}");
-	} else {
-		tprints("...}");
-	}
-}
-
-#undef STAT_MINOR
-#undef STAT_MAJOR
-#undef STRUCT_STAT
-#undef DO_PRINTSTAT
diff --git a/ptrace.h b/ptrace.h
index 2e7d5e3..ddb46cb 100644
--- a/ptrace.h
+++ b/ptrace.h
@@ -33,6 +33,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef STRACE_PTRACE_H
+#define STRACE_PTRACE_H
+
 #ifdef NEED_PTRACE_PROTOTYPE_WORKAROUND
 # define ptrace xptrace
 # include <sys/ptrace.h>
@@ -64,6 +67,16 @@
 # undef ptrace_peeksiginfo_args
 #endif
 
+#if defined(SPARC) || defined(SPARC64)
+/*
+ * SPARC has a different PTRACE_DETACH value correctly defined in sys/ptrace.h,
+ * but linux/ptrace.h clobbers it with the standard one.  PTRACE_SUNDETACH is
+ * also defined to the correct value by sys/ptrace.h, so use that instead.
+ */
+# undef PTRACE_DETACH
+# define PTRACE_DETACH PTRACE_SUNDETACH
+#endif
+
 #ifndef PTRACE_EVENT_FORK
 # define PTRACE_EVENT_FORK	1
 #endif
@@ -172,3 +185,5 @@
 #if !HAVE_DECL_PTRACE_POKEUSER
 # define PTRACE_POKEUSER PTRACE_POKEUSR
 #endif
+
+#endif /* !STRACE_PTRACE_H */
diff --git a/quota.c b/quota.c
index 0a388b2..7dd01f9 100644
--- a/quota.c
+++ b/quota.c
@@ -49,6 +49,12 @@
 #include "xlat/if_dqinfo_flags.h"
 #include "xlat/if_dqinfo_valid.h"
 
+/*
+ * We add attribute packed due to the fact that the structure is 8-byte aligned
+ * on 64-bit systems and therefore has additional 4 bytes of padding, which
+ * leads to problems when it is used on 32-bit tracee which does not have such
+ * padding.
+ */
 struct if_dqblk
 {
 	uint64_t dqb_bhardlimit;
@@ -60,7 +66,7 @@
 	uint64_t dqb_btime;
 	uint64_t dqb_itime;
 	uint32_t dqb_valid;
-};
+} ATTRIBUTE_PACKED;
 
 struct if_nextdqblk {
 	uint64_t dqb_bhardlimit;
@@ -75,30 +81,6 @@
 	uint32_t dqb_id;
 };
 
-struct v1_dqblk
-{
-	uint32_t dqb_bhardlimit;	/* absolute limit on disk blks alloc */
-	uint32_t dqb_bsoftlimit;	/* preferred limit on disk blks */
-	uint32_t dqb_curblocks;		/* current block count */
-	uint32_t dqb_ihardlimit;	/* maximum # allocated inodes */
-	uint32_t dqb_isoftlimit;	/* preferred inode limit */
-	uint32_t dqb_curinodes;		/* current # allocated inodes */
-	time_t  dqb_btime;		/* time limit for excessive disk use */
-	time_t  dqb_itime;		/* time limit for excessive files */
-};
-
-struct v2_dqblk
-{
-	unsigned int dqb_ihardlimit;
-	unsigned int dqb_isoftlimit;
-	unsigned int dqb_curinodes;
-	unsigned int dqb_bhardlimit;
-	unsigned int dqb_bsoftlimit;
-	uint64_t dqb_curspace;
-	time_t  dqb_btime;
-	time_t  dqb_itime;
-};
-
 struct xfs_dqblk
 {
 	int8_t  d_version;		/* version of this structure */
@@ -133,41 +115,6 @@
 	uint32_t dqi_valid;
 };
 
-struct v2_dqinfo
-{
-	unsigned int dqi_bgrace;
-	unsigned int dqi_igrace;
-	unsigned int dqi_flags;
-	unsigned int dqi_blocks;
-	unsigned int dqi_free_blk;
-	unsigned int dqi_free_entry;
-};
-
-struct v1_dqstats
-{
-	uint32_t lookups;
-	uint32_t drops;
-	uint32_t reads;
-	uint32_t writes;
-	uint32_t cache_hits;
-	uint32_t allocated_dquots;
-	uint32_t free_dquots;
-	uint32_t syncs;
-};
-
-struct v2_dqstats
-{
-	uint32_t lookups;
-	uint32_t drops;
-	uint32_t reads;
-	uint32_t writes;
-	uint32_t cache_hits;
-	uint32_t allocated_dquots;
-	uint32_t free_dquots;
-	uint32_t syncs;
-	uint32_t version;
-};
-
 typedef struct fs_qfilestat
 {
 	uint64_t qfs_ino;	/* inode number */
@@ -211,297 +158,300 @@
 	uint64_t qs_pad2[8];
 };
 
+#define PRINT_FIELD_D(prefix, where, field)	\
+	tprintf("%s%s=%lld", (prefix), #field,	\
+		sign_extend_unsigned_to_ll((where).field))
+
+#define PRINT_FIELD_U(prefix, where, field)	\
+	tprintf("%s%s=%llu", (prefix), #field,	\
+		zero_extend_signed_to_ull((where).field))
+
+#define PRINT_FIELD_X(prefix, where, field)	\
+	tprintf("%s%s=%#llx", (prefix), #field,	\
+		zero_extend_signed_to_ull((where).field))
+
 static int
-decode_cmd_data(struct tcb *tcp, uint32_t cmd, unsigned long data)
+decode_cmd_data(struct tcb *tcp, uint32_t id, uint32_t cmd, unsigned long data)
 {
 	switch (cmd) {
-		case Q_GETQUOTA:
-			if (entering(tcp))
-				return 0;
-		case Q_SETQUOTA:
-		{
-			struct if_dqblk dq;
+	case Q_QUOTAOFF:
+	case Q_SYNC:
+	case Q_XQUOTASYNC:
+		break;
+	case Q_QUOTAON:
+		tprints(", ");
+		printxval(quota_formats, id, "QFMT_VFS_???");
+		tprints(", ");
+		printpath(tcp, data);
+		break;
+	case Q_GETQUOTA:
+		if (entering(tcp)) {
+			printuid(", ", id);
+			tprints(", ");
 
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{bhardlimit=%" PRIu64 ", ", dq.dqb_bhardlimit);
-			tprintf("bsoftlimit=%" PRIu64 ", ", dq.dqb_bsoftlimit);
-			tprintf("curspace=%" PRIu64 ", ", dq.dqb_curspace);
-			tprintf("ihardlimit=%" PRIu64 ", ", dq.dqb_ihardlimit);
-			tprintf("isoftlimit=%" PRIu64 ", ", dq.dqb_isoftlimit);
-			tprintf("curinodes=%" PRIu64 ", ", dq.dqb_curinodes);
-			if (!abbrev(tcp)) {
-				tprintf("btime=%" PRIu64 ", ", dq.dqb_btime);
-				tprintf("itime=%" PRIu64 ", ", dq.dqb_itime);
-				tprints("valid=");
-				printflags(if_dqblk_valid,
-					   dq.dqb_valid, "QIF_???");
-				tprints("}");
-			} else
-				tprints("...}");
-			break;
+			return 0;
 		}
-		case Q_GETNEXTQUOTA:
-		{
-			struct if_nextdqblk dq;
 
-			if (entering(tcp))
-				return 0;
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{bhardlimit=%" PRIu64 ", ", dq.dqb_bhardlimit);
-			tprintf("bsoftlimit=%" PRIu64 ", ", dq.dqb_bsoftlimit);
-			tprintf("curspace=%" PRIu64 ", ", dq.dqb_curspace);
-			tprintf("ihardlimit=%" PRIu64 ", ", dq.dqb_ihardlimit);
-			tprintf("isoftlimit=%" PRIu64 ", ", dq.dqb_isoftlimit);
-			tprintf("curinodes=%" PRIu64 ", ", dq.dqb_curinodes);
-			if (!abbrev(tcp)) {
-				tprintf("btime=%" PRIu64 ", ", dq.dqb_btime);
-				tprintf("itime=%" PRIu64 ", ", dq.dqb_itime);
-				tprints("valid=");
-				printflags(if_dqblk_valid,
-					   dq.dqb_valid, "QIF_???");
-				tprintf(", id=%u}", dq.dqb_id);
-			} else
-				tprintf("id=%u, ...}", dq.dqb_id);
-			break;
+		/* Fall-through */
+	case Q_SETQUOTA:
+	{
+		struct if_dqblk dq;
+
+		if (entering(tcp)) {
+			printuid(", ", id);
+			tprints(", ");
 		}
-		case Q_V1_GETQUOTA:
-			if (entering(tcp))
-				return 0;
-		case Q_V1_SETQUOTA:
-		{
-			struct v1_dqblk dq;
 
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{bhardlimit=%u, ", dq.dqb_bhardlimit);
-			tprintf("bsoftlimit=%u, ", dq.dqb_bsoftlimit);
-			tprintf("curblocks=%u, ", dq.dqb_curblocks);
-			tprintf("ihardlimit=%u, ", dq.dqb_ihardlimit);
-			tprintf("isoftlimit=%u, ", dq.dqb_isoftlimit);
-			tprintf("curinodes=%u, ", dq.dqb_curinodes);
-			tprintf("btime=%lu, ", (long) dq.dqb_btime);
-			tprintf("itime=%lu}", (long) dq.dqb_itime);
+		if (umove_or_printaddr(tcp, data, &dq))
 			break;
+		PRINT_FIELD_U("{", dq, dqb_bhardlimit);
+		PRINT_FIELD_U(", ", dq, dqb_bsoftlimit);
+		PRINT_FIELD_U(", ", dq, dqb_curspace);
+		PRINT_FIELD_U(", ", dq, dqb_ihardlimit);
+		PRINT_FIELD_U(", ", dq, dqb_isoftlimit);
+		PRINT_FIELD_U(", ", dq, dqb_curinodes);
+		if (!abbrev(tcp)) {
+			PRINT_FIELD_U(", ", dq, dqb_btime);
+			PRINT_FIELD_U(", ", dq, dqb_itime);
+			tprints(", dqb_valid=");
+			printflags(if_dqblk_valid,
+				   dq.dqb_valid, "QIF_???");
+		} else {
+			tprints(", ...");
 		}
-		case Q_V2_GETQUOTA:
-			if (entering(tcp))
-				return 0;
-		case Q_V2_SETQUOTA:
-		{
-			struct v2_dqblk dq;
+		tprints("}");
+		break;
+	}
+	case Q_GETNEXTQUOTA:
+	{
+		struct if_nextdqblk dq;
 
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{ihardlimit=%u, ", dq.dqb_ihardlimit);
-			tprintf("isoftlimit=%u, ", dq.dqb_isoftlimit);
-			tprintf("curinodes=%u, ", dq.dqb_curinodes);
-			tprintf("bhardlimit=%u, ", dq.dqb_bhardlimit);
-			tprintf("bsoftlimit=%u, ", dq.dqb_bsoftlimit);
-			tprintf("curspace=%" PRIu64 ", ", dq.dqb_curspace);
-			tprintf("btime=%lu, ", (long) dq.dqb_btime);
-			tprintf("itime=%lu}", (long) dq.dqb_itime);
+		if (entering(tcp)) {
+			printuid(", ", id);
+			tprints(", ");
+
+			return 0;
+		}
+
+		if (umove_or_printaddr(tcp, data, &dq))
 			break;
+		PRINT_FIELD_U("{", dq, dqb_bhardlimit);
+		PRINT_FIELD_U(", ", dq, dqb_bsoftlimit);
+		PRINT_FIELD_U(", ", dq, dqb_curspace);
+		PRINT_FIELD_U(", ", dq, dqb_ihardlimit);
+		PRINT_FIELD_U(", ", dq, dqb_isoftlimit);
+		PRINT_FIELD_U(", ", dq, dqb_curinodes);
+		if (!abbrev(tcp)) {
+			PRINT_FIELD_U(", ", dq, dqb_btime);
+			PRINT_FIELD_U(", ", dq, dqb_itime);
+			tprints(", dqb_valid=");
+			printflags(if_dqblk_valid,
+				   dq.dqb_valid, "QIF_???");
+			PRINT_FIELD_U(", ", dq, dqb_id);
+		} else {
+			PRINT_FIELD_U(", ", dq, dqb_id);
+			tprints(", ...");
 		}
-		case Q_XGETQUOTA:
-		case Q_XGETNEXTQUOTA:
-			if (entering(tcp))
-				return 0;
-		case Q_XSETQLIM:
-		{
-			struct xfs_dqblk dq;
+		tprints("}");
+		break;
+	}
+	case Q_XGETQUOTA:
+	case Q_XGETNEXTQUOTA:
+		if (entering(tcp)) {
+			printuid(", ", id);
+			tprints(", ");
 
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{version=%d, ", dq.d_version);
-			tprints("flags=");
-			printflags(xfs_dqblk_flags,
-				   (uint8_t) dq.d_flags, "XFS_???_QUOTA");
-			tprintf(", fieldmask=%#x, ", dq.d_fieldmask);
-			tprintf("id=%u, ", dq.d_id);
-			tprintf("blk_hardlimit=%" PRIu64 ", ", dq.d_blk_hardlimit);
-			tprintf("blk_softlimit=%" PRIu64 ", ", dq.d_blk_softlimit);
-			tprintf("ino_hardlimit=%" PRIu64 ", ", dq.d_ino_hardlimit);
-			tprintf("ino_softlimit=%" PRIu64 ", ", dq.d_ino_softlimit);
-			tprintf("bcount=%" PRIu64 ", ", dq.d_bcount);
-			tprintf("icount=%" PRIu64 ", ", dq.d_icount);
-			if (!abbrev(tcp)) {
-				tprintf("itimer=%d, ", dq.d_itimer);
-				tprintf("btimer=%d, ", dq.d_btimer);
-				tprintf("iwarns=%u, ", dq.d_iwarns);
-				tprintf("bwarns=%u, ", dq.d_bwarns);
-				tprintf("rtbcount=%" PRIu64 ", ", dq.d_rtbcount);
-				tprintf("rtbtimer=%d, ", dq.d_rtbtimer);
-				tprintf("rtbwarns=%u}", dq.d_rtbwarns);
-			} else
-				tprints("...}");
+			return 0;
+		}
+
+		/* Fall-through */
+	case Q_XSETQLIM:
+	{
+		struct xfs_dqblk dq;
+
+		if (entering(tcp)) {
+			printuid(", ", id);
+			tprints(", ");
+		}
+
+		if (umove_or_printaddr(tcp, data, &dq))
 			break;
+		PRINT_FIELD_D("{", dq, d_version);
+		tprints(", d_flags=");
+		printflags(xfs_dqblk_flags,
+			   (uint8_t) dq.d_flags, "XFS_???_QUOTA");
+		PRINT_FIELD_X(", ", dq, d_fieldmask);
+		PRINT_FIELD_U(", ", dq, d_id);
+		PRINT_FIELD_U(", ", dq, d_blk_hardlimit);
+		PRINT_FIELD_U(", ", dq, d_blk_softlimit);
+		PRINT_FIELD_U(", ", dq, d_ino_hardlimit);
+		PRINT_FIELD_U(", ", dq, d_ino_softlimit);
+		PRINT_FIELD_U(", ", dq, d_bcount);
+		PRINT_FIELD_U(", ", dq, d_icount);
+		if (!abbrev(tcp)) {
+			PRINT_FIELD_D(", ", dq, d_itimer);
+			PRINT_FIELD_D(", ", dq, d_btimer);
+			PRINT_FIELD_U(", ", dq, d_iwarns);
+			PRINT_FIELD_U(", ", dq, d_bwarns);
+			PRINT_FIELD_U(", ", dq, d_rtb_hardlimit);
+			PRINT_FIELD_U(", ", dq, d_rtb_softlimit);
+			PRINT_FIELD_U(", ", dq, d_rtbcount);
+			PRINT_FIELD_D(", ", dq, d_rtbtimer);
+			PRINT_FIELD_U(", ", dq, d_rtbwarns);
+		} else {
+			tprints(", ...");
 		}
-		case Q_GETFMT:
-		{
-			uint32_t fmt;
+		tprints("}");
+		break;
+	}
+	case Q_GETFMT:
+	{
+		uint32_t fmt;
 
-			if (entering(tcp))
-				return 0;
-			if (umove_or_printaddr(tcp, data, &fmt))
-				break;
-			tprints("[");
-			printxval(quota_formats, fmt, "QFMT_VFS_???");
-			tprints("]");
+		if (entering(tcp)) {
+			tprints(", ");
+
+			return 0;
+		}
+
+		if (umove_or_printaddr(tcp, data, &fmt))
 			break;
-		}
-		case Q_GETINFO:
-			if (entering(tcp))
-				return 0;
-		case Q_SETINFO:
-		{
-			struct if_dqinfo dq;
+		tprints("[");
+		printxval(quota_formats, fmt, "QFMT_VFS_???");
+		tprints("]");
+		break;
+	}
+	case Q_GETINFO:
+		if (entering(tcp)) {
+			tprints(", ");
 
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{bgrace=%" PRIu64 ", ", dq.dqi_bgrace);
-			tprintf("igrace=%" PRIu64 ", ", dq.dqi_igrace);
-			tprints("flags=");
-			printflags(if_dqinfo_flags, dq.dqi_flags, "DQF_???");
-			tprints(", valid=");
-			printflags(if_dqinfo_valid, dq.dqi_valid, "IIF_???");
-			tprints("}");
+			return 0;
+		}
+
+		/* Fall-through */
+	case Q_SETINFO:
+	{
+		struct if_dqinfo dq;
+
+		if (entering(tcp))
+			tprints(", ");
+
+		if (umove_or_printaddr(tcp, data, &dq))
 			break;
-		}
-		case Q_V2_GETINFO:
-			if (entering(tcp))
-				return 0;
-		case Q_V2_SETINFO:
-		{
-			struct v2_dqinfo dq;
+		PRINT_FIELD_U("{", dq, dqi_bgrace);
+		PRINT_FIELD_U(", ", dq, dqi_igrace);
+		tprints(", dqi_flags=");
+		printflags(if_dqinfo_flags, dq.dqi_flags, "DQF_???");
+		tprints(", dqi_valid=");
+		printflags(if_dqinfo_valid, dq.dqi_valid, "IIF_???");
+		tprints("}");
+		break;
+	}
+	case Q_XGETQSTAT:
+	{
+		struct xfs_dqstats dq;
 
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{bgrace=%u, ", dq.dqi_bgrace);
-			tprintf("igrace=%u, ", dq.dqi_igrace);
-			tprints("flags=");
-			printflags(if_dqinfo_flags, dq.dqi_flags, "DQF_???");
-			tprintf(", blocks=%u, ", dq.dqi_blocks);
-			tprintf("free_blk=%u, ", dq.dqi_free_blk);
-			tprintf("free_entry=%u}", dq.dqi_free_entry);
+		if (entering(tcp)) {
+			tprints(", ");
+
+			return 0;
+		}
+
+		if (umove_or_printaddr(tcp, data, &dq))
 			break;
-		}
-		case Q_V1_GETSTATS:
-		{
-			struct v1_dqstats dq;
-
-			if (entering(tcp))
-				return 0;
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{lookups=%u, ", dq.lookups);
-			tprintf("drops=%u, ", dq.drops);
-			tprintf("reads=%u, ", dq.reads);
-			tprintf("writes=%u, ", dq.writes);
-			tprintf("cache_hits=%u, ", dq.cache_hits);
-			tprintf("allocated_dquots=%u, ", dq.allocated_dquots);
-			tprintf("free_dquots=%u, ", dq.free_dquots);
-			tprintf("syncs=%u}", dq.syncs);
-			break;
-		}
-		case Q_V2_GETSTATS:
-		{
-			struct v2_dqstats dq;
-
-			if (entering(tcp))
-				return 0;
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{lookups=%u, ", dq.lookups);
-			tprintf("drops=%u, ", dq.drops);
-			tprintf("reads=%u, ", dq.reads);
-			tprintf("writes=%u, ", dq.writes);
-			tprintf("cache_hits=%u, ", dq.cache_hits);
-			tprintf("allocated_dquots=%u, ", dq.allocated_dquots);
-			tprintf("free_dquots=%u, ", dq.free_dquots);
-			tprintf("syncs=%u, ", dq.syncs);
-			tprintf("version=%u}", dq.version);
-			break;
-		}
-		case Q_XGETQSTAT:
-		{
-			struct xfs_dqstats dq;
-
-			if (entering(tcp))
-				return 0;
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{version=%d, ", dq.qs_version);
-			if (abbrev(tcp)) {
-				tprints("...}");
-				break;
-			}
-			tprints("flags=");
+		PRINT_FIELD_D("{", dq, qs_version);
+		if (!abbrev(tcp)) {
+			tprints(", qs_flags=");
 			printflags(xfs_quota_flags,
 				   dq.qs_flags, "XFS_QUOTA_???");
-			tprintf(", incoredqs=%u, ", dq.qs_incoredqs);
-			tprintf("u_ino=%" PRIu64 ", ", dq.qs_uquota.qfs_ino);
-			tprintf("u_nblks=%" PRIu64 ", ", dq.qs_uquota.qfs_nblks);
-			tprintf("u_nextents=%u, ", dq.qs_uquota.qfs_nextents);
-			tprintf("g_ino=%" PRIu64 ", ", dq.qs_gquota.qfs_ino);
-			tprintf("g_nblks=%" PRIu64 ", ", dq.qs_gquota.qfs_nblks);
-			tprintf("g_nextents=%u, ", dq.qs_gquota.qfs_nextents);
-			tprintf("btimelimit=%d, ", dq.qs_btimelimit);
-			tprintf("itimelimit=%d, ", dq.qs_itimelimit);
-			tprintf("rtbtimelimit=%d, ", dq.qs_rtbtimelimit);
-			tprintf("bwarnlimit=%u, ", dq.qs_bwarnlimit);
-			tprintf("iwarnlimit=%u}", dq.qs_iwarnlimit);
-			break;
+			PRINT_FIELD_U(", ", dq, qs_incoredqs);
+			PRINT_FIELD_U(", qs_uquota={", dq.qs_uquota, qfs_ino);
+			PRINT_FIELD_U(", ", dq.qs_uquota, qfs_nblks);
+			PRINT_FIELD_U(", ", dq.qs_uquota, qfs_nextents);
+			PRINT_FIELD_U("}, qs_gquota={", dq.qs_gquota, qfs_ino);
+			PRINT_FIELD_U(", ", dq.qs_gquota, qfs_nblks);
+			PRINT_FIELD_U(", ", dq.qs_gquota, qfs_nextents);
+			PRINT_FIELD_D("}, ", dq, qs_btimelimit);
+			PRINT_FIELD_D(", ", dq, qs_itimelimit);
+			PRINT_FIELD_D(", ", dq, qs_rtbtimelimit);
+			PRINT_FIELD_U(", ", dq, qs_bwarnlimit);
+			PRINT_FIELD_U(", ", dq, qs_iwarnlimit);
+		} else {
+			tprints(", ...");
 		}
-		case Q_XGETQSTATV:
-		{
-			struct fs_quota_statv dq;
+		tprints("}");
+		break;
+	}
+	case Q_XGETQSTATV:
+	{
+		struct fs_quota_statv dq;
 
-			if (entering(tcp))
-				return 0;
-			if (umove_or_printaddr(tcp, data, &dq))
-				break;
-			tprintf("{version=%d, ", dq.qs_version);
-			if (abbrev(tcp)) {
-				tprints("...}");
-				break;
-			}
-			tprints("flags=");
+		if (entering(tcp)) {
+			tprints(", ");
+
+			return 0;
+		}
+
+		if (umove_or_printaddr(tcp, data, &dq))
+			break;
+		PRINT_FIELD_D("{", dq, qs_version);
+		if (!abbrev(tcp)) {
+			tprints(", qs_flags=");
 			printflags(xfs_quota_flags,
 				   dq.qs_flags, "XFS_QUOTA_???");
-			tprintf(", incoredqs=%u, ", dq.qs_incoredqs);
-			tprintf("u_ino=%" PRIu64 ", ", dq.qs_uquota.qfs_ino);
-			tprintf("u_nblks=%" PRIu64 ", ", dq.qs_uquota.qfs_nblks);
-			tprintf("u_nextents=%u, ", dq.qs_uquota.qfs_nextents);
-			tprintf("g_ino=%" PRIu64 ", ", dq.qs_gquota.qfs_ino);
-			tprintf("g_nblks=%" PRIu64 ", ", dq.qs_gquota.qfs_nblks);
-			tprintf("g_nextents=%u, ", dq.qs_gquota.qfs_nextents);
-			tprintf("p_ino=%" PRIu64 ", ", dq.qs_pquota.qfs_ino);
-			tprintf("p_nblks=%" PRIu64 ", ", dq.qs_pquota.qfs_nblks);
-			tprintf("p_nextents=%u, ", dq.qs_pquota.qfs_nextents);
-			tprintf("btimelimit=%d, ", dq.qs_btimelimit);
-			tprintf("itimelimit=%d, ", dq.qs_itimelimit);
-			tprintf("rtbtimelimit=%d, ", dq.qs_rtbtimelimit);
-			tprintf("bwarnlimit=%u, ", dq.qs_bwarnlimit);
-			tprintf("iwarnlimit=%u}", dq.qs_iwarnlimit);
-			break;
+			PRINT_FIELD_U(", ", dq, qs_incoredqs);
+			PRINT_FIELD_U(", qs_uquota={", dq.qs_uquota, qfs_ino);
+			PRINT_FIELD_U(", ", dq.qs_uquota, qfs_nblks);
+			PRINT_FIELD_U(", ", dq.qs_uquota, qfs_nextents);
+			PRINT_FIELD_U("}, qs_gquota={", dq.qs_gquota, qfs_ino);
+			PRINT_FIELD_U(", ", dq.qs_gquota, qfs_nblks);
+			PRINT_FIELD_U(", ", dq.qs_gquota, qfs_nextents);
+			PRINT_FIELD_U("}, qs_pquota={", dq.qs_pquota, qfs_ino);
+			PRINT_FIELD_U(", ", dq.qs_pquota, qfs_nblks);
+			PRINT_FIELD_U(", ", dq.qs_pquota, qfs_nextents);
+			PRINT_FIELD_D("}, ", dq, qs_btimelimit);
+			PRINT_FIELD_D(", ", dq, qs_itimelimit);
+			PRINT_FIELD_D(", ", dq, qs_rtbtimelimit);
+			PRINT_FIELD_U(", ", dq, qs_bwarnlimit);
+			PRINT_FIELD_U(", ", dq, qs_iwarnlimit);
+		} else {
+			tprints(", ...");
 		}
-		case Q_XQUOTAON:
-		case Q_XQUOTAOFF:
-		{
-			uint32_t flag;
+		tprints("}");
+		break;
+	}
+	case Q_XQUOTAON:
+	case Q_XQUOTAOFF:
+	{
+		uint32_t flag;
 
-			if (umove_or_printaddr(tcp, data, &flag))
-				break;
-			tprints("[");
-			printflags(xfs_quota_flags, flag, "XFS_QUOTA_???");
-			tprints("]");
+		tprints(", ");
+
+		if (umove_or_printaddr(tcp, data, &flag))
 			break;
-		}
-		default:
-			printaddr(data);
+		tprints("[");
+		printflags(xfs_quota_flags, flag, "XFS_QUOTA_???");
+		tprints("]");
+		break;
+	}
+	case Q_XQUOTARM:
+	{
+		uint32_t flag;
+
+		tprints(", ");
+
+		if (umove_or_printaddr(tcp, data, &flag))
 			break;
+		tprints("[");
+		printflags(xfs_dqblk_flags, flag, "XFS_???_QUOTA");
+		tprints("]");
+		break;
+	}
+	default:
+		printuid(", ", id);
+		tprints(", ");
+		printaddr(data);
+		break;
 	}
 	return RVAL_DECODED;
 }
@@ -520,21 +470,12 @@
 	uint32_t id = tcp->u_arg[2];
 
 	if (entering(tcp)) {
+		tprints("QCMD(");
 		printxval(quotacmds, cmd, "Q_???");
-		tprints("|");
+		tprints(", ");
 		printxval(quotatypes, type, "???QUOTA");
-		tprints(", ");
+		tprints("), ");
 		printpath(tcp, tcp->u_arg[1]);
-		tprints(", ");
-		switch (cmd) {
-			case Q_QUOTAON:
-			case Q_V1_QUOTAON:
-				printxval(quota_formats, id, "QFMT_VFS_???");
-				tprints(", ");
-				printpath(tcp, tcp->u_arg[3]);
-				return RVAL_DECODED;
-		}
-		tprintf("%u, ", id);
 	}
-	return decode_cmd_data(tcp, cmd, tcp->u_arg[3]);
+	return decode_cmd_data(tcp, id, cmd, tcp->u_arg[3]);
 }
diff --git a/readahead.c b/readahead.c
index 3f8e4ce..f2b9c80 100644
--- a/readahead.c
+++ b/readahead.c
@@ -6,7 +6,7 @@
 
 	printfd(tcp, tcp->u_arg[0]);
 	argn = printllval(tcp, ", %lld", 1);
-	tprintf(", %ld", tcp->u_arg[argn]);
+	tprintf(", %lu", tcp->u_arg[argn]);
 
 	return RVAL_DECODED;
 }
diff --git a/regs.h b/regs.h
index 9b0746c..d89581d 100644
--- a/regs.h
+++ b/regs.h
@@ -1,3 +1,6 @@
+#ifndef STRACE_REGS_H
+#define STRACE_REGS_H
+
 #include <sys/user.h>
 
 #ifdef HAVE_SYS_REG_H
@@ -5,3 +8,5 @@
 #endif
 
 #include "arch_regs.h"
+
+#endif /* !STRACE_REGS_H */
diff --git a/scsi.c b/scsi.c
index dc51dd5..979c342 100644
--- a/scsi.c
+++ b/scsi.c
@@ -275,7 +275,7 @@
 			else
 				print_sg_io_res(tcp, iid, arg);
 		}
-		tprintf("}");
+		tprints("}");
 		return RVAL_DECODED | 1;
 	}
 }
diff --git a/seccomp_fprog.h b/seccomp_fprog.h
index 6b1f77f..f483727 100644
--- a/seccomp_fprog.h
+++ b/seccomp_fprog.h
@@ -1,4 +1,9 @@
+#ifndef STRACE_SECCOMP_FPROG_H
+#define STRACE_SECCOMP_FPROG_H
+
 struct seccomp_fprog {
 	unsigned short len;
 	unsigned long filter;
 };
+
+#endif /* !STRACE_SECCOMP_FPROG_H */
diff --git a/sen.h b/sen.h
index bf6cdfd..f300344 100644
--- a/sen.h
+++ b/sen.h
@@ -1,5 +1,6 @@
 enum {
 SEN_printargs = 0,
+SEN_ARCH_mmap,
 SEN_accept,
 SEN_accept4,
 SEN_access,
@@ -8,7 +9,6 @@
 SEN_adjtimex,
 SEN_afs_syscall,
 SEN_alarm,
-SEN_ARCH_mmap,
 SEN_arch_prctl,
 SEN_bdflush,
 SEN_bind,
@@ -73,6 +73,7 @@
 SEN_fsetxattr,
 SEN_fstat,
 SEN_fstat64,
+SEN_fstatat64,
 SEN_fstatfs,
 SEN_fstatfs64,
 SEN_fsync,
@@ -81,6 +82,10 @@
 SEN_ftruncate64,
 SEN_futex,
 SEN_futimesat,
+SEN_get_kernel_syms,
+SEN_get_mempolicy,
+SEN_get_robust_list,
+SEN_get_thread_area,
 SEN_getcpu,
 SEN_getcwd,
 SEN_getdents,
@@ -96,8 +101,6 @@
 SEN_getgroups16,
 SEN_gethostname,
 SEN_getitimer,
-SEN_get_kernel_syms,
-SEN_get_mempolicy,
 SEN_getpagesize,
 SEN_getpeername,
 SEN_getpgid,
@@ -112,12 +115,10 @@
 SEN_getresuid,
 SEN_getresuid16,
 SEN_getrlimit,
-SEN_get_robust_list,
 SEN_getrusage,
 SEN_getsid,
 SEN_getsockname,
 SEN_getsockopt,
-SEN_get_thread_area,
 SEN_gettid,
 SEN_gettimeofday,
 SEN_getuid,
@@ -134,15 +135,15 @@
 SEN_inotify_init1,
 SEN_inotify_rm_watch,
 SEN_io_cancel,
-SEN_ioctl,
 SEN_io_destroy,
 SEN_io_getevents,
+SEN_io_setup,
+SEN_io_submit,
+SEN_ioctl,
 SEN_ioperm,
 SEN_iopl,
 SEN_ioprio_get,
 SEN_ioprio_set,
-SEN_io_setup,
-SEN_io_submit,
 SEN_ipc,
 SEN_kcmp,
 SEN_kexec_file_load,
@@ -200,17 +201,17 @@
 SEN_newfstatat,
 SEN_nfsservctl,
 SEN_nice,
-SEN_oldfstat,
-SEN_oldlstat,
 SEN_old_mmap,
 SEN_old_mmap_pgoff,
+SEN_oldfstat,
+SEN_oldlstat,
 SEN_oldolduname,
 SEN_oldselect,
 SEN_oldstat,
 SEN_olduname,
 SEN_open,
-SEN_openat,
 SEN_open_by_handle_at,
+SEN_openat,
 SEN_or1k_atomic,
 SEN_osf_fstatfs,
 SEN_osf_getitimer,
@@ -274,11 +275,11 @@
 SEN_rt_sigsuspend,
 SEN_rt_sigtimedwait,
 SEN_rt_tgsigqueueinfo,
+SEN_sched_get_priority_max,
+SEN_sched_get_priority_min,
 SEN_sched_getaffinity,
 SEN_sched_getattr,
 SEN_sched_getparam,
-SEN_sched_get_priority_max,
-SEN_sched_get_priority_min,
 SEN_sched_getscheduler,
 SEN_sched_rr_get_interval,
 SEN_sched_setaffinity,
@@ -299,6 +300,10 @@
 SEN_sendmmsg,
 SEN_sendmsg,
 SEN_sendto,
+SEN_set_mempolicy,
+SEN_set_robust_list,
+SEN_set_thread_area,
+SEN_set_tid_address,
 SEN_setdomainname,
 SEN_setfsgid,
 SEN_setfsgid16,
@@ -310,7 +315,6 @@
 SEN_setgroups16,
 SEN_sethostname,
 SEN_setitimer,
-SEN_set_mempolicy,
 SEN_setns,
 SEN_setpgid,
 SEN_setpgrp,
@@ -324,11 +328,8 @@
 SEN_setreuid,
 SEN_setreuid16,
 SEN_setrlimit,
-SEN_set_robust_list,
 SEN_setsid,
 SEN_setsockopt,
-SEN_set_thread_area,
-SEN_set_tid_address,
 SEN_settimeofday,
 SEN_setuid,
 SEN_setuid16,
@@ -381,13 +382,13 @@
 SEN_time,
 SEN_timer_create,
 SEN_timer_delete,
+SEN_timer_getoverrun,
+SEN_timer_gettime,
+SEN_timer_settime,
 SEN_timerfd,
 SEN_timerfd_create,
 SEN_timerfd_gettime,
 SEN_timerfd_settime,
-SEN_timer_getoverrun,
-SEN_timer_gettime,
-SEN_timer_settime,
 SEN_times,
 SEN_truncate,
 SEN_truncate64,
diff --git a/sigevent.h b/sigevent.h
index 6b3bacf..04c9079 100644
--- a/sigevent.h
+++ b/sigevent.h
@@ -25,8 +25,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef SIGEVENT_H_
-#define SIGEVENT_H_
+#ifndef STRACE_SIGEVENT_H
+#define STRACE_SIGEVENT_H
 
 typedef struct {
 	union {
@@ -44,4 +44,4 @@
 	} sigev_un;
 } struct_sigevent;
 
-#endif
+#endif /* !STRACE_SIGEVENT_H */
diff --git a/signal.c b/signal.c
index cb200bf..b483ce0 100644
--- a/signal.c
+++ b/signal.c
@@ -70,6 +70,7 @@
 # endif
 #endif
 
+#include "xlat/sa_handler_values.h"
 #include "xlat/sigact_flags.h"
 #include "xlat/sigprocmaskcmds.h"
 
@@ -113,6 +114,23 @@
  * Use (NSIG / 8) as a size instead.
  */
 
+static const char *
+get_sa_handler_str(unsigned long handler)
+{
+	return xlookup(sa_handler_values, handler);
+}
+
+static void
+print_sa_handler(unsigned long handler)
+{
+	const char *sa_handler_str = get_sa_handler_str(handler);
+
+	if (sa_handler_str)
+		tprints(sa_handler_str);
+	else
+		printaddr(handler);
+}
+
 const char *
 signame(const int sig)
 {
@@ -258,8 +276,6 @@
 	return 0;
 }
 
-#ifdef HAVE_SIGACTION
-
 struct old_sigaction {
 	/* sa_handler may be a libc #define, need to use other name: */
 #ifdef MIPS
@@ -320,14 +336,7 @@
 	 * compiler from generating code to manipulate
 	 * __sa_handler we cast the function pointers to long. */
 	tprints("{");
-	if ((long)sa.__sa_handler == (long)SIG_ERR)
-		tprints("SIG_ERR");
-	else if ((long)sa.__sa_handler == (long)SIG_DFL)
-		tprints("SIG_DFL");
-	else if ((long)sa.__sa_handler == (long)SIG_IGN)
-		tprints("SIG_IGN");
-	else
-		printaddr((long) sa.__sa_handler);
+	print_sa_handler((unsigned long) sa.__sa_handler);
 	tprints(", ");
 #ifdef MIPS
 	tprintsigmask_addr("", sa.sa_mask);
@@ -360,39 +369,15 @@
 	if (entering(tcp)) {
 		printsignal(tcp->u_arg[0]);
 		tprints(", ");
-		switch (tcp->u_arg[1]) {
-		case (long) SIG_ERR:
-			tprints("SIG_ERR");
-			break;
-		case (long) SIG_DFL:
-			tprints("SIG_DFL");
-			break;
-		case (long) SIG_IGN:
-			tprints("SIG_IGN");
-			break;
-		default:
-			printaddr(tcp->u_arg[1]);
-		}
+		print_sa_handler(tcp->u_arg[1]);
 		return 0;
-	}
-	else if (!syserror(tcp)) {
-		switch (tcp->u_rval) {
-		case (long) SIG_ERR:
-			tcp->auxstr = "SIG_ERR"; break;
-		case (long) SIG_DFL:
-			tcp->auxstr = "SIG_DFL"; break;
-		case (long) SIG_IGN:
-			tcp->auxstr = "SIG_IGN"; break;
-		default:
-			tcp->auxstr = NULL;
-		}
+	} else if (!syserror(tcp)) {
+		tcp->auxstr = get_sa_handler_str(tcp->u_rval);
 		return RVAL_HEX | RVAL_STR;
 	}
 	return 0;
 }
 
-#endif /* HAVE_SIGACTION */
-
 SYS_FUNC(siggetmask)
 {
 	if (exiting(tcp)) {
@@ -408,8 +393,6 @@
 	return RVAL_DECODED;
 }
 
-#ifdef HAVE_SIGACTION
-
 /* "Old" sigprocmask, which operates with word-sized signal masks */
 SYS_FUNC(sigprocmask)
 {
@@ -447,8 +430,6 @@
 	return 0;
 }
 
-#endif /* HAVE_SIGACTION */
-
 SYS_FUNC(kill)
 {
 	tprintf("%d, %s",
@@ -545,7 +526,7 @@
 		 * For little-endian, it's the same.
 		 * For big-endian, we swap 32-bit words.
 		 */
-		sa.sa_mask[0] = sa32.sa_mask[0] + ((long)(sa32.sa_mask[1]) << 32);
+		sa.sa_mask[0] = LONG_LONG(sa32.sa_mask[0], sa32.sa_mask[1]);
 	} else
 #endif
 	if (umove_or_printaddr(tcp, addr, &sa))
@@ -560,14 +541,7 @@
 	 * compiler from generating code to manipulate
 	 * __sa_handler we cast the function pointers to long. */
 	tprints("{");
-	if ((long)sa.__sa_handler == (long)SIG_ERR)
-		tprints("SIG_ERR");
-	else if ((long)sa.__sa_handler == (long)SIG_DFL)
-		tprints("SIG_DFL");
-	else if ((long)sa.__sa_handler == (long)SIG_IGN)
-		tprints("SIG_IGN");
-	else
-		printaddr((unsigned long) sa.__sa_handler);
+	print_sa_handler((unsigned long) sa.__sa_handler);
 	tprints(", ");
 	/*
 	 * Sigset size is in tcp->u_arg[4] (SPARC)
diff --git a/tests/signalfd.c b/stat.c
similarity index 63%
copy from tests/signalfd.c
copy to stat.c
index 7b1d6ce..2143819 100644
--- a/tests/signalfd.c
+++ b/stat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,30 +25,50 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "tests.h"
-#include <fcntl.h>
+#include "defs.h"
+#include "stat.h"
 
-#if defined HAVE_SYS_SIGNALFD_H && defined HAVE_SIGNALFD && defined O_CLOEXEC
-
-# include <signal.h>
-# include <unistd.h>
-# include <sys/signalfd.h>
-
-int
-main(void)
+static void
+decode_struct_stat(struct tcb *tcp, const unsigned long addr)
 {
-	sigset_t mask;
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGUSR2);
-	sigaddset(&mask, SIGCHLD);
-	(void) close(0);
-	if (signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK))
-		perror_msg_and_skip("signalfd");
+	struct strace_stat st;
+
+	if (fetch_struct_stat(tcp, addr, &st))
+		print_struct_stat(tcp, &st);
+}
+
+SYS_FUNC(stat)
+{
+	if (entering(tcp)) {
+		printpath(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		decode_struct_stat(tcp, tcp->u_arg[1]);
+	}
 	return 0;
 }
 
-#else
+SYS_FUNC(fstat)
+{
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		decode_struct_stat(tcp, tcp->u_arg[1]);
+	}
+	return 0;
+}
 
-SKIP_MAIN_UNDEFINED("HAVE_SYS_SIGNALFD_H && HAVE_SIGNALFD && O_CLOEXEC")
-
-#endif
+SYS_FUNC(newfstatat)
+{
+	if (entering(tcp)) {
+		print_dirfd(tcp, tcp->u_arg[0]);
+		printpath(tcp, tcp->u_arg[1]);
+		tprints(", ");
+	} else {
+		decode_struct_stat(tcp, tcp->u_arg[2]);
+		tprints(", ");
+		printflags(at_flags, tcp->u_arg[3], "AT_???");
+	}
+	return 0;
+}
diff --git a/tests/signalfd.c b/stat.h
similarity index 70%
rename from tests/signalfd.c
rename to stat.h
index 7b1d6ce..092d268 100644
--- a/tests/signalfd.c
+++ b/stat.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,30 +25,26 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "tests.h"
-#include <fcntl.h>
+#ifndef STRACE_STAT_H
+#define STRACE_STAT_H
 
-#if defined HAVE_SYS_SIGNALFD_H && defined HAVE_SIGNALFD && defined O_CLOEXEC
+struct strace_stat {
+	unsigned long long	dev;
+	unsigned long long	ino;
+	unsigned long long	rdev;
+	unsigned long long	size;
+	unsigned long long	blocks;
+	unsigned long long	blksize;
+	unsigned long long	mode;
+	unsigned long long	nlink;
+	unsigned long long	uid;
+	unsigned long long	gid;
+	long long		atime;
+	long long		ctime;
+	long long		mtime;
+	unsigned long long	atime_nsec;
+	unsigned long long	ctime_nsec;
+	unsigned long long	mtime_nsec;
+};
 
-# include <signal.h>
-# include <unistd.h>
-# include <sys/signalfd.h>
-
-int
-main(void)
-{
-	sigset_t mask;
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGUSR2);
-	sigaddset(&mask, SIGCHLD);
-	(void) close(0);
-	if (signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK))
-		perror_msg_and_skip("signalfd");
-	return 0;
-}
-
-#else
-
-SKIP_MAIN_UNDEFINED("HAVE_SYS_SIGNALFD_H && HAVE_SIGNALFD && O_CLOEXEC")
-
-#endif
+#endif /* !STRACE_STAT_H */
diff --git a/tests/signalfd.c b/stat64.c
similarity index 62%
copy from tests/signalfd.c
copy to stat64.c
index 7b1d6ce..3c816cd 100644
--- a/tests/signalfd.c
+++ b/stat64.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,30 +25,50 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "tests.h"
-#include <fcntl.h>
+#include "defs.h"
+#include "stat.h"
 
-#if defined HAVE_SYS_SIGNALFD_H && defined HAVE_SIGNALFD && defined O_CLOEXEC
-
-# include <signal.h>
-# include <unistd.h>
-# include <sys/signalfd.h>
-
-int
-main(void)
+static void
+decode_struct_stat64(struct tcb *tcp, const unsigned long addr)
 {
-	sigset_t mask;
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGUSR2);
-	sigaddset(&mask, SIGCHLD);
-	(void) close(0);
-	if (signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK))
-		perror_msg_and_skip("signalfd");
+	struct strace_stat st;
+
+	if (fetch_struct_stat64(tcp, addr, &st))
+		print_struct_stat(tcp, &st);
+}
+
+SYS_FUNC(stat64)
+{
+	if (entering(tcp)) {
+		printpath(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		decode_struct_stat64(tcp, tcp->u_arg[1]);
+	}
 	return 0;
 }
 
-#else
+SYS_FUNC(fstat64)
+{
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+	} else {
+		decode_struct_stat64(tcp, tcp->u_arg[1]);
+	}
+	return 0;
+}
 
-SKIP_MAIN_UNDEFINED("HAVE_SYS_SIGNALFD_H && HAVE_SIGNALFD && O_CLOEXEC")
-
-#endif
+SYS_FUNC(fstatat64)
+{
+	if (entering(tcp)) {
+		print_dirfd(tcp, tcp->u_arg[0]);
+		printpath(tcp, tcp->u_arg[1]);
+		tprints(", ");
+	} else {
+		decode_struct_stat64(tcp, tcp->u_arg[2]);
+		tprints(", ");
+		printflags(at_flags, tcp->u_arg[3], "AT_???");
+	}
+	return 0;
+}
diff --git a/statfs.h b/statfs.h
index 9341687..c986424 100644
--- a/statfs.h
+++ b/statfs.h
@@ -42,4 +42,4 @@
 	unsigned long long f_flags;
 };
 
-#endif /* STRACE_STATFS_H */
+#endif /* !STRACE_STATFS_H */
diff --git a/strace.1 b/strace.1
index b7dddc0..6cc17c5 100644
--- a/strace.1
+++ b/strace.1
@@ -601,10 +601,13 @@
 is used.
 .LP
 When using
-.BR \-p ,
+.B \-p
+without a
+.IR command ,
 the exit status of
 .B strace
-is zero unless there was an unexpected error in doing the tracing.
+is zero unless no processes has been attached or there was an unexpected error
+in doing the tracing.
 .SH "SETUID INSTALLATION"
 If
 .B strace
diff --git a/strace.c b/strace.c
index ab4867f..ffb6bae 100644
--- a/strace.c
+++ b/strace.c
@@ -138,7 +138,7 @@
 /* Are we "strace PROG" and need to hide everything until execve? */
 bool hide_log_until_execve = 0;
 
-static int exit_code = 0;
+static int exit_code;
 static int strace_child = 0;
 static int strace_tracer_pid = 0;
 
@@ -360,22 +360,26 @@
 	error_msg_and_help("invalid -%c argument: '%s'", opt, arg);
 }
 
-#if USE_SEIZE
+static const char *ptrace_attach_cmd;
+
 static int
 ptrace_attach_or_seize(int pid)
 {
+#if USE_SEIZE
 	int r;
 	if (!use_seize)
-		return ptrace(PTRACE_ATTACH, pid, 0L, 0L);
+		return ptrace_attach_cmd = "PTRACE_ATTACH",
+		       ptrace(PTRACE_ATTACH, pid, 0L, 0L);
 	r = ptrace(PTRACE_SEIZE, pid, 0L, (unsigned long) ptrace_setoptions);
 	if (r)
-		return r;
+		return ptrace_attach_cmd = "PTRACE_SEIZE", r;
 	r = ptrace(PTRACE_INTERRUPT, pid, 0L, 0L);
-	return r;
-}
+	return ptrace_attach_cmd = "PTRACE_INTERRUPT", r;
 #else
-# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
+		return ptrace_attach_cmd = "PTRACE_ATTACH",
+		       ptrace(PTRACE_ATTACH, pid, 0L, 0L);
 #endif
+}
 
 /*
  * Used when we want to unblock stopped traced process.
@@ -401,10 +405,8 @@
 		msg = "CONT";
 	if (op == PTRACE_DETACH)
 		msg = "DETACH";
-#ifdef PTRACE_LISTEN
 	if (op == PTRACE_LISTEN)
 		msg = "LISTEN";
-#endif
 	/*
 	 * Why curcol != 0? Otherwise sometimes we get this:
 	 *
@@ -832,10 +834,6 @@
 	 * before detaching.  Arghh.  We go through hoops
 	 * to make a clean break of things.
 	 */
-#if defined(SPARC)
-# undef PTRACE_DETACH
-# define PTRACE_DETACH PTRACE_SUNDETACH
-#endif
 
 	if (!(tcp->flags & TCB_ATTACHED))
 		goto drop;
@@ -1011,6 +1009,69 @@
 }
 
 static void
+attach_tcb(struct tcb *const tcp)
+{
+	if (ptrace_attach_or_seize(tcp->pid) < 0) {
+		perror_msg("attach: ptrace(%s, %d)",
+			   ptrace_attach_cmd, tcp->pid);
+		droptcb(tcp);
+		return;
+	}
+
+	tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
+	newoutf(tcp);
+	if (debug_flag)
+		error_msg("attach to pid %d (main) succeeded", tcp->pid);
+
+	char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
+	DIR *dir;
+	unsigned int ntid = 0, nerr = 0;
+
+	if (followfork && tcp->pid != strace_child &&
+	    sprintf(procdir, "/proc/%d/task", tcp->pid) > 0 &&
+	    (dir = opendir(procdir)) != NULL) {
+		struct_dirent *de;
+
+		while ((de = read_dir(dir)) != NULL) {
+			if (de->d_fileno == 0)
+				continue;
+
+			int tid = string_to_uint(de->d_name);
+			if (tid <= 0 || tid == tcp->pid)
+				continue;
+
+			++ntid;
+			if (ptrace_attach_or_seize(tid) < 0) {
+				++nerr;
+				if (debug_flag)
+					perror_msg("attach: ptrace(%s, %d)",
+						   ptrace_attach_cmd, tid);
+				continue;
+			}
+			if (debug_flag)
+				error_msg("attach to pid %d succeeded", tid);
+
+			struct tcb *tid_tcp = alloctcb(tid);
+			tid_tcp->flags |= TCB_ATTACHED | TCB_STARTUP |
+					  post_attach_sigstop;
+			newoutf(tid_tcp);
+		}
+
+		closedir(dir);
+	}
+
+	if (!qflag) {
+		if (ntid > nerr)
+			error_msg("Process %u attached"
+				  " with %u threads",
+				  tcp->pid, ntid - nerr + 1);
+		else
+			error_msg("Process %u attached",
+				  tcp->pid);
+	}
+}
+
+static void
 startup_attach(void)
 {
 	pid_t parent_pid = strace_tracer_pid;
@@ -1058,89 +1119,19 @@
 
 		if (tcp->pid == parent_pid || tcp->pid == strace_tracer_pid) {
 			errno = EPERM;
-			perror_msg("attach: %d", tcp->pid);
+			perror_msg("attach: pid %d", tcp->pid);
 			droptcb(tcp);
 			continue;
 		}
-		if (followfork && tcp->pid != strace_child) {
-			char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
-			DIR *dir;
 
-			sprintf(procdir, "/proc/%d/task", tcp->pid);
-			dir = opendir(procdir);
-			if (dir != NULL) {
-				unsigned int ntid = 0, nerr = 0;
-				struct_dirent *de;
+		attach_tcb(tcp);
 
-				while ((de = read_dir(dir)) != NULL) {
-					struct tcb *cur_tcp;
-					int tid;
-
-					if (de->d_fileno == 0)
-						continue;
-					/* we trust /proc filesystem */
-					tid = atoi(de->d_name);
-					if (tid <= 0)
-						continue;
-					++ntid;
-					if (ptrace_attach_or_seize(tid) < 0) {
-						++nerr;
-						if (debug_flag)
-							error_msg("attach to pid %d failed", tid);
-						continue;
-					}
-					if (debug_flag)
-						error_msg("attach to pid %d succeeded", tid);
-					cur_tcp = tcp;
-					if (tid != tcp->pid)
-						cur_tcp = alloctcb(tid);
-					cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
-					newoutf(cur_tcp);
-				}
-				closedir(dir);
-				if (interactive) {
-					sigprocmask(SIG_SETMASK, &empty_set, NULL);
-					if (interrupted)
-						goto ret;
-					sigprocmask(SIG_BLOCK, &blocked_set, NULL);
-				}
-				ntid -= nerr;
-				if (ntid == 0) {
-					perror_msg("attach: ptrace(PTRACE_ATTACH, ...)");
-					droptcb(tcp);
-					continue;
-				}
-				if (!qflag) {
-					if (ntid > 1)
-						error_msg("Process %u attached"
-							  " with %u threads",
-							  tcp->pid, ntid);
-					else
-						error_msg("Process %u attached",
-							  tcp->pid);
-				}
-				if (!(tcp->flags & TCB_ATTACHED)) {
-					/* -p PID, we failed to attach to PID itself
-					 * but did attach to some of its sibling threads.
-					 * Drop PID's tcp.
-					 */
-					droptcb(tcp);
-				}
-				continue;
-			} /* if (opendir worked) */
-		} /* if (-f) */
-		if (ptrace_attach_or_seize(tcp->pid) < 0) {
-			perror_msg("attach: ptrace(PTRACE_ATTACH, ...)");
-			droptcb(tcp);
-			continue;
+		if (interactive) {
+			sigprocmask(SIG_SETMASK, &empty_set, NULL);
+			if (interrupted)
+				goto ret;
+			sigprocmask(SIG_BLOCK, &blocked_set, NULL);
 		}
-		tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
-		newoutf(tcp);
-		if (debug_flag)
-			error_msg("attach to pid %d (main) succeeded", tcp->pid);
-
-		if (!qflag)
-			error_msg("Process %u attached", tcp->pid);
 	} /* for each tcbtab[] */
 
 	if (daemonized_tracer) {
@@ -1224,6 +1215,12 @@
 	perror_msg_and_die("exec");
 }
 
+/*
+ * Open a dummy descriptor for use as a placeholder.
+ * The descriptor is O_RDONLY with FD_CLOEXEC flag set.
+ * A read attempt from such descriptor ends with EOF,
+ * a write attempt is rejected with EBADF.
+ */
 static int
 open_dummy_desc(void)
 {
@@ -1232,9 +1229,56 @@
 	if (pipe(fds))
 		perror_msg_and_die("pipe");
 	close(fds[1]);
+	set_cloexec_flag(fds[0]);
 	return fds[0];
 }
 
+/* placeholder fds status for stdin and stdout */
+static bool fd_is_placeholder[2];
+
+/*
+ * Ensure that all standard file descriptors are open by opening placeholder
+ * file descriptors for those standard file descriptors that are not open.
+ *
+ * The information which descriptors have been made open is saved
+ * in fd_is_placeholder for later use.
+ */
+static void
+ensure_standard_fds_opened(void)
+{
+	int fd;
+
+	while ((fd = open_dummy_desc()) <= 2) {
+		if (fd == 2)
+			break;
+		fd_is_placeholder[fd] = true;
+	}
+
+	if (fd > 2)
+		close(fd);
+}
+
+/*
+ * Redirect stdin and stdout unless they have been opened earlier
+ * by ensure_standard_fds_opened as placeholders.
+ */
+static void
+redirect_standard_fds(void)
+{
+	int i;
+
+	/*
+	 * It might be a good idea to redirect stderr as well,
+	 * but we sometimes need to print error messages.
+	 */
+	for (i = 0; i <= 1; ++i) {
+		if (!fd_is_placeholder[i]) {
+			close(i);
+			open_dummy_desc();
+		}
+	}
+}
+
 static void
 startup_child(char **argv)
 {
@@ -1363,7 +1407,8 @@
 
 			if (ptrace_attach_or_seize(pid)) {
 				kill_save_errno(pid, SIGKILL);
-				perror_msg_and_die("Can't attach to %d", pid);
+				perror_msg_and_die("attach: ptrace(%s, %d)",
+						   ptrace_attach_cmd, pid);
 			}
 			if (!NOMMU_SYSTEM)
 				kill(pid, SIGCONT);
@@ -1411,18 +1456,11 @@
 	 * the pipe is still open, it has a reader. Thus, "head" will not get its
 	 * SIGPIPE at once, on the first write.
 	 *
-	 * Preventing it by closing strace's stdin/out.
+	 * Preventing it by redirecting strace's stdin/out.
 	 * (Don't leave fds 0 and 1 closed, this is bad practice: future opens
 	 * will reuse them, unexpectedly making a newly opened object "stdin").
 	 */
-	close(0);
-	open_dummy_desc(); /* opens to fd#0 */
-	dup2(0, 1);
-#if 0
-	/* A good idea too, but we sometimes need to print error messages */
-	if (shared_log != stderr)
-		dup2(0, 2);
-#endif
+	redirect_standard_fds();
 }
 
 #if USE_SEIZE
@@ -1755,24 +1793,18 @@
 		error_msg("ptrace_setoptions = %#x", ptrace_setoptions);
 	test_ptrace_seize();
 
-	if (fcntl(0, F_GETFD) == -1 || fcntl(1, F_GETFD) == -1) {
-		/*
-		 * Something weird with our stdin and/or stdout -
-		 * for example, may be not open? In this case,
-		 * ensure that none of the future opens uses them.
-		 *
-		 * This was seen in the wild when /proc/sys/kernel/core_pattern
-		 * was set to "|/bin/strace -o/tmp/LOG PROG":
-		 * kernel runs coredump helper with fd#0 open but fd#1 closed (!),
-		 * therefore LOG gets opened to fd#1, and fd#1 is closed by
-		 * "don't hold up stdin/out open" code soon after.
-		 */
-		int fd = open_dummy_desc();
-		while (fd >= 0 && fd < 2)
-			fd = dup(fd);
-		if (fd > 2)
-			close(fd);
-	}
+	/*
+	 * Is something weird with our stdin and/or stdout -
+	 * for example, may they be not open? In this case,
+	 * ensure that none of the future opens uses them.
+	 *
+	 * This was seen in the wild when /proc/sys/kernel/core_pattern
+	 * was set to "|/bin/strace -o/tmp/LOG PROG":
+	 * kernel runs coredump helper with fd#0 open but fd#1 closed (!),
+	 * therefore LOG gets opened to fd#1, and fd#1 is closed by
+	 * "don't hold up stdin/out open" code soon after.
+	 */
+	ensure_standard_fds_opened();
 
 	/* Check if they want to redirect the output. */
 	if (outfname) {
@@ -2389,6 +2421,8 @@
 {
 	init(argc, argv);
 
+	exit_code = !nprocs;
+
 	while (trace())
 		;
 
diff --git a/sys_func.h b/sys_func.h
index a40a293..614a187 100644
--- a/sys_func.h
+++ b/sys_func.h
@@ -58,13 +58,13 @@
 extern SYS_FUNC(fsetxattr);
 extern SYS_FUNC(fstat);
 extern SYS_FUNC(fstat64);
+extern SYS_FUNC(fstatat64);
 extern SYS_FUNC(fstatfs);
 extern SYS_FUNC(fstatfs64);
 extern SYS_FUNC(ftruncate);
 extern SYS_FUNC(ftruncate64);
 extern SYS_FUNC(futex);
 extern SYS_FUNC(futimesat);
-extern SYS_FUNC(fxstat);
 extern SYS_FUNC(getcpu);
 extern SYS_FUNC(getcwd);
 extern SYS_FUNC(getdents);
@@ -308,4 +308,3 @@
 extern SYS_FUNC(waitpid);
 extern SYS_FUNC(write);
 extern SYS_FUNC(writev);
-extern SYS_FUNC(xstat);
diff --git a/syscall.c b/syscall.c
index 6af0dec..0894733 100644
--- a/syscall.c
+++ b/syscall.c
@@ -419,12 +419,44 @@
 }
 
 static int
+lookup_class(const char *s)
+{
+	if (strcmp(s, "file") == 0)
+		return TRACE_FILE;
+	if (strcmp(s, "ipc") == 0)
+		return TRACE_IPC;
+	if (strcmp(s, "network") == 0)
+		return TRACE_NETWORK;
+	if (strcmp(s, "process") == 0)
+		return TRACE_PROCESS;
+	if (strcmp(s, "signal") == 0)
+		return TRACE_SIGNAL;
+	if (strcmp(s, "desc") == 0)
+		return TRACE_DESC;
+	if (strcmp(s, "memory") == 0)
+		return TRACE_MEMORY;
+	return -1;
+}
+
+static int
 qual_syscall(const char *s, const unsigned int bitflag, const int not)
 {
-	int p;
+	unsigned int p;
 	unsigned int i;
+	int n;
 	int rc = -1;
 
+	if ((n = lookup_class(s)) >= 0) {
+		for (p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
+			for (i = 0; i < nsyscall_vec[p]; ++i) {
+				if ((sysent_vec[p][i].sys_flags & n) == n) {
+					qualify_one(i, bitflag, not, p);
+				}
+			}
+		}
+		return 0;
+	}
+
 	if (*s >= '0' && *s <= '9') {
 		i = string_to_uint(s);
 		if (i >= MAX_NSYSCALLS)
@@ -483,26 +515,6 @@
 	return -1;
 }
 
-static int
-lookup_class(const char *s)
-{
-	if (strcmp(s, "file") == 0)
-		return TRACE_FILE;
-	if (strcmp(s, "ipc") == 0)
-		return TRACE_IPC;
-	if (strcmp(s, "network") == 0)
-		return TRACE_NETWORK;
-	if (strcmp(s, "process") == 0)
-		return TRACE_PROCESS;
-	if (strcmp(s, "signal") == 0)
-		return TRACE_SIGNAL;
-	if (strcmp(s, "desc") == 0)
-		return TRACE_DESC;
-	if (strcmp(s, "memory") == 0)
-		return TRACE_MEMORY;
-	return -1;
-}
-
 void
 qualify(const char *s)
 {
@@ -544,16 +556,6 @@
 	}
 	copy = xstrdup(s);
 	for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
-		int n;
-		if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
-			unsigned pers;
-			for (pers = 0; pers < SUPPORTED_PERSONALITIES; pers++) {
-				for (i = 0; i < nsyscall_vec[pers]; i++)
-					if (sysent_vec[pers][i].sys_flags & n)
-						qualify_one(i, opt->bitflag, not, pers);
-			}
-			continue;
-		}
 		if (opt->qualify(p, opt->bitflag, not)) {
 			error_msg_and_die("invalid %s '%s'",
 				opt->argument_name, p);
@@ -643,11 +645,18 @@
 		sizeof(tcp->u_arg) - sizeof(tcp->u_arg[0]));
 	/*
 	 * Fetching the last arg of 7-arg syscalls (fadvise64_64
-	 * and sync_file_range) would require additional code,
+	 * and sync_file_range) requires additional code,
 	 * see linux/mips/get_syscall_args.c
 	 */
+	if (tcp->s_ent->nargs == MAX_ARGS) {
+		if (umoven(tcp,
+			   mips_REG_SP + MAX_ARGS * sizeof(tcp->u_arg[0]),
+			   sizeof(tcp->u_arg[0]),
+			   &tcp->u_arg[MAX_ARGS - 1]) < 0)
+		tcp->u_arg[MAX_ARGS - 1] = 0;
+	}
 }
-#endif
+#endif /* LINUX_MIPSO32 */
 
 static void
 dumpio(struct tcb *tcp)
@@ -753,11 +762,20 @@
 	if (SCNO_IS_VALID(scno))
 		return sysent[scno].sys_name;
 	else {
-		sprintf(buf, "syscall_%lu", shuffle_scno(scno));
+		sprintf(buf, "syscall_%lu", scno);
 		return buf;
 	}
 }
 
+const char *
+err_name(unsigned long err)
+{
+	if ((err < nerrnos) && errnoent[err])
+		return errnoent[err];
+
+	return NULL;
+}
+
 static long get_regs_error;
 
 void
@@ -787,10 +805,7 @@
 
 	if (res != 1) {
 		printleader(tcp);
-		if (scno_good != 1)
-			tprints("????" /* anti-trigraph gap */ "(");
-		else
-			tprintf("%s(", syscall_name(tcp->scno));
+		tprintf("%s(", scno_good == 1 ? tcp->s_ent->sys_name : "????");
 		/*
 		 * " <unavailable>" will be added later by the code which
 		 * detects ptrace errors.
@@ -849,7 +864,7 @@
 #endif
 
 	printleader(tcp);
-	tprintf("%s(", syscall_name(tcp->scno));
+	tprintf("%s(", tcp->s_ent->sys_name);
 	if ((tcp->qual_flg & QUAL_RAW) && SEN_exit != tcp->s_ent->sen)
 		res = printargs(tcp);
 	else
@@ -871,7 +886,8 @@
 	int sys_res;
 	struct timeval tv;
 	int res;
-	long u_error;
+	unsigned long u_error;
+	const char *u_error_str;
 
 	/* Measure the exit time as early as possible to avoid errors. */
 	if (Tflag || cflag)
@@ -910,7 +926,7 @@
 	if ((followfork < 2 && printing_tcp != tcp) || (tcp->flags & TCB_REPRINT)) {
 		tcp->flags &= ~TCB_REPRINT;
 		printleader(tcp);
-		tprintf("<... %s resumed> ", syscall_name(tcp->scno));
+		tprintf("<... %s resumed> ", tcp->s_ent->sys_name);
 	}
 	printing_tcp = tcp;
 
@@ -953,7 +969,7 @@
 	u_error = tcp->u_error;
 	if (tcp->qual_flg & QUAL_RAW) {
 		if (u_error)
-			tprintf("= -1 (errno %ld)", u_error);
+			tprintf("= -1 (errno %lu)", u_error);
 		else
 			tprintf("= %#lx", tcp->u_rval);
 	}
@@ -1013,13 +1029,13 @@
 			tprints("= ? ERESTART_RESTARTBLOCK (Interrupted by signal)");
 			break;
 		default:
-			if ((unsigned long) u_error < nerrnos
-			    && errnoent[u_error])
-				tprintf("= -1 %s (%s)", errnoent[u_error],
-					strerror(u_error));
+			u_error_str = err_name(u_error);
+			if (u_error_str)
+				tprintf("= -1 %s (%s)",
+					u_error_str, strerror(u_error));
 			else
-				tprintf("= -1 ERRNO_%lu (%s)", u_error,
-					strerror(u_error));
+				tprintf("= -1 %lu (%s)",
+					u_error, strerror(u_error));
 			break;
 		}
 		if ((sys_res & RVAL_STR) && tcp->auxstr)
@@ -1040,7 +1056,8 @@
 					tprintf("= %#lx", tcp->u_rval);
 				break;
 			case RVAL_OCTAL:
-				tprintf("= %#lo", tcp->u_rval);
+				tprints("= ");
+				print_numeric_long_umask(tcp->u_rval);
 				break;
 			case RVAL_UDECIMAL:
 #if SUPPORTED_PERSONALITIES > 1
@@ -1130,7 +1147,7 @@
 	}
 }
 
-static int saved_u_error;
+static unsigned long saved_u_error;
 
 void
 temporarily_clear_syserror(struct tcb *tcp)
@@ -1157,18 +1174,18 @@
 	/* Linux kernel defines MAX_ERRNO to 4095. */
 	kernel_ulong_t max = -(kernel_long_t) 4095;
 
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
-	if (current_wordsize < sizeof(val)) {
+#if defined X86_64 || defined X32
+	/*
+	 * current_wordsize is 4 for x32 personality
+	 * but truncation _must not_ be done in it, so
+	 * check current_personality instead.
+	 */
+	if (current_personality == 1) {
 		val = (uint32_t) val;
 		max = (uint32_t) max;
 	}
-#elif defined X32
-	/*
-	 * current_wordsize is 4 even in personality 0 (native X32)
-	 * but truncation _must not_ be done in it.
-	 * can't check current_wordsize here!
-	 */
-	if (current_personality != 0) {
+#elif SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+	if (current_wordsize < sizeof(val)) {
 		val = (uint32_t) val;
 		max = (uint32_t) max;
 	}
@@ -1277,6 +1294,20 @@
 #endif
 }
 
+struct sysent_buf {
+	struct tcb *tcp;
+	struct_sysent ent;
+	char buf[sizeof("syscall_%lu") + sizeof(long) * 3];
+};
+
+static void
+free_sysent_buf(void *ptr)
+{
+	struct sysent_buf *s = ptr;
+	s->tcp->s_prev_ent = s->tcp->s_ent = NULL;
+	free(ptr);
+}
+
 /*
  * Returns:
  * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently.
@@ -1298,14 +1329,20 @@
 		tcp->s_ent = &sysent[tcp->scno];
 		tcp->qual_flg = qual_flags[tcp->scno];
 	} else {
-		static const struct_sysent unknown = {
-			.nargs = MAX_ARGS,
-			.sys_flags = 0,
-			.sys_func = printargs,
-			.sys_name = "system call",
-		};
-		tcp->s_ent = &unknown;
+		struct sysent_buf *s = xcalloc(1, sizeof(*s));
+
+		s->tcp = tcp;
+		s->ent.nargs = MAX_ARGS;
+		s->ent.sen = SEN_printargs;
+		s->ent.sys_func = printargs;
+		s->ent.sys_name = s->buf;
+		sprintf(s->buf, "syscall_%lu", shuffle_scno(tcp->scno));
+
+		tcp->s_ent = &s->ent;
 		tcp->qual_flg = QUAL_RAW | DEFAULT_QUAL_FLAGS;
+
+		set_tcb_priv_data(tcp, s, free_sysent_buf);
+
 		if (debug_flag)
 			error_msg("pid %d invalid syscall %ld", tcp->pid, tcp->scno);
 	}
diff --git a/sysinfo.c b/sysinfo.c
index c3cb9ad..a0f29cb 100644
--- a/sysinfo.c
+++ b/sysinfo.c
@@ -59,19 +59,19 @@
 			", freehigh=%llu"
 			", mem_unit=%u"
 			"}",
-			widen_to_ull(si.uptime)
-			, widen_to_ull(si.loads[0])
-			, widen_to_ull(si.loads[1])
-			, widen_to_ull(si.loads[2])
-			, widen_to_ull(si.totalram)
-			, widen_to_ull(si.freeram)
-			, widen_to_ull(si.sharedram)
-			, widen_to_ull(si.bufferram)
-			, widen_to_ull(si.totalswap)
-			, widen_to_ull(si.freeswap)
+			zero_extend_signed_to_ull(si.uptime)
+			, zero_extend_signed_to_ull(si.loads[0])
+			, zero_extend_signed_to_ull(si.loads[1])
+			, zero_extend_signed_to_ull(si.loads[2])
+			, zero_extend_signed_to_ull(si.totalram)
+			, zero_extend_signed_to_ull(si.freeram)
+			, zero_extend_signed_to_ull(si.sharedram)
+			, zero_extend_signed_to_ull(si.bufferram)
+			, zero_extend_signed_to_ull(si.totalswap)
+			, zero_extend_signed_to_ull(si.freeswap)
 			, (unsigned) si.procs
-			, widen_to_ull(si.totalhigh)
-			, widen_to_ull(si.freehigh)
+			, zero_extend_signed_to_ull(si.totalhigh)
+			, zero_extend_signed_to_ull(si.freehigh)
 			, si.mem_unit
 			);
 	}
diff --git a/term.c b/term.c
index 530ffc4..2b0be68 100644
--- a/term.c
+++ b/term.c
@@ -67,10 +67,10 @@
 	if (!(tios.c_lflag & ICANON))
 		tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
 			tios.c_cc[VMIN], tios.c_cc[VTIME]);
-	tprintf("c_cc=\"");
+	tprints("c_cc=\"");
 	for (i = 0; i < NCCS; i++)
 		tprintf("\\x%02x", tios.c_cc[i]);
-	tprintf("\"}");
+	tprints("\"}");
 }
 
 static void
@@ -109,10 +109,10 @@
 		tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
 			tio.c_cc[VMIN], tio.c_cc[VTIME]);
 #endif /* !_VMIN */
-	tprintf("c_cc=\"");
+	tprints("c_cc=\"");
 	for (i = 0; i < NCC; i++)
 		tprintf("\\x%02x", tio.c_cc[i]);
-	tprintf("\"}");
+	tprints("\"}");
 }
 
 static void
diff --git a/test/seccomp.c b/test/seccomp.c
new file mode 100644
index 0000000..00e6cca
--- /dev/null
+++ b/test/seccomp.c
@@ -0,0 +1,93 @@
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <asm/unistd.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+#if defined __i386__
+# define SECCOMP_ARCH AUDIT_ARCH_I386
+#elif defined __x86_64__
+# define SECCOMP_ARCH AUDIT_ARCH_X86_64
+#elif defined __arm__
+# define SECCOMP_ARCH AUDIT_ARCH_ARM
+#elif defined __arm64__ || defined __aarch64__
+# define SECCOMP_ARCH AUDIT_ARCH_AARCH64
+#else
+# error unsupported architecture
+#endif
+
+#define SOCK_FILTER_KILL_PROCESS \
+		BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL)
+
+#define SOCK_FILTER_DENY_SYSCALL(nr, err) \
+		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_ ## nr, 0, 1), \
+		BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (SECCOMP_RET_DATA & (err)))
+
+#define SOCK_FILTER_ALLOW_SYSCALL(nr) \
+		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_ ## nr, 0, 1), \
+		BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
+
+static const struct sock_filter filter[] = {
+	/* load architecture */
+	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof (struct seccomp_data, arch))),
+	/* jump forward 1 instruction if architecture matches */
+	BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_ARCH, 1, 0),
+	/* kill process */
+	SOCK_FILTER_KILL_PROCESS,
+
+	/* load syscall number */
+	BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
+
+	/* allow syscalls */
+	SOCK_FILTER_ALLOW_SYSCALL(close),
+	SOCK_FILTER_ALLOW_SYSCALL(exit),
+	SOCK_FILTER_ALLOW_SYSCALL(exit_group),
+
+	/* deny syscalls */
+	SOCK_FILTER_DENY_SYSCALL(sync, EBUSY),
+	SOCK_FILTER_DENY_SYSCALL(setsid, EACCES),
+	SOCK_FILTER_DENY_SYSCALL(getpid, EPERM),
+	SOCK_FILTER_DENY_SYSCALL(munlockall, SECCOMP_RET_DATA),
+
+	/* kill process */
+	SOCK_FILTER_KILL_PROCESS
+};
+
+static const struct sock_fprog prog = {
+	.len = sizeof(filter) / sizeof(filter[0]),
+	.filter = (struct sock_filter *) filter,
+};
+
+int
+main(void)
+{
+	int fds[2];
+
+	close(0);
+	close(1);
+	if (pipe(fds))
+		return 77;
+
+	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
+		return 77;
+
+	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog))
+		return 77;
+
+	if (close(0) || close(1))
+		_exit(1);
+
+#define TEST_DENIED_SYSCALL(nr, err, fail) \
+	if (errno = 0, syscall(__NR_ ## nr, 0xbad, 0xf00d, 0xdead, 0xbeef, err, fail) != -1 || err != errno) \
+		close(-fail)
+
+	TEST_DENIED_SYSCALL(sync, EBUSY, 2);
+	TEST_DENIED_SYSCALL(setsid, EACCES, 3);
+	TEST_DENIED_SYSCALL(getpid, EPERM, 4);
+	TEST_DENIED_SYSCALL(munlockall, SECCOMP_RET_DATA, 5);
+
+	_exit(0);
+}
diff --git a/test/threaded_execve.c b/test/threaded_execve.c
new file mode 100644
index 0000000..d1d2208
--- /dev/null
+++ b/test/threaded_execve.c
@@ -0,0 +1,147 @@
+/*
+ * Create NUM_THREADS threads which print "1" and sleep in pause().
+ * Then create another thread which prints "2", and re-execs the program.
+ * The leader then either sleeps in pause(), or exits if $LEADER_EXIT is set.
+ * This triggers "execve'ed thread replaces thread leader" case.
+ *
+ * gcc -Wall -Os -o threaded_execve threaded_execve.c
+ *
+ * Try running it under strace like this:
+ *
+ * # Should not be confused by traced execve-ing thread
+ * # replacing traced leader:
+ * strace -oLOG -f ./threaded_execve
+ *
+ * # Same, but different output mode. Output after execve
+ * # should go into leader's LOG.<pid> file, not into execve'ed
+ * # thread's log file:
+ * strace -oLOG -ff ./threaded_execve
+ *
+ * # Should not be confused by non-traced execve-ing thread
+ * # replacing traced leader:
+ * strace -oLOG ./threaded_execve
+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * In Linux 3.2, non-traced execve-ing thread does not
+ * become traced after execve, even though it has pid == leader's pid
+ * after execve. And yet, strace's waitpid doesn't return ECHILD.
+ *
+ * # Run for NUM seconds, not just one second.
+ * # Watch top to check for memory leaks in strace:
+ * strace -oLOG -f ./threaded_execve <NUM>
+ *
+ */
+#define NUM_THREADS 1
+
+#define _GNU_SOURCE 1
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sched.h>
+#include <signal.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <asm/unistd.h>
+
+/* Define clone2 for all arches */
+#ifdef __ia64__
+extern int __clone2(int (*fn) (void *), void *child_stack_base,
+		size_t stack_size, int flags, void *arg, ...);
+#define clone2 __clone2
+#elif defined(__metag__)
+#define clone2(func, stack_base, size, flags, arg...) \
+        clone(func, stack_base, flags, arg)
+#else
+#define clone2(func, stack_base, size, flags, arg...) \
+        clone(func, (stack_base) + (size), flags, arg)
+#endif
+/* Direct calls to syscalls, avoiding libc wrappers */
+#define syscall_tgkill(pid, tid, sig) syscall(__NR_tgkill, (pid), (tid), (sig))
+#define syscall_getpid() syscall(__NR_getpid)
+#define syscall_gettid() syscall(__NR_gettid)
+#define syscall_exit(v) syscall(__NR_exit, (v));
+
+static char my_name[PATH_MAX];
+static int leader_final_action;
+
+static int
+thread1(void *unused)
+{
+	write(1, "1", 1);
+	for(;;) pause();
+	return 0;
+}
+
+static int
+thread2(void *unused)
+{
+	char buf[64];
+	sprintf(buf, "%d", leader_final_action);
+	write(1, "2", 1);
+	usleep(20*1000);
+	/* This fails with ENOENT if leader has exited by now! :) */
+	execl("/proc/self/exe", "exe", "exe", buf, NULL);
+	/* So fall back to resolved name */
+	execl(my_name, "exe", "exe", buf, NULL);
+	for(;;) pause();
+	return 0;
+}
+
+static void
+thread_leader(void)
+{
+	/* malloc gives sufficiently aligned buffer.
+	 * long buf[] does not! (on ia64).
+	 */
+	int cnt = NUM_THREADS;
+	while (--cnt >= 0) {
+		/* As seen in pthread_create(): */
+		clone2(thread1, malloc(16 * 1024), 16 * 1024, 0
+			| CLONE_VM
+			| CLONE_FS
+			| CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM
+			| 0        /* no signal to send on death */
+			, NULL);
+		usleep(20*1000);
+	}
+	clone2(thread2, malloc(16 * 1024), 16 * 1024, 0
+		| CLONE_VM
+		| CLONE_FS
+		| CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM
+		| 0        /* no signal to send on death */
+		, NULL);
+
+	/* Various states leader can be while other thread execve's: */
+	switch (leader_final_action % 3) {
+		case 0: syscall_exit(42); /* leader is dead */
+		case 1: for(;;) pause(); /* leader is in syscall */
+		default: for(;;) continue; /* leader is in userspace */
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	if (readlink("/proc/self/exe", my_name, sizeof(my_name)-1) <= 0)
+		return 1;
+
+	setbuf(stdout, NULL);
+
+	if (argv[1] && strcmp(argv[1], "exe") == 0) {
+		leader_final_action = atoi(argv[2]) + 1;
+		thread_leader();
+	}
+
+	printf("%d: thread leader\n", getpid());
+
+	alarm(argv[1] ? atoi(argv[1]) : 1);
+	thread_leader();
+
+        return 0;
+}
diff --git a/test/x32_lseek.c b/test/x32_lseek.c
new file mode 100644
index 0000000..f95b1a1
--- /dev/null
+++ b/test/x32_lseek.c
@@ -0,0 +1,38 @@
+// Test program which explores whether lseek syscall (not llseek!)
+// on x32 uses 64-bit offset argument.
+// IOW: does _kernel_ truncate it on entry?
+// The answer appears to be "no, full 64-bit offset is used".
+// strace must show it correctly too - tricky if strace itself is x32 one!
+//
+// Build: x86_64-gcc -static -Wall -ox32_lseek x32_lseek.c
+// Run:   $ strace ./x32_lseek 2>&1 | grep lseek | grep 1250999896321
+//        lseek(0, 1250999896321, SEEK_SET) = 1250999896321
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <asm/unistd.h>
+// Ensure we are compiling to 64 bits
+struct bug { int t[sizeof(long) > 4 ? 1 : -1]; };
+int main(int argc, char **argv)
+{
+	long ofs = 0x12345678901;
+	errno = 0;
+	close(0);
+	if (open("/etc/passwd", O_RDONLY))
+		return 1;
+	long r = syscall(
+		(long) (__NR_lseek | 0x40000000), // make x32 call
+		(long) (0),
+		(long) (ofs),
+		(long) (SEEK_SET)
+	);
+	printf("pos:%ld(0x%lx) errno:%m\n", r, r);
+	if (!errno)
+		printf((r == ofs) ? "64-bit offset used\n" : "Kernel truncated offset\n");
+	return 0;
+}
diff --git a/test/x32_mmap.c b/test/x32_mmap.c
new file mode 100644
index 0000000..f7f3ed3
--- /dev/null
+++ b/test/x32_mmap.c
@@ -0,0 +1,49 @@
+// Test program which explores whether mmap's ofs parameter
+// is 64-bit, and whether it needs to be shifted << PAGE_SHIFT.
+// Apparently it is 64-bit and isn't shifted.
+//
+// Build: x86_64-gcc -static -Wall -ox32_mmap x32_mmap.c
+// Typical output:
+// 7f9390696000-7f93906a6000 r--s 12345670000 08:06 2224545 /etc/passwd
+//                                ^^^^^^^^^^^
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <asm/unistd.h>
+// Ensure we are compiling to 64 bits
+struct bug { int t[sizeof(long) > 4 ? 1 : -1]; };
+int main(int argc, char **argv)
+{
+	long ofs = 0x12345670000; // fails if not page-aligned
+	errno = 0;
+	close(0);
+	if (open("/etc/passwd", O_RDONLY))
+		return 1;
+	long r = syscall(
+		(long) (__NR_mmap | 0x40000000), // make x32 call
+		(long) (0),		// start
+		(long) (0x10000),	// len
+		(long) (PROT_READ),	// prot
+		(long) (MAP_SHARED),	// flags
+		(long) (0),		// fd
+		(long) (ofs)		// ofs
+	);
+	printf("ret:0x%lx errno:%m\n", r);
+
+	char buf[16*1024];
+	sprintf(buf, "/proc/%d/maps", getpid());
+	int fd = open(buf, O_RDONLY);
+	if (fd > 0) {
+		int sz = read(fd, buf, sizeof(buf));
+		if (sz > 0)
+			write(1, buf, sz);
+	}
+
+	return 0;
+}
diff --git a/tests/.gitignore b/tests/.gitignore
index 500ae69..5b33416 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -10,6 +10,7 @@
 accept4
 access
 acct
+addkey
 adjtimex
 aio
 alarm
@@ -44,6 +45,9 @@
 execveat
 execveat-v
 faccessat
+fadvise64
+fadvise64_64
+fallocate
 fanotify_mark
 fchdir
 fchmod
@@ -67,8 +71,10 @@
 fsync
 ftruncate
 ftruncate64
+futex
 futimesat
 get_mempolicy
+getcpu
 getcwd
 getdents
 getdents64
@@ -112,6 +118,7 @@
 ipc_msgbuf
 ipc_sem
 ipc_shm
+keyctl
 kill
 ksysent
 ksysent.h
@@ -169,6 +176,7 @@
 openat
 pause
 pc
+perf_event_open
 personality
 pipe
 poll
@@ -183,7 +191,12 @@
 pselect6
 ptrace
 pwritev
+quotactl
+quotactl-v
+quotactl-xfs
+quotactl-xfs-v
 read-write
+readahead
 readdir
 readlink
 readlinkat
@@ -192,10 +205,12 @@
 recvfrom
 recvmmsg-timeout
 recvmsg
+redirect-fds
 remap_file_pages
 rename
 renameat
 renameat2
+request_key
 restart_syscall
 rmdir
 rt_sigpending
@@ -248,7 +263,7 @@
 sigaltstack
 siginfo
 signal_receive
-signalfd
+signalfd4
 sigreturn
 sleep
 socketcall
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9023029..0c24969 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -54,6 +54,7 @@
 	printflags.c \
 	printxval.c \
 	signal2name.c \
+	sprintrc.c \
 	tail_alloc.c \
 	tests.h \
 	tprintf.c \
@@ -68,6 +69,7 @@
 	accept4 \
 	access \
 	acct \
+	add_key \
 	adjtimex \
 	aio \
 	alarm \
@@ -102,6 +104,9 @@
 	execveat \
 	execveat-v \
 	faccessat \
+	fadvise64 \
+	fadvise64_64 \
+	fallocate \
 	fanotify_mark \
 	fchdir \
 	fchmod \
@@ -125,8 +130,10 @@
 	fsync \
 	ftruncate \
 	ftruncate64 \
+	futex \
 	futimesat \
 	get_mempolicy \
+	getcpu \
 	getcwd \
 	getdents \
 	getdents64 \
@@ -170,6 +177,7 @@
 	ipc_msgbuf \
 	ipc_sem \
 	ipc_shm \
+	keyctl \
 	kill \
 	ksysent \
 	lchown \
@@ -225,6 +233,7 @@
 	openat \
 	pause \
 	pc \
+	perf_event_open \
 	personality \
 	pipe \
 	poll \
@@ -239,7 +248,12 @@
 	pselect6 \
 	ptrace \
 	pwritev \
+	quotactl \
+	quotactl-v \
+	quotactl-xfs \
+	quotactl-xfs-v \
 	read-write \
+	readahead \
 	readdir \
 	readlink \
 	readlinkat \
@@ -248,10 +262,12 @@
 	recvfrom \
 	recvmmsg-timeout \
 	recvmsg \
+	redirect-fds \
 	remap_file_pages \
 	rename \
 	renameat \
 	renameat2 \
+	request_key \
 	restart_syscall \
 	rmdir \
 	rt_sigpending \
@@ -304,7 +320,7 @@
 	sigaltstack \
 	siginfo \
 	signal_receive \
-	signalfd \
+	signalfd4 \
 	sigreturn \
 	sleep \
 	socketcall \
@@ -401,6 +417,7 @@
 	accept4.test \
 	access.test \
 	acct.test \
+	add_key.test \
 	adjtimex.test \
 	aio.test \
 	alarm.test \
@@ -434,6 +451,9 @@
 	execveat-v.test \
 	execveat.test \
 	faccessat.test \
+	fadvise64.test \
+	fadvise64_64.test \
+	fallocate.test \
 	fanotify_mark.test \
 	fchdir.test \
 	fchmod.test \
@@ -455,8 +475,10 @@
 	fsync.test \
 	ftruncate.test \
 	ftruncate64.test \
+	futex.test \
 	futimesat.test \
 	get_mempolicy.test \
+	getcpu.test \
 	getcwd.test \
 	getdents.test \
 	getdents64.test \
@@ -500,6 +522,7 @@
 	ipc_msgbuf.test \
 	ipc_sem.test \
 	ipc_shm.test \
+	keyctl.test \
 	kill.test \
 	lchown.test \
 	lchown32.test \
@@ -550,6 +573,7 @@
 	open.test \
 	openat.test \
 	pause.test \
+	perf_event_open.test \
 	personality.test \
 	pipe.test \
 	poll.test \
@@ -564,7 +588,12 @@
 	pselect6.test \
 	ptrace.test \
 	pwritev.test \
+	quotactl.test \
+	quotactl-v.test \
+	quotactl-xfs.test \
+	quotactl-xfs-v.test \
 	read-write.test \
+	readahead.test \
 	readdir.test \
 	readlink.test \
 	readlinkat.test \
@@ -577,6 +606,7 @@
 	rename.test \
 	renameat.test \
 	renameat2.test \
+	request_key.test \
 	rmdir.test \
 	rt_sigpending.test \
 	rt_sigprocmask.test \
@@ -626,7 +656,7 @@
 	sigaction.test \
 	sigaltstack.test \
 	siginfo.test \
-	signalfd.test \
+	signalfd4.test \
 	sigreturn.test \
 	socketcall.test \
 	splice.test \
@@ -700,6 +730,7 @@
 	pc.test \
 	qual_syscall.test \
 	redirect.test \
+	redirect-fds.test \
 	restart_syscall.test \
 	signal_receive.test \
 	strace-E.test \
@@ -722,36 +753,34 @@
 XFAIL_TESTS = $(XFAIL_TESTS_$(MPERS_NAME))
 
 TEST_LOG_COMPILER = env
-AM_TEST_LOG_FLAGS = STRACE_ARCH=$(ARCH) $(srcdir)/run.sh
+AM_TEST_LOG_FLAGS = STRACE_ARCH=$(ARCH) MIPS_ABI=$(MIPS_ABI) $(srcdir)/run.sh
 
 EXTRA_DIST = init.sh run.sh match.awk \
 	     caps.awk \
 	     count-f.expected \
 	     eventfd.expected \
-	     fanotify_mark.expected \
+	     fadvise.h \
 	     filter-unavailable.expected \
 	     fstatat.c \
 	     fstatx.c \
 	     getresugid.c \
-	     ip_mreq.expected \
 	     ipc.sh \
 	     ipc_msgbuf.expected \
 	     ksysent.sed \
 	     lstatx.c \
-	     memfd_create.expected \
 	     mq.expected \
 	     net.expected \
 	     oldselect.expected \
 	     pipe.expected \
 	     ppoll.expected \
 	     ppoll-v.expected \
+	     quotactl.h \
 	     setfsugid.c \
 	     setreugid.c \
 	     setresugid.c \
 	     setugid.c \
 	     sigaction.awk \
 	     sigaltstack.expected \
-	     signalfd.expected \
 	     sockname.c \
 	     statfs.expected \
 	     statx.sh \
@@ -763,6 +792,7 @@
 	     struct_flock.c \
 	     sun_path.expected \
 	     uio.expected \
+	     umode_t.c \
 	     umovestr.expected \
 	     unix-pair-send-recv.expected \
 	     unix-pair-sendto-recvfrom.expected \
@@ -778,7 +808,7 @@
 ksysent.h: $(srcdir)/ksysent.sed
 	echo '#include <asm/unistd.h>' | \
 		$(CPP) $(AM_CPPFLAGS) $(CPPFLAGS) -dM - > $@.t1
-	LC_COLLATE=C sed -n -f $(srcdir)/ksysent.sed < $@.t1 > $@.t2
+	LC_COLLATE=C sed -r -n -f $(srcdir)/ksysent.sed < $@.t1 > $@.t2
 	mv -f $@.t2 $@
 	rm -f $@.t1
 
diff --git a/tests/_newselect.c b/tests/_newselect.c
index be1672e..ae2bc51 100644
--- a/tests/_newselect.c
+++ b/tests/_newselect.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR__newselect
 
diff --git a/tests/access.c b/tests/access.c
index 2920db5..e6f169b 100644
--- a/tests/access.c
+++ b/tests/access.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_access
 
diff --git a/tests/acct.c b/tests/acct.c
index ef11b0b..1cc3fa5 100644
--- a/tests/acct.c
+++ b/tests/acct.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_acct
 
diff --git a/tests/add_key.c b/tests/add_key.c
new file mode 100644
index 0000000..62f4be3
--- /dev/null
+++ b/tests/add_key.c
@@ -0,0 +1,156 @@
+/*
+ * Check decoding of add_key syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __NR_add_key
+
+# include <inttypes.h>
+# include <stdio.h>
+# include <unistd.h>
+
+void
+print_val_str(const void *ptr, const char *str)
+{
+	if (str)
+		printf("%s, ", str);
+	else
+		printf("%p, ", ptr);
+}
+
+void
+do_add_key(const char *type, const char *type_str, const char *desc,
+	const char *desc_str, const char *payload, const char *payload_str,
+	size_t plen, int32_t keyring, const char *keyring_str)
+{
+	long rc = syscall(__NR_add_key, type, desc, payload, plen, keyring);
+	const char *errstr = sprintrc(rc);
+	printf("add_key(");
+	print_val_str(type, type_str);
+	print_val_str(desc, desc_str);
+	print_val_str(payload, payload_str);
+	printf("%zu, ", plen);
+	if (keyring_str)
+		printf("%s", keyring_str);
+	else
+		printf("%d", keyring);
+	printf(") = %s\n", errstr);
+}
+
+# define _STR(_arg) #_arg
+# define ARG_STR(_arg) (_arg), #_arg
+
+int
+main(void)
+{
+	static const char unterminated1[] = { '\1', '\2', '\3', '\4', '\5' };
+	static const char unterminated2[] = { '\6', '\7', '\10', '\11', '\12' };
+	static const char unterminated3[] =
+		{ '\16', '\17', '\20', '\21', '\22' };
+
+	char *bogus_type = tail_memdup(unterminated1, sizeof(unterminated1));
+	char *bogus_desc = tail_memdup(unterminated2, sizeof(unterminated2));
+	char *bogus_payload = tail_memdup(unterminated3, sizeof(unterminated3));
+
+	unsigned i;
+	unsigned j;
+	unsigned k;
+	unsigned l;
+
+	struct {
+		const char *type;
+		const char *str;
+	} types[] = {
+		{ ARG_STR(NULL) },
+		{ (const char *) 0xfffffee1fffffbadULL, NULL },
+		{ bogus_type, NULL },
+		{ ARG_STR("\20\21\22\23\24") },
+		{ ARG_STR("user") },
+	};
+
+	struct {
+		const char *desc;
+		const char *str;
+	} descs[] = {
+		{ ARG_STR(NULL) },
+		{ (const char *) 0xfffff00dfffffca7ULL, NULL },
+		{ bogus_desc, NULL },
+		{ ARG_STR("\25\26\27\30\31") },
+		{ ARG_STR("desc") },
+		{ "overly long description", _STR("overly long ") "..." },
+	};
+
+	struct {
+		const char *pload;
+		const char *str;
+		size_t plen;
+	} payloads[] = {
+		{ ARG_STR(NULL), 0 },
+		{ (const char *) 0xfffffacefffff157ULL, NULL,
+			(size_t) 0xdeadbeefbadc0dedULL },
+		{ bogus_payload, _STR(""), 0 },
+		{ bogus_payload, _STR("\16\17\20\21\22"), 5 },
+		{ bogus_payload, NULL, 10 },
+		{ "overly long payload", _STR("overly long ") "...", 15 },
+	};
+
+	struct {
+		uint32_t keyring;
+		const char *str;
+	} keyrings[] = {
+		{ ARG_STR(0) },
+		{ ARG_STR(1234567890) },
+		{ ARG_STR(-1234567890) },
+		{ -1, "KEY_SPEC_THREAD_KEYRING" },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(types); i++)
+		for (j = 0; j < ARRAY_SIZE(descs); j++)
+			for (k = 0; k < ARRAY_SIZE(payloads); k++)
+				for (l = 0; l < ARRAY_SIZE(keyrings); l++)
+					do_add_key(types[i].type, types[i].str,
+						descs[j].desc, descs[j].str,
+						payloads[k].pload,
+						payloads[k].str,
+						payloads[k].plen,
+						keyrings[l].keyring,
+						keyrings[l].str);
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_add_key");
+
+#endif
diff --git a/tests/add_key.test b/tests/add_key.test
new file mode 100755
index 0000000..eadd8c2
--- /dev/null
+++ b/tests/add_key.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of add_key syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a30 -s12
diff --git a/tests/aio.c b/tests/aio.c
index ab259f4..8717f4f 100644
--- a/tests/aio.c
+++ b/tests/aio.c
@@ -26,13 +26,12 @@
  */
 
 #include "tests.h"
-#include <assert.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <time.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_io_setup \
  && defined __NR_io_submit \
@@ -44,6 +43,12 @@
 int
 main(void)
 {
+	static const long bogus_ctx =
+		(long) 0xface1e55deadbeefLL;
+
+	static const char data2[] =
+		"\0\1\2\3cat test test test 0123456789abcdef";
+
 	const unsigned int sizeof_data0 = 4096;
 	const unsigned int sizeof_data1 = 8192;
 	void *data0 = tail_alloc(sizeof_data0);
@@ -51,17 +56,17 @@
 
 	const struct iocb proto_cb[] = {
 		{
-			.aio_data = 0xfeedface11111111,
+			.aio_data = (unsigned long) 0xfeedface11111111ULL,
 			.aio_reqprio = 11,
 			.aio_buf = (unsigned long) data0,
-			.aio_offset = 0xdeface1facefeed,
+			.aio_offset = (unsigned long) 0xdeface1facefeedULL,
 			.aio_nbytes = sizeof_data0
 		},
 		{
-			.aio_data = 0xfeedface22222222,
+			.aio_data = (unsigned long) 0xfeedface22222222ULL,
 			.aio_reqprio = 22,
 			.aio_buf = (unsigned long) data1,
-			.aio_offset = 0xdeface2cafef00d,
+			.aio_offset = (unsigned long) 0xdeface2cafef00dULL,
 			.aio_nbytes = sizeof_data1
 		}
 	};
@@ -93,26 +98,84 @@
 
 	const struct iocb proto_cbv[] = {
 		{
-			.aio_data = 0xfeed11111111face,
+			.aio_data = (unsigned long) 0xfeed11111111faceULL,
 			.aio_lio_opcode = 7,
 			.aio_reqprio = 111,
 			.aio_buf = (unsigned long) iov0,
-			.aio_offset = 0xdeface1facefeed,
+			.aio_offset = (unsigned long) 0xdeface1facefeedULL,
 			.aio_nbytes = ARRAY_SIZE(proto_iov0)
 		},
 		{
-			.aio_data = 0xfeed22222222face,
+			.aio_data = (unsigned long) 0xfeed22222222faceULL,
 			.aio_lio_opcode = 7,
 			.aio_reqprio = 222,
 			.aio_buf = (unsigned long) iov1,
-			.aio_offset = 0xdeface2cafef00d,
+			.aio_offset = (unsigned long) 0xdeface2cafef00dULL,
 			.aio_nbytes = ARRAY_SIZE(proto_iov1)
 		}
 	};
 	const struct iocb *cbv = tail_memdup(proto_cbv, sizeof(proto_cbv));
 
+	/* For additional decoder testing */
+	const struct iocb proto_cbv2[] = {
+		{
+			.aio_data = 0xbadfacedc0ffeeedULL,
+			.aio_key = 0xdefaced0,
+			.aio_lio_opcode = 0xf00d,
+			.aio_reqprio = 0,
+			.aio_fildes = 0xdefaced1,
+			.aio_buf = 0,
+		},
+		{
+			.aio_data = 0,
+			.aio_key = 0xdefaced0,
+			.aio_lio_opcode = 1,
+			.aio_reqprio = 0xbeef,
+			.aio_fildes = 0xdefaced1,
+			.aio_buf = 0,
+			/* In order to make record valid */
+			.aio_nbytes = (size_t) 0x1020304050607080ULL,
+			.aio_offset = 0xdeadda7abadc0dedULL,
+# ifdef IOCB_FLAG_RESFD
+			.aio_flags = 0xfacef157,
+			.aio_resfd = 0xded1ca7e,
+# endif
+		},
+		{
+			.aio_data = 0,
+			.aio_key = 0xdefaced0,
+			.aio_lio_opcode = 1,
+			.aio_reqprio = 0xbeef,
+			.aio_fildes = 0xdefaced1,
+			.aio_buf = 0xbadc0ffeedefacedULL,
+			.aio_nbytes = 0x8090a0b0c0d0e0f0ULL,
+			.aio_offset = 0xdeadda7abadc0dedULL,
+		},
+		{
+			.aio_data = 0,
+			.aio_key = 0xdefaced0,
+			.aio_lio_opcode = 1,
+			.aio_reqprio = 0xbeef,
+			.aio_fildes = 0xdefaced1,
+			.aio_buf = (unsigned long)data2,
+			.aio_nbytes = sizeof(data2),
+			.aio_offset = 0xdeadda7abadc0ded,
+		},
+		{
+			.aio_data = 0,
+			.aio_key = 0xdefaced0,
+			.aio_lio_opcode = 8,
+			.aio_reqprio = 0xbeef,
+			.aio_fildes = 0xdefaced1,
+			.aio_buf = 0,
+			.aio_nbytes = 0x8090a0b0c0d0e0f0ULL,
+			.aio_offset = 0xdeadda7abadc0dedULL,
+		},
+	};
+	const struct iocb *cbv2 = tail_memdup(proto_cbv2, sizeof(proto_cbv2));
+
 	const struct iocb proto_cbc = {
-		.aio_data = 0xdeadbeefbadc0ded,
+		.aio_data = (unsigned long) 0xdeadbeefbadc0dedULL,
 		.aio_reqprio = 99,
 		.aio_fildes = -42
 	};
@@ -128,6 +191,13 @@
 	};
 	const long *cbvs = tail_memdup(proto_cbvs, sizeof(proto_cbvs));
 
+	const long proto_cbvs2[] = {
+		(long) &cbv2[0], (long) &cbv2[1], (long) &cbv2[2],
+		(long) &cbv2[3], (long) &cbv2[4],
+		(long) NULL, (long) 0xffffffffffffffffLL,
+	};
+	const long *cbvs2 = tail_memdup(proto_cbvs2, sizeof(proto_cbvs2));
+
 	unsigned long *ctx = tail_alloc(sizeof(unsigned long));
 	*ctx = 0;
 
@@ -142,67 +212,150 @@
 	if (open("/dev/zero", O_RDONLY))
 		perror_msg_and_skip("open: %s", "/dev/zero");
 
+	long rc = syscall(__NR_io_setup, 0xdeadbeef, NULL);
+	printf("io_setup(%u, NULL) = %s\n", 0xdeadbeef, sprintrc(rc));
+
+	rc = syscall(__NR_io_setup, lnr, ctx + 1);
+	printf("io_setup(%u, %p) = %s\n", nr, ctx + 1, sprintrc(rc));
+
 	if (syscall(__NR_io_setup, lnr, ctx))
 		perror_msg_and_skip("io_setup");
-	printf("io_setup(%u, [%lu]) = 0\n", nr, *ctx);
+	printf("io_setup(%u, [%#lx]) = 0\n", nr, *ctx);
 
-	assert(syscall(__NR_io_submit, *ctx, -1L, cbs) == -1);
-	printf("io_submit(%lu, -1, %p) = -1 %s (%m)\n",
-	       *ctx, cbs, errno2name());
+	rc = syscall(__NR_io_submit, bogus_ctx, (long) 0xca7faceddeadf00dLL,
+		     NULL);
+	printf("io_submit(%#lx, %ld, NULL) = %s\n",
+	       bogus_ctx, (long) 0xca7faceddeadf00dLL, sprintrc(rc));
 
-	if (syscall(__NR_io_submit, *ctx, nr, cbs) != (long) nr)
+	rc = syscall(__NR_io_submit, *ctx, nr, cbs + nr);
+	printf("io_submit(%#lx, %ld, %p) = %s\n",
+	       *ctx, (long) nr, cbs + nr, sprintrc(rc));
+
+	rc = syscall(__NR_io_submit, *ctx, -1L, cbs);
+	printf("io_submit(%#lx, -1, %p) = %s\n",
+	       *ctx, cbs, sprintrc(rc));
+
+	rc = syscall(__NR_io_submit, *ctx, nr, cbs);
+	if (rc != (long) nr)
 		perror_msg_and_skip("io_submit");
-	printf("io_submit(%lu, %u, ["
-		"{data=%#llx, pread, reqprio=11, fildes=0, "
-			"buf=%p, nbytes=%u, offset=%lld}, "
-		"{data=%#llx, pread, reqprio=22, fildes=0, "
-			"buf=%p, nbytes=%u, offset=%lld}"
-		"]) = %u\n",
+	printf("io_submit(%#lx, %u, ["
+	       "{data=%#" PRI__x64 ", pread, reqprio=11, fildes=0, "
+	               "buf=%p, nbytes=%u, offset=%" PRI__d64 "}, "
+	       "{data=%#" PRI__x64 ", pread, reqprio=22, fildes=0, "
+	               "buf=%p, nbytes=%u, offset=%" PRI__d64 "}"
+	       "]) = %s\n",
 	       *ctx, nr,
-	       (unsigned long long) cb[0].aio_data, data0,
-	       sizeof_data0, (long long) cb[0].aio_offset,
-	       (unsigned long long) cb[1].aio_data, data1,
-	       sizeof_data1, (long long) cb[1].aio_offset,
-	       nr);
+	       cb[0].aio_data, data0, sizeof_data0, cb[0].aio_offset,
+	       cb[1].aio_data, data1, sizeof_data1, cb[1].aio_offset,
+	       sprintrc(rc));
 
-	assert(syscall(__NR_io_getevents, *ctx, nr, nr + 1, ev, ts) == (long) nr);
-	printf("io_getevents(%lu, %u, %u, ["
-		"{data=%#llx, obj=%p, res=%u, res2=0}, "
-		"{data=%#llx, obj=%p, res=%u, res2=0}"
-		"], {0, 123456789}) = %u\n",
-	       *ctx, nr, nr + 1,
-	       (unsigned long long) cb[0].aio_data, &cb[0], sizeof_data0,
-	       (unsigned long long) cb[1].aio_data, &cb[1], sizeof_data1,
-	       nr);
+	rc = syscall(__NR_io_getevents, bogus_ctx,
+		     (long) 0xca7faceddeadf00dLL, (long) 0xba5e1e505ca571e0LL,
+		     ev + 1, NULL);
+	printf("io_getevents(%#lx, %ld, %ld, %p, NULL) = %s\n",
+	       bogus_ctx, (long) 0xca7faceddeadf00dLL,
+	       (long) 0xba5e1e505ca571e0LL, ev + 1, sprintrc(rc));
 
-	assert(syscall(__NR_io_cancel, *ctx, cbc, ev) == -1);
-	printf("io_cancel(%lu, {data=%#llx, pread, reqprio=99, fildes=-42}, %p) "
-		"= -1 %s (%m)\n",
-	       *ctx, (unsigned long long) cbc->aio_data, ev, errno2name());
+	rc = syscall(__NR_io_getevents, bogus_ctx,
+		     (long) 0xca7faceddeadf00dLL, (long) 0xba5e1e505ca571e0LL,
+		     NULL, ts + 1);
+	printf("io_getevents(%#lx, %ld, %ld, NULL, %p) = %s\n",
+	       bogus_ctx, (long) 0xca7faceddeadf00dLL,
+	       (long) 0xba5e1e505ca571e0LL, ts + 1, sprintrc(rc));
 
-	if (syscall(__NR_io_submit, *ctx, nr, cbvs) != (long) nr)
+	rc = syscall(__NR_io_getevents, *ctx, nr, nr + 1, ev, ts);
+	printf("io_getevents(%#lx, %ld, %ld, ["
+	       "{data=%#" PRI__x64 ", obj=%p, res=%u, res2=0}, "
+	       "{data=%#" PRI__x64 ", obj=%p, res=%u, res2=0}"
+	       "], {0, 123456789}) = %s\n",
+	       *ctx, (long) nr, (long) (nr + 1),
+	       cb[0].aio_data, &cb[0], sizeof_data0,
+	       cb[1].aio_data, &cb[1], sizeof_data1,
+	       sprintrc(rc));
+
+	rc = syscall(__NR_io_cancel, bogus_ctx, NULL, NULL);
+	printf("io_cancel(%#lx, NULL, NULL) = %s\n", bogus_ctx, sprintrc(rc));
+
+	rc = syscall(__NR_io_cancel, *ctx, cbc + 1, ev);
+	printf("io_cancel(%#lx, %p, %p) = %s\n", *ctx, cbc + 1, ev,
+	       sprintrc(rc));
+
+	rc = syscall(__NR_io_cancel, *ctx, cbc, ev);
+	printf("io_cancel(%#lx, {data=%#" PRI__x64
+	       ", pread, reqprio=99, fildes=-42}, %p) = %s\n",
+	       *ctx, cbc->aio_data, ev, sprintrc(rc));
+
+	rc = syscall(__NR_io_submit, (unsigned long) 0xfacef157beeff00dULL,
+		     (long) 0xdeadc0defacefeedLL, NULL);
+	printf("io_submit(%#lx, %ld, NULL) = %s\n",
+	       (long) 0xfacef157beeff00dULL,
+	       (long) 0xdeadc0defacefeedLL, sprintrc(rc));
+
+	rc = syscall(__NR_io_submit, *ctx, -1L, cbvs + nr);
+	printf("io_submit(%#lx, %ld, %p) = %s\n",
+	       *ctx, -1L, cbvs + nr, sprintrc(rc));
+
+	rc = syscall(__NR_io_submit, *ctx, 1057L, cbvs2);
+	printf("io_submit(%#lx, %ld, ["
+	       "{data=%#" PRI__x64 ", key=%u, %hu /* SUB_??? */, fildes=%d}, "
+	       "{key=%u, pwrite, reqprio=%hd, fildes=%d, str=NULL"
+	               ", nbytes=%" PRI__u64 ", offset=%" PRI__d64
+# ifdef IOCB_FLAG_RESFD
+	               ", resfd=%d, flags=%x"
+# endif
+	               "}, "
+	       "{key=%u, pwrite, reqprio=%hd, fildes=%d, buf=%#" PRI__x64
+	               ", nbytes=%" PRI__u64 ", offset=%" PRI__d64 "}, "
+	       "{key=%u, pwrite, reqprio=%hd, fildes=%d"
+	               ", str=\"\\0\\1\\2\\3%.28s\"..."
+	               ", nbytes=%" PRI__u64 ", offset=%" PRI__d64 "}, "
+	       "{key=%u, pwritev, reqprio=%hd, fildes=%d, buf=%#" PRI__x64
+	               ", nbytes=%" PRI__u64 ", offset=%" PRI__d64 "}"
+	       ", {NULL}, {%#lx}, %p]) = %s\n",
+	       *ctx, 1057L,
+	       cbv2[0].aio_data, cbv2[0].aio_key,
+	       cbv2[0].aio_lio_opcode, cbv2[0].aio_fildes,
+	       cbv2[1].aio_key, cbv2[1].aio_reqprio, cbv2[1].aio_fildes,
+	       cbv2[1].aio_nbytes, cbv2[1].aio_offset,
+# ifdef IOCB_FLAG_RESFD
+	       cbv2[1].aio_resfd, cbv2[1].aio_flags,
+# endif
+	       cbv2[2].aio_key, cbv2[2].aio_reqprio, cbv2[2].aio_fildes,
+	       cbv2[2].aio_buf, cbv2[2].aio_nbytes, cbv2[2].aio_offset,
+	       cbv2[3].aio_key, cbv2[3].aio_reqprio, cbv2[3].aio_fildes,
+	       data2 + 4, cbv2[3].aio_nbytes, cbv2[3].aio_offset,
+	       cbv2[4].aio_key, cbv2[4].aio_reqprio, cbv2[4].aio_fildes,
+	       cbv2[4].aio_buf, cbv2[4].aio_nbytes, cbv2[4].aio_offset,
+	       cbvs2[6], cbvs2 + 7, sprintrc(rc));
+
+	rc = syscall(__NR_io_submit, *ctx, nr, cbvs);
+	if (rc != (long) nr)
 		perror_msg_and_skip("io_submit");
-	printf("io_submit(%lu, %u, ["
-		"{data=%#llx, preadv, reqprio=%hd, fildes=0, "
-			"iovec=[{iov_base=%p, iov_len=%u}"
-			", {iov_base=%p, iov_len=%u}], offset=%lld}, "
-		"{data=%#llx, preadv, reqprio=%hd, fildes=0, "
-			"iovec=[{iov_base=%p, iov_len=%u}"
-			", {iov_base=%p, iov_len=%u}], offset=%lld}"
-		"]) = %u\n",
+	printf("io_submit(%#lx, %u, ["
+	       "{data=%#" PRI__x64 ", preadv, reqprio=%hd, fildes=0, "
+	               "iovec=[{iov_base=%p, iov_len=%u}"
+	               ", {iov_base=%p, iov_len=%u}], offset=%" PRI__d64 "}, "
+	       "{data=%#" PRI__x64 ", preadv, reqprio=%hd, fildes=0, "
+	               "iovec=[{iov_base=%p, iov_len=%u}"
+	               ", {iov_base=%p, iov_len=%u}], offset=%" PRI__d64 "}"
+	       "]) = %s\n",
 	       *ctx, nr,
-	       (unsigned long long) cbv[0].aio_data, cbv[0].aio_reqprio,
+	       cbv[0].aio_data, cbv[0].aio_reqprio,
 	       iov0[0].iov_base, (unsigned int) iov0[0].iov_len,
 	       iov0[1].iov_base, (unsigned int) iov0[1].iov_len,
-	       (long long) cbv[0].aio_offset,
-	       (unsigned long long) cbv[1].aio_data, cbv[1].aio_reqprio,
+	       cbv[0].aio_offset,
+	       cbv[1].aio_data, cbv[1].aio_reqprio,
 	       iov1[0].iov_base, (unsigned int) iov1[0].iov_len,
 	       iov1[1].iov_base, (unsigned int) iov1[1].iov_len,
-	       (long long) cbv[1].aio_offset,
-	       nr);
+	       cbv[1].aio_offset,
+	       sprintrc(rc));
 
-	assert(syscall(__NR_io_destroy, *ctx) == 0);
-	printf("io_destroy(%lu) = 0\n", *ctx);
+	rc = syscall(__NR_io_destroy, bogus_ctx);
+	printf("io_destroy(%#lx) = %s\n",
+	       bogus_ctx, sprintrc(rc));
+
+	rc = syscall(__NR_io_destroy, *ctx);
+	printf("io_destroy(%#lx) = %s\n", *ctx, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/alarm.c b/tests/alarm.c
index fc10b66..f954dcf 100644
--- a/tests/alarm.c
+++ b/tests/alarm.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_alarm
 
diff --git a/tests/attach-f-p.c b/tests/attach-f-p.c
index 8e0f205..c75deb6 100644
--- a/tests/attach-f-p.c
+++ b/tests/attach-f-p.c
@@ -31,11 +31,9 @@
 #include <assert.h>
 #include <errno.h>
 #include <pthread.h>
-#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <time.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <unistd.h>
 
 #define N 3
@@ -45,38 +43,24 @@
 	pid_t pid;
 } retval_t;
 
-typedef struct {
-	sigset_t set;
-	unsigned int no;
-} thread_arg_t;
-
 static const char text_parent[] = "attach-f-p.test parent";
 static const char *child[N] = {
 	"attach-f-p.test child 0",
 	"attach-f-p.test child 1",
 	"attach-f-p.test child 2"
 };
-static const int sigs[N] = { SIGALRM, SIGUSR1, SIGUSR2 };
-static const struct itimerspec its[N] = {
-	{ .it_value.tv_sec = 1 },
-	{ .it_value.tv_sec = 2 },
-	{ .it_value.tv_sec = 3 }
-};
-static thread_arg_t args[N] = {
-	{ .no = 0 },
-	{ .no = 1 },
-	{ .no = 2 }
-};
+typedef int pipefd[2];
+static pipefd pipes[N];
 
 static void *
 thread(void *a)
 {
-	thread_arg_t *arg = a;
-	int signo;
-	errno = sigwait(&arg->set, &signo);
-	if (errno)
-		perror_msg_and_fail("sigwait");
-	assert(chdir(child[arg->no]) == -1);
+	unsigned int no = (long) a;
+	int i;
+
+	if (read(pipes[no][0], &i, sizeof(i)) != (int) sizeof(i))
+		perror_msg_and_fail("read[%u]", no);
+	assert(chdir(child[no]) == -1);
 	retval_t retval = { .pid = syscall(__NR_gettid) };
 	return retval.ptr;
 }
@@ -84,31 +68,17 @@
 int
 main(void)
 {
-	static timer_t timerid[N];
 	pthread_t t[N];
 	unsigned int i;
 
-	for (i = 0; i < N; ++i) {
-		sigemptyset(&args[i].set);
-		sigaddset(&args[i].set, sigs[i]);
-
-		errno = pthread_sigmask(SIG_BLOCK, &args[i].set, NULL);
-		if (errno)
-			perror_msg_and_fail("pthread_sigmask");
-	}
+	if (write(3, "", 0) != 0)
+		perror_msg_and_fail("write");
 
 	for (i = 0; i < N; ++i) {
-		struct sigevent sev = {
-			.sigev_notify = SIGEV_SIGNAL,
-			.sigev_signo = sigs[i]
-		};
-		if (timer_create(CLOCK_MONOTONIC, &sev, &timerid[i]))
-			perror_msg_and_skip("timer_create");
+		if (pipe(pipes[i]))
+			perror_msg_and_fail("pipe");
 
-		if (timer_settime(timerid[i], 0, &its[i], NULL))
-			perror_msg_and_fail("timer_settime");
-
-		errno = pthread_create(&t[i], NULL, thread, (void *) &args[i]);
+		errno = pthread_create(&t[i], NULL, thread, (void *) (long) i);
 		if (errno)
 			perror_msg_and_fail("pthread_create");
 	}
@@ -117,6 +87,10 @@
 		perror_msg_and_fail("write");
 
 	for (i = 0; i < N; ++i) {
+		/* sleep a bit to let the tracer catch up */
+		sleep(1);
+		if (write(pipes[i][1], &i, sizeof(i)) != (int) sizeof(i))
+			perror_msg_and_fail("write[%u]", i);
 		retval_t retval;
 		errno = pthread_join(t[i], &retval.ptr);
 		if (errno)
@@ -128,12 +102,7 @@
 	}
 
 	/* sleep a bit more to let the tracer catch up */
-	if (timer_settime(timerid[0], 0, &its[0], NULL))
-		perror_msg_and_fail("timer_settime");
-	int signo;
-	errno = sigwait(&args[0].set, &signo);
-	if (errno)
-		perror_msg_and_fail("sigwait");
+	sleep(1);
 
 	pid_t pid = getpid();
 	assert(chdir(text_parent) == -1);
diff --git a/tests/attach-f-p.test b/tests/attach-f-p.test
index 02230a0..030659a 100755
--- a/tests/attach-f-p.test
+++ b/tests/attach-f-p.test
@@ -44,6 +44,6 @@
 		fail_ 'set_ptracer_any sleep failed'
 done
 
-run_strace -a32 -f -echdir -esignal=none -p $tracee_pid
+run_strace -a32 -f -echdir -p $tracee_pid
 match_diff "$LOG" "$EXP"
 rm -f "$EXP" "$OUT"
diff --git a/tests/attach-p-cmd-cmd.c b/tests/attach-p-cmd-cmd.c
index d2b3ca1..edfff20 100644
--- a/tests/attach-p-cmd-cmd.c
+++ b/tests/attach-p-cmd-cmd.c
@@ -28,17 +28,19 @@
  */
 
 #include "tests.h"
-#include <assert.h>
 #include <stdio.h>
 #include <unistd.h>
 
 int
 main(void)
 {
-	static const char text[] = "attach-p-cmd.test cmd";
+	static const char dir[] = "attach-p-cmd.test cmd";
 	pid_t pid = getpid();
-	assert(chdir(text) == -1);
-	printf("%-5d chdir(\"%s\") = -1 ENOENT (%m)\n"
-	       "%-5d +++ exited with 0 +++\n", pid, text, pid);
+	int rc = chdir(dir);
+
+	printf("%-5d chdir(\"%s\") = %d %s (%m)\n"
+	       "%-5d +++ exited with 0 +++\n",
+	       pid, dir, rc, errno2name(), pid);
+
 	return 0;
 }
diff --git a/tests/attach-p-cmd-p.c b/tests/attach-p-cmd-p.c
index a059ce5..d63371d 100644
--- a/tests/attach-p-cmd-p.c
+++ b/tests/attach-p-cmd-p.c
@@ -28,8 +28,8 @@
  */
 
 #include "tests.h"
-#include <errno.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -39,14 +39,8 @@
 }
 
 int
-main(int ac, char **av)
+main(void)
 {
-	if (ac < 2)
-		error_msg_and_fail("missing operand");
-
-	if (ac > 2)
-		error_msg_and_fail("extra operand");
-
 	const struct sigaction act = { .sa_handler = handler };
 	if (sigaction(SIGALRM, &act, NULL))
 		perror_msg_and_skip("sigaction");
@@ -56,8 +50,17 @@
 	if (sigprocmask(SIG_UNBLOCK, &mask, NULL))
 		perror_msg_and_skip("sigprocmask");
 
-	alarm(atoi(av[1]));
+	alarm(1);
 	pause();
 
-	return !(chdir("attach-p-cmd.test -p") && ENOENT == errno);
+	static const char dir[] = "attach-p-cmd.test -p";
+	pid_t pid = getpid();
+	int rc = chdir(dir);
+
+	printf("%-5d --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---\n"
+	       "%-5d chdir(\"%s\") = %d %s (%m)\n"
+	       "%-5d +++ exited with 0 +++\n",
+	       pid, pid, dir, rc, errno2name(), pid);
+
+	return 0;
 }
diff --git a/tests/attach-p-cmd.test b/tests/attach-p-cmd.test
index f8c1d1c..2779719 100755
--- a/tests/attach-p-cmd.test
+++ b/tests/attach-p-cmd.test
@@ -32,9 +32,10 @@
 run_prog_skip_if_failed \
 	kill -0 $$
 run_prog ./attach-p-cmd-cmd > /dev/null
-run_prog ./attach-p-cmd-p 1 > /dev/null
+run_prog ./attach-p-cmd-p > /dev/null
 
-./set_ptracer_any ./attach-p-cmd-p 1 > "$OUT" &
+rm -f "$OUT"
+./set_ptracer_any ./attach-p-cmd-p >> "$OUT" &
 tracee_pid=$!
 
 while ! [ -s "$OUT" ]; do
@@ -43,11 +44,5 @@
 done
 
 run_strace -a30 -echdir -p $tracee_pid ./attach-p-cmd-cmd > "$OUT"
-{
-printf '%-5d --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---\n' $tracee_pid
-printf '%-5d chdir("attach-p-cmd.test -p") = -1 ENOENT (No such file or directory)\n' $tracee_pid
-printf '%-5d +++ exited with 0 +++\n' $tracee_pid
-} >> "$OUT"
-
 match_diff "$LOG" "$OUT"
 rm -f "$OUT"
diff --git a/tests/bpf.c b/tests/bpf.c
index d9b05e5..5a1fcdc 100644
--- a/tests/bpf.c
+++ b/tests/bpf.c
@@ -29,7 +29,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined HAVE_UNION_BPF_ATTR_LOG_BUF && defined __NR_bpf
 # include <linux/bpf.h>
diff --git a/tests/brk.c b/tests/brk.c
index ed311aa..572ebd6 100644
--- a/tests/brk.c
+++ b/tests/brk.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_brk
 
diff --git a/tests/btrfs.c b/tests/btrfs.c
index e5940ce..d600534 100644
--- a/tests/btrfs.c
+++ b/tests/btrfs.c
@@ -1567,9 +1567,7 @@
 {
 	struct btrfs_ioctl_dev_replace_args args = {
 		.cmd = BTRFS_IOCTL_DEV_REPLACE_CMD_START,
-		.start = {
-			.srcdevid = 1,
-		},
+		.start.srcdevid = 1
 	};
 	strcpy((char *)args.start.srcdev_name, "/dev/sda1");
 	strcpy((char *)args.start.tgtdev_name, "/dev/sdb1");
diff --git a/tests/chmod.c b/tests/chmod.c
index 056101c..f6f98ec 100644
--- a/tests/chmod.c
+++ b/tests/chmod.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016 Anchit Jain <anchitjain1234@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +27,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_chmod
 
@@ -40,30 +41,20 @@
 {
 	static const char fname[] = "chmod_test_file";
 
-	if (open(fname, O_CREAT|O_RDONLY, 0400) == -1)
+	if (open(fname, O_CREAT|O_RDONLY, 0400) < 0)
 		perror_msg_and_fail("open");
 
-	int chmod_res = syscall(__NR_chmod, fname, 0600);
+	long rc = syscall(__NR_chmod, fname, 0600);
+	printf("chmod(\"%s\", 0600) = %s\n", fname, sprintrc(rc));
 
-	if (chmod_res == 0) {
-		printf("chmod(\"%s\", 0600) = 0\n", fname);
-	} else {
-		if (errno == ENOSYS) {
-			printf("chmod(\"%s\", 0600) = -1 ENOSYS (%m)\n", fname);
-		} else {
-			perror_msg_and_fail("chmod");
-		}
-	}
-
-	if (unlink(fname) == -1)
+	if (unlink(fname))
 		perror_msg_and_fail("unlink");
 
-	if (chmod_res == 0) {
-		if (syscall(__NR_chmod, fname, 0600) != -1)
-			perror_msg_and_fail("chmod");
+	rc = syscall(__NR_chmod, fname, 051);
+	printf("chmod(\"%s\", 051) = %s\n", fname, sprintrc(rc));
 
-		printf("chmod(\"%s\", 0600) = -1 ENOENT (%m)\n", fname);
-	}
+	rc = syscall(__NR_chmod, fname, 004);
+	printf("chmod(\"%s\", 004) = %s\n", fname, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/chown.c b/tests/chown.c
index 59a4d63..12aa8b7 100644
--- a/tests/chown.c
+++ b/tests/chown.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_chown
 
diff --git a/tests/chown32.c b/tests/chown32.c
index 5e590a8..4fffd76 100644
--- a/tests/chown32.c
+++ b/tests/chown32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_chown32
 
diff --git a/tests/chroot.c b/tests/chroot.c
index fb9548c..a084cf3 100644
--- a/tests/chroot.c
+++ b/tests/chroot.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_chroot
 
diff --git a/tests/clock_adjtime.c b/tests/clock_adjtime.c
index 93c58b7..01089b5 100644
--- a/tests/clock_adjtime.c
+++ b/tests/clock_adjtime.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_clock_adjtime
 
diff --git a/tests/clock_nanosleep.c b/tests/clock_nanosleep.c
index 1c4c427..d9b68fd 100644
--- a/tests/clock_nanosleep.c
+++ b/tests/clock_nanosleep.c
@@ -33,7 +33,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/time.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 static void
 handler(int signo)
@@ -47,7 +47,7 @@
 		struct timespec ts;
 		uint32_t pad[2];
 	} req = {
-		.ts = { .tv_nsec = 0xc0de1 },
+		.ts.tv_nsec = 0xc0de1,
 		.pad = { 0xdeadbeef, 0xbadc0ded }
 	}, rem = {
 		.ts = { .tv_sec = 0xc0de2, .tv_nsec = 0xc0de3 },
diff --git a/tests/clock_xettime.c b/tests/clock_xettime.c
index 633351a..04dddf6 100644
--- a/tests/clock_xettime.c
+++ b/tests/clock_xettime.c
@@ -30,7 +30,7 @@
 #include <stdint.h>
 #include <time.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_clock_getres \
  && defined __NR_clock_gettime \
diff --git a/tests/copy_file_range.c b/tests/copy_file_range.c
index 0e563d6..f3ec5b4 100644
--- a/tests/copy_file_range.c
+++ b/tests/copy_file_range.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_copy_file_range
 
diff --git a/tests/creat.c b/tests/creat.c
index 8572e7f..f22fdaa 100644
--- a/tests/creat.c
+++ b/tests/creat.c
@@ -1,23 +1,11 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_creat
 
-# include <stdio.h>
-# include <unistd.h>
-
-# define TMP_FILE "creat"
-
-int
-main(void)
-{
-	long rc = syscall(__NR_creat, TMP_FILE, 0400);
-	printf("creat(\"%s\", %#o) = %ld %s (%m)\n",
-	       TMP_FILE, 0400, rc, errno2name());
-
-	puts("+++ exited with 0 +++");
-	return 0;
-}
+# define TEST_SYSCALL_NR __NR_creat
+# define TEST_SYSCALL_STR "creat"
+# include "umode_t.c"
 
 #else
 
diff --git a/tests/creat.test b/tests/creat.test
index 49fddd2..069648f 100755
--- a/tests/creat.test
+++ b/tests/creat.test
@@ -3,4 +3,4 @@
 # Check creat syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a21
+run_strace_match_diff -a20
diff --git a/tests/dup2.c b/tests/dup2.c
index 70d8f3e..04a261c 100644
--- a/tests/dup2.c
+++ b/tests/dup2.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_dup2
 
diff --git a/tests/dup3.c b/tests/dup3.c
index 884331a..2611dd8 100644
--- a/tests/dup3.c
+++ b/tests/dup3.c
@@ -1,6 +1,6 @@
 #include "tests.h"
 #include <fcntl.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_dup3 && defined O_CLOEXEC
 
diff --git a/tests/epoll_create.c b/tests/epoll_create.c
index 4be06c4..1f24852 100644
--- a/tests/epoll_create.c
+++ b/tests/epoll_create.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_epoll_create
 
diff --git a/tests/epoll_create1.c b/tests/epoll_create1.c
index d348492..cd905ec 100644
--- a/tests/epoll_create1.c
+++ b/tests/epoll_create1.c
@@ -27,7 +27,7 @@
 
 #include "tests.h"
 #include <fcntl.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_epoll_create1 && defined O_CLOEXEC
 
@@ -38,16 +38,11 @@
 main(void)
 {
 	long rc = syscall(__NR_epoll_create1, O_CLOEXEC);
-	if (rc == -1) {
-		printf("epoll_create1(EPOLL_CLOEXEC) = -1 %s (%m)\n",
-		       errno2name());
-	} else {
-		printf("epoll_create1(EPOLL_CLOEXEC) = %ld\n", rc);
-	}
+	printf("epoll_create1(EPOLL_CLOEXEC) = %s\n", sprintrc(rc));
 
 	rc = syscall(__NR_epoll_create1, O_CLOEXEC | O_NONBLOCK);
-	printf("epoll_create1(EPOLL_CLOEXEC|%#x) = %ld %s (%m)\n",
-	       O_NONBLOCK, rc, errno2name());
+	printf("epoll_create1(EPOLL_CLOEXEC|%#x) = %s\n",
+	       O_NONBLOCK, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/epoll_ctl.c b/tests/epoll_ctl.c
index 231e271..8b46f4e 100644
--- a/tests/epoll_ctl.c
+++ b/tests/epoll_ctl.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_epoll_ctl
 
diff --git a/tests/epoll_pwait.c b/tests/epoll_pwait.c
index acd4218..27337ec 100644
--- a/tests/epoll_pwait.c
+++ b/tests/epoll_pwait.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_epoll_pwait
 
diff --git a/tests/epoll_wait.c b/tests/epoll_wait.c
index c2eb563..038bf1f 100644
--- a/tests/epoll_wait.c
+++ b/tests/epoll_wait.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_epoll_wait
 
diff --git a/tests/eventfd.c b/tests/eventfd.c
index 8b08443..d6ad649 100644
--- a/tests/eventfd.c
+++ b/tests/eventfd.c
@@ -28,7 +28,7 @@
 #include "tests.h"
 #include <fcntl.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_eventfd2 && defined O_CLOEXEC
 
diff --git a/tests/execve-v.c b/tests/execve-v.c
index 26bc9d6..4506c63 100644
--- a/tests/execve-v.c
+++ b/tests/execve-v.c
@@ -1,3 +1,3 @@
 /* This file is part of execve-v strace test. */
-#define VERBOSE_EXECVE
+#define VERBOSE 1
 #include "execve.c"
diff --git a/tests/execve.c b/tests/execve.c
index 852eebf..74749e7 100644
--- a/tests/execve.c
+++ b/tests/execve.c
@@ -59,7 +59,7 @@
 	execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\""
 	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ???]"
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       ", [\"%s\", \"%s\", %p, %p, %p, ???]"
 #else
 	       ", [/* 5 vars, unterminated */]"
@@ -67,7 +67,7 @@
 	       ") = -1 ENOENT (%m)\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
 	       argv[3], argv[4], argv[5]
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       , q_envp[0], q_envp[1], envp[2], envp[3], envp[4]
 #endif
 	       );
@@ -77,28 +77,28 @@
 
 	execve(FILENAME, tail_argv, tail_envp);
 	printf("execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       ", [\"%s\", \"%s\"]"
 #else
 	       ", [/* 2 vars */]"
 #endif
 	       ") = -1 ENOENT (%m)\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2]
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       , q_envp[0], q_envp[1]
 #endif
 	       );
 
 	execve(FILENAME, tail_argv + 2, tail_envp + 1);
 	printf("execve(\"%s\", [\"%s\"]"
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       ", [\"%s\"]"
 #else
 	       ", [/* 1 var */]"
 #endif
 	       ") = -1 ENOENT (%m)\n",
 	       Q_FILENAME, q_argv[2]
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       , q_envp[1]
 #endif
 	       );
@@ -109,7 +109,7 @@
 
 	execve(FILENAME, empty, empty);
 	printf("execve(\"%s\", []"
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	       ", []"
 #else
 	       ", [/* 0 vars */]"
@@ -132,12 +132,12 @@
 	printf("execve(\"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
 	for (i = 1; i < DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	printf(", \"%s\"", a[i]);
 #else
 	printf(", ...");
 #endif
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	printf("], [\"%.*s\"...", DEFAULT_STRLEN, b[0]);
 	for (i = 1; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", b[i]);
@@ -150,7 +150,7 @@
 	printf("execve(\"%s\", [\"%s\"", Q_FILENAME, a[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
-#ifdef VERBOSE_EXECVE
+#if VERBOSE
 	printf("], [\"%s\"", b[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", b[i]);
diff --git a/tests/execveat-v.c b/tests/execveat-v.c
index 530ddfc..ff4de2e 100644
--- a/tests/execveat-v.c
+++ b/tests/execveat-v.c
@@ -1,3 +1,3 @@
 /* This file is part of execveat-v strace test. */
-#define VERBOSE_EXECVEAT
+#define VERBOSE 1
 #include "execveat.c"
diff --git a/tests/execveat.c b/tests/execveat.c
index 972fc17..4e444a2 100644
--- a/tests/execveat.c
+++ b/tests/execveat.c
@@ -30,7 +30,7 @@
 #include "tests.h"
 #include <stdio.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_execveat
 
@@ -62,7 +62,7 @@
 	syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100);
 	printf("execveat(AT_FDCWD, \"%s\""
 	       ", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ???]"
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       ", [\"%s\", \"%s\", %p, %p, %p, ???]"
 #else
 	       ", [/* 5 vars, unterminated */]"
@@ -70,7 +70,7 @@
 	       ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
 	       argv[3], argv[4], argv[5],
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       q_envp[0], q_envp[1], envp[2], envp[3], envp[4],
 #endif
 	       errno2name());
@@ -80,28 +80,28 @@
 
 	syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100);
 	printf("execveat(AT_FDCWD, \"%s\", [\"%s\", \"%s\", \"%s\"]"
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       ", [\"%s\", \"%s\"]"
 #else
 	       ", [/* 2 vars */]"
 #endif
 	       ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
 	       Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       q_envp[0], q_envp[1],
 #endif
 	       errno2name());
 
 	syscall(__NR_execveat, -100, FILENAME, tail_argv + 2, tail_envp + 1, 0x1100);
 	printf("execveat(AT_FDCWD, \"%s\", [\"%s\"]"
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       ", [\"%s\"]"
 #else
 	       ", [/* 1 var */]"
 #endif
 	       ", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
 	       Q_FILENAME, q_argv[2],
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       q_envp[1],
 #endif
 	       errno2name());
@@ -112,7 +112,7 @@
 
 	syscall(__NR_execveat, -100, FILENAME, empty, empty, 0x1100);
 	printf("execveat(AT_FDCWD, \"%s\", []"
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	       ", []"
 #else
 	       ", [/* 0 vars */]"
@@ -136,12 +136,12 @@
 	printf("execveat(AT_FDCWD, \"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
 	for (i = 1; i < DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	printf(", \"%s\"", a[i]);
 #else
 	printf(", ...");
 #endif
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	printf("], [\"%.*s\"...", DEFAULT_STRLEN, b[0]);
 	for (i = 1; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", b[i]);
@@ -155,7 +155,7 @@
 	printf("execveat(AT_FDCWD, \"%s\", [\"%s\"", Q_FILENAME, a[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", a[i]);
-#ifdef VERBOSE_EXECVEAT
+#if VERBOSE
 	printf("], [\"%s\"", b[1]);
 	for (i = 2; i <= DEFAULT_STRLEN; ++i)
 		printf(", \"%s\"", b[i]);
diff --git a/tests/faccessat.c b/tests/faccessat.c
index 06a6ae3..c21039d 100644
--- a/tests/faccessat.c
+++ b/tests/faccessat.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_faccessat
 
diff --git a/tests/signalfd.c b/tests/fadvise.h
similarity index 60%
copy from tests/signalfd.c
copy to tests/fadvise.h
index 7b1d6ce..bc79091 100644
--- a/tests/signalfd.c
+++ b/tests/fadvise.h
@@ -1,5 +1,8 @@
 /*
- * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Common definitions for fadvise64 and fadvise64_64 tests.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,30 +28,37 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "tests.h"
-#include <fcntl.h>
+#ifndef STRACE_TESTS_FADVISE_H
+#define STRACE_TESTS_FADVISE_H
 
-#if defined HAVE_SYS_SIGNALFD_H && defined HAVE_SIGNALFD && defined O_CLOEXEC
-
-# include <signal.h>
+# include <limits.h>
+# include <stdio.h>
 # include <unistd.h>
-# include <sys/signalfd.h>
+
+# include "xlat.h"
+# include "xlat/advise.h"
+
+# if WORDS_BIGENDIAN
+#  define LL_PAIR(HI, LO) (HI), (LO)
+# else
+#  define LL_PAIR(HI, LO) (LO), (HI)
+# endif
+# define LL_VAL_TO_PAIR(llval) LL_PAIR((long) ((llval) >> 32), (long) (llval))
+
+static void do_fadvise(long fd, long long offset, long long llen, long advice);
 
 int
 main(void)
 {
-	sigset_t mask;
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGUSR2);
-	sigaddset(&mask, SIGCHLD);
-	(void) close(0);
-	if (signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK))
-		perror_msg_and_skip("signalfd");
+	static const long bogus_fd = (long) 0xfeedf00dbeeffaceULL;
+	static const long long bogus_offset = 0xbadc0dedda7a1057ULL;
+	static const long long bogus_len = 0xbadfaceca7b0d1e5ULL;
+	static const long bogus_advice = (long) 0xf00dfeeddeadca75ULL;
+
+	do_fadvise(bogus_fd, bogus_offset, bogus_len, bogus_advice);
+
+	puts("+++ exited with 0 +++");
 	return 0;
 }
 
-#else
-
-SKIP_MAIN_UNDEFINED("HAVE_SYS_SIGNALFD_H && HAVE_SIGNALFD && O_CLOEXEC")
-
-#endif
+#endif /* !STRACE_TESTS_FADVISE_H */
diff --git a/tests/fadvise64.c b/tests/fadvise64.c
new file mode 100644
index 0000000..02d7394
--- /dev/null
+++ b/tests/fadvise64.c
@@ -0,0 +1,76 @@
+/*
+ * Check decoding of fadvise64 syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __NR_fadvise64
+
+# include "fadvise.h"
+
+static void
+do_fadvise(long fd, long long offset, long long llen, long advice)
+{
+	long ret;
+	const char *errstr;
+
+# if (LONG_MAX > INT_MAX) \
+  || (defined __x86_64__ && defined __ILP32__) \
+  || defined LINUX_MIPSN32
+	ret = syscall(__NR_fadvise64, fd, offset, llen, advice);
+	errstr = sprintrc(ret);
+	printf("fadvise64(%d, %lld, %llu, ", (int) fd, offset, llen);
+# elif defined LINUX_MIPSO32
+	ret = syscall(__NR_fadvise64, fd, 0,
+		      LL_VAL_TO_PAIR(offset), LL_VAL_TO_PAIR(llen), advice);
+	errstr = sprintrc(ret);
+	printf("fadvise64(%d, %lld, %lld, ", (int) fd, offset, llen);
+# else /* LONG_MAX == INT_MAX && !X32 && !LINUX_MIPSN32 */
+	long len = (long) llen;
+#  if defined POWERPC
+	ret = syscall(__NR_fadvise64, fd, 0,
+		      LL_VAL_TO_PAIR(offset), len, advice);
+#  else
+	ret = syscall(__NR_fadvise64, fd,
+		      LL_VAL_TO_PAIR(offset), len, advice);
+#  endif
+	errstr = sprintrc(ret);
+	printf("fadvise64(%d, %lld, %lu, ", (int) fd, offset, len);
+# endif /* LONG_MAX == INT_MAX && !X32 && !LINUX_MIPSN32 */
+	printxval(advise, (unsigned) advice, "POSIX_FADV_???");
+	printf(") = %s\n", errstr);
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fadvise64");
+
+#endif
diff --git a/tests/fadvise64.test b/tests/fadvise64.test
new file mode 100755
index 0000000..9f74672
--- /dev/null
+++ b/tests/fadvise64.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Check decoding of fadvise64 syscall.
+
+. "${srcdir=.}/init.sh"
+
+run_prog > /dev/null
+run_strace -e $NAME $args > "$EXP"
+check_prog grep
+grep -v "^$NAME([0123]," < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
+rm -f "$EXP" "$OUT"
diff --git a/tests/fadvise64_64.c b/tests/fadvise64_64.c
new file mode 100644
index 0000000..69b1c7f
--- /dev/null
+++ b/tests/fadvise64_64.c
@@ -0,0 +1,74 @@
+/*
+ * Check decoding of fadvise64_64 syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __arm__
+# ifdef __NR_arm_fadvise64_64
+#  undef __NR_fadvise64_64
+#  define __NR_fadvise64_64 __NR_arm_fadvise64_64
+# endif /* __NR_arm_fadvise64_64 */
+#endif /* __arm__ */
+
+#ifdef __NR_fadvise64_64
+
+# include "fadvise.h"
+
+static void
+do_fadvise(long fd, long long offset, long long llen, long advice)
+{
+	long ret;
+	const char *errstr;
+
+# if (LONG_MAX > INT_MAX) \
+  || (defined __x86_64__ && defined __ILP32__) \
+  || defined LINUX_MIPSN32
+	ret = syscall(__NR_fadvise64_64, fd, offset, llen, advice);
+# elif defined __ARM_EABI__ || defined POWERPC || defined XTENSA
+	ret = syscall(__NR_fadvise64_64, fd, advice,
+		      LL_VAL_TO_PAIR(offset), LL_VAL_TO_PAIR(llen));
+# else
+	ret = syscall(__NR_fadvise64_64, fd,
+		      LL_VAL_TO_PAIR(offset), LL_VAL_TO_PAIR(llen), advice);
+# endif
+	errstr = sprintrc(ret);
+
+	printf("fadvise64_64(%d, %lld, %lld, ", (int) fd, offset, llen);
+	printxval(advise, (unsigned) advice, "POSIX_FADV_???");
+	printf(") = %s\n", errstr);
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fadvise64_64");
+
+#endif
diff --git a/tests/fadvise64_64.test b/tests/fadvise64_64.test
new file mode 100755
index 0000000..a50fe2b
--- /dev/null
+++ b/tests/fadvise64_64.test
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# Check decoding of fadvise64_64 syscall.
+
+. "${srcdir=.}/fadvise64.test"
diff --git a/tests/fallocate.c b/tests/fallocate.c
new file mode 100644
index 0000000..40ac244
--- /dev/null
+++ b/tests/fallocate.c
@@ -0,0 +1,75 @@
+/*
+ * Check decoding of fallocate syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#if defined(__NR_fallocate) && defined(HAVE_FALLOCATE) && HAVE_FALLOCATE
+
+# include <errno.h>
+# include <fcntl.h>
+# include <stdio.h>
+
+# include "xlat.h"
+# include "xlat/falloc_flags.h"
+
+int
+main(void)
+{
+	static const int bogus_fd = 0xbeefface;
+	static const int bogus_mode = 0xdeadca75;
+	static const off_t bogus_offset = (off_t) 0xbadc0dedda7a1057LLU;
+	static const off_t bogus_len = (off_t) 0xbadfaceca7b0d1e5LLU;
+
+	long rc = fallocate(bogus_fd, bogus_mode, bogus_offset, bogus_len);
+	/*
+	 * Workaround a bug fixed by commit glibc-2.11-346-gde240a0.
+	 */
+	if (rc > 0) {
+		errno = rc;
+		rc = -1;
+	}
+	const char *errstr = sprintrc(rc);
+
+	printf("fallocate(%d, ", bogus_fd);
+	printflags(falloc_flags, (unsigned) bogus_mode, "FALLOC_FL_???");
+	printf(", %lld, %lld) = %s\n",
+	       (long long) bogus_offset, (long long) bogus_len, errstr);
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_fallocate && HAVE_FALLOCATE");
+
+#endif
diff --git a/tests/fallocate.test b/tests/fallocate.test
new file mode 100755
index 0000000..405187e
--- /dev/null
+++ b/tests/fallocate.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check getcwd syscall decoding.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a18
diff --git a/tests/fanotify_mark.c b/tests/fanotify_mark.c
index e467bf0..9cac5ef 100644
--- a/tests/fanotify_mark.c
+++ b/tests/fanotify_mark.c
@@ -2,12 +2,18 @@
 
 #if defined HAVE_SYS_FANOTIFY_H && defined HAVE_FANOTIFY_MARK
 
+# include <stdio.h>
 # include <sys/fanotify.h>
 
 int
 main(void)
 {
-	fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR, -100, ".");
+	int rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
+			       -100, ".");
+	printf("fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY|FAN_ONDIR"
+	       ", AT_FDCWD, \".\") = %d %s (%m)\n", rc, errno2name());
+
+	puts("+++ exited with 0 +++");
 	return 0;
 }
 
diff --git a/tests/fanotify_mark.expected b/tests/fanotify_mark.expected
deleted file mode 100644
index d2bb336..0000000
--- a/tests/fanotify_mark.expected
+++ /dev/null
@@ -1 +0,0 @@
-fanotify_mark\(-1, FAN_MARK_ADD, FAN_MODIFY\|FAN_ONDIR, AT_FDCWD, "\."\) += -1.*
diff --git a/tests/fanotify_mark.test b/tests/fanotify_mark.test
index 4b7749a..84b3c83 100755
--- a/tests/fanotify_mark.test
+++ b/tests/fanotify_mark.test
@@ -1,11 +1,6 @@
 #!/bin/sh
 
-# Check fanotify_mark syscall decoding.
+# Check decoding of fanotify_mark syscall.
 
 . "${srcdir=.}/init.sh"
-
-run_prog
-run_strace -efanotify_mark $args
-match_grep
-
-exit 0
+run_strace_match_diff
diff --git a/tests/fchdir.c b/tests/fchdir.c
index 7306d4d..5808872 100644
--- a/tests/fchdir.c
+++ b/tests/fchdir.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fchdir
 
diff --git a/tests/fchmod.c b/tests/fchmod.c
index 57fefa1..932d083 100644
--- a/tests/fchmod.c
+++ b/tests/fchmod.c
@@ -1,5 +1,8 @@
 /*
+ * Check decoding of fchmod syscall.
+ *
  * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,14 +29,14 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
-#if defined __NR_fchmod
+#ifdef __NR_fchmod
 
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <unistd.h>
+# include <fcntl.h>
+# include <sys/stat.h>
+# include <stdio.h>
+# include <unistd.h>
 
 int
 main(void)
@@ -41,22 +44,22 @@
 	static const char fname[] = "fchmod_test_file";
 
 	int fd = open(fname, O_CREAT|O_RDONLY, 0400);
-
-	if (fd == -1)
+	if (fd < 0)
 		perror_msg_and_fail("open");
 
-	if (unlink(fname) == -1)
+	if (unlink(fname))
 		perror_msg_and_fail("unlink");
 
-	if (syscall(__NR_fchmod, fd, 0600) == 0) {
-		close(fd);
+	long rc = syscall(__NR_fchmod, fd, 0600);
+	printf("fchmod(%d, 0600) = %s\n", fd, sprintrc(rc));
 
-		printf("fchmod(%d, 0600) = 0\n", fd);
+	close(fd);
 
-		if (syscall(__NR_fchmod, fd, 0600) != -1)
-			perror_msg_and_fail("fchmod");
-	}
-	printf("fchmod(%d, 0600) = -1 %s (%m)\n", fd, errno2name());
+	rc = syscall(__NR_fchmod, fd, 051);
+	printf("fchmod(%d, 051) = %s\n", fd, sprintrc(rc));
+
+	rc = syscall(__NR_fchmod, fd, 004);
+	printf("fchmod(%d, 004) = %s\n", fd, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/fchmod.test b/tests/fchmod.test
index 32ad456..4cb1263 100755
--- a/tests/fchmod.test
+++ b/tests/fchmod.test
@@ -3,4 +3,4 @@
 # Check fchmod syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a16
+run_strace_match_diff -a15
diff --git a/tests/fchmodat.c b/tests/fchmodat.c
index 2ae613e..c52a1ca 100644
--- a/tests/fchmodat.c
+++ b/tests/fchmodat.c
@@ -28,11 +28,12 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fchmodat
 
 # include <fcntl.h>
+# include <sys/stat.h>
 # include <stdio.h>
 # include <unistd.h>
 
@@ -41,21 +42,23 @@
 {
 	static const char sample[] = "fchmodat_sample";
 
-	if (open(sample, O_RDONLY | O_CREAT, 0400) == -1)
+	if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
 		perror_msg_and_fail("open");
 
-	if (syscall(__NR_fchmodat, -100, sample, 0600) == 0) {
-		printf("fchmodat(AT_FDCWD, \"%s\", 0600) = 0\n", sample);
+	long rc = syscall(__NR_fchmodat, -100, sample, 0600);
+	printf("fchmodat(AT_FDCWD, \"%s\", 0600) = %s\n",
+	       sample, sprintrc(rc));
 
-		if (unlink(sample))
-			perror_msg_and_fail("unlink");
+	if (unlink(sample))
+		perror_msg_and_fail("unlink");
 
-		if (syscall(__NR_fchmodat, -100, sample, 0600) != -1)
-			perror_msg_and_fail("fchmodat");
-	}
+	rc = syscall(__NR_fchmodat, -100, sample, 051);
+	printf("fchmodat(AT_FDCWD, \"%s\", 051) = %s\n",
+	       sample, sprintrc(rc));
 
-	printf("fchmodat(AT_FDCWD, \"%s\", 0600) = -1 %s (%m)\n",
-	       sample, errno2name());
+	rc = syscall(__NR_fchmodat, -100, sample, 004);
+	printf("fchmodat(AT_FDCWD, \"%s\", 004) = %s\n",
+	       sample, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/fchown.c b/tests/fchown.c
index 53a522e..d711903 100644
--- a/tests/fchown.c
+++ b/tests/fchown.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fchown
 
diff --git a/tests/fchown32.c b/tests/fchown32.c
index 0927b56..2d9d60f 100644
--- a/tests/fchown32.c
+++ b/tests/fchown32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fchown32
 
diff --git a/tests/fchownat.c b/tests/fchownat.c
index 9a0ecc8..f2f37ae 100644
--- a/tests/fchownat.c
+++ b/tests/fchownat.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <fcntl.h>
 
 #if defined __NR_fchownat && defined AT_FDCWD && defined AT_SYMLINK_NOFOLLOW
@@ -47,22 +47,16 @@
 		perror_msg_and_fail("open");
 
 	long rc = syscall(__NR_fchownat, AT_FDCWD, sample, uid, gid, 0);
-	if (rc == 0) {
-		printf("fchownat(AT_FDCWD, \"%s\", %d, %d, 0) = 0\n",
-		       sample, uid, gid);
+	printf("fchownat(AT_FDCWD, \"%s\", %d, %d, 0) = %s\n",
+	       sample, uid, gid, sprintrc(rc));
 
-		if (unlink(sample))
-			perror_msg_and_fail("unlink");
+	if (unlink(sample))
+		perror_msg_and_fail("unlink");
 
-		rc = syscall(__NR_fchownat, AT_FDCWD,
-			     sample, -1, -1L, AT_SYMLINK_NOFOLLOW);
-
-		printf("fchownat(AT_FDCWD, \"%s\", -1, -1, AT_SYMLINK_NOFOLLOW)"
-		       " = %ld %s (%m)\n", sample, rc, errno2name());
-	} else {
-		printf("fchownat(AT_FDCWD, \"%s\", %d, %d, 0)"
-		       " = %ld %s (%m)\n", sample, uid, gid, rc, errno2name());
-	}
+	rc = syscall(__NR_fchownat, AT_FDCWD,
+		     sample, -1, -1L, AT_SYMLINK_NOFOLLOW);
+	printf("fchownat(AT_FDCWD, \"%s\", -1, -1, AT_SYMLINK_NOFOLLOW) = %s\n",
+	       sample, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/fcntl.c b/tests/fcntl.c
index 1ea83e1..4ae5beb 100644
--- a/tests/fcntl.c
+++ b/tests/fcntl.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fcntl
 
@@ -59,7 +59,10 @@
 #if !defined(F_GETOWN_EX) || F_GETOWN_EX != F_SETLK64
 	TEST_FLOCK64_EINVAL(F_SETLK64);
 #endif
+/* F_GETLK and F_SETLKW64 have conflicting values on mips64 */
+#if !defined(__mips64) || F_GETLK != F_SETLKW64
 	TEST_FLOCK64_EINVAL(F_SETLKW64);
+#endif
 #if !defined(F_SETOWN_EX) || F_SETOWN_EX != F_GETLK64
 	TEST_FLOCK64_EINVAL(F_GETLK64);
 #endif
diff --git a/tests/fcntl64.c b/tests/fcntl64.c
index b83a098..ff6a531 100644
--- a/tests/fcntl64.c
+++ b/tests/fcntl64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fcntl64
 
diff --git a/tests/fdatasync.c b/tests/fdatasync.c
index 86f1cfa..c47a0bf 100644
--- a/tests/fdatasync.c
+++ b/tests/fdatasync.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fdatasync
 
diff --git a/tests/flock.c b/tests/flock.c
index d6e2008..cb231d5 100644
--- a/tests/flock.c
+++ b/tests/flock.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_flock
 
diff --git a/tests/fstat.c b/tests/fstat.c
index 0206c9f..9ddc811 100644
--- a/tests/fstat.c
+++ b/tests/fstat.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fstat
 
diff --git a/tests/fstat64.c b/tests/fstat64.c
index 59c94a2..cf147df 100644
--- a/tests/fstat64.c
+++ b/tests/fstat64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fstat64
 
@@ -34,6 +34,7 @@
 # define TEST_SYSCALL_STR "fstat64"
 # define STRUCT_STAT struct stat64
 # define STRUCT_STAT_STR "struct stat64"
+# define STRUCT_STAT_IS_STAT64 1
 # define SAMPLE_SIZE ((libc_off_t) 43147718418)
 # include "fstatx.c"
 
diff --git a/tests/fstatat64.c b/tests/fstatat64.c
index 1bf95c1..fa8992d 100644
--- a/tests/fstatat64.c
+++ b/tests/fstatat64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fstatat64
 
diff --git a/tests/fstatfs.c b/tests/fstatfs.c
index 7ff39dc..9e68c8d 100644
--- a/tests/fstatfs.c
+++ b/tests/fstatfs.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fstatfs
 
diff --git a/tests/fstatfs64.c b/tests/fstatfs64.c
index 6c59974..afc54aa 100644
--- a/tests/fstatfs64.c
+++ b/tests/fstatfs64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fstatfs64
 
diff --git a/tests/fsync.c b/tests/fsync.c
index 911c167..42aa5c7 100644
--- a/tests/fsync.c
+++ b/tests/fsync.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_fsync
 
diff --git a/tests/ftruncate.c b/tests/ftruncate.c
index db8388b..315f7bf 100644
--- a/tests/ftruncate.c
+++ b/tests/ftruncate.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_ftruncate
 
diff --git a/tests/ftruncate64.c b/tests/ftruncate64.c
index 0b13eaf..7530e70 100644
--- a/tests/ftruncate64.c
+++ b/tests/ftruncate64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_ftruncate64
 
diff --git a/tests/futex.c b/tests/futex.c
new file mode 100644
index 0000000..7cc6cc4
--- /dev/null
+++ b/tests/futex.c
@@ -0,0 +1,708 @@
+/*
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __NR_futex
+
+# include <errno.h>
+# include <stdarg.h>
+# include <stdbool.h>
+# include <stdio.h>
+# include <stdint.h>
+# include <unistd.h>
+
+# include <sys/time.h>
+
+# ifndef FUTEX_PRIVATE_FLAG
+#  define FUTEX_PRIVATE_FLAG 128
+# endif
+# ifndef FUTEX_CLOCK_REALTIME
+#  define FUTEX_CLOCK_REALTIME 256
+# endif
+# ifndef FUTEX_CMD_MASK
+#  define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
+# endif
+
+# include "xlat.h"
+# include "xlat/futexops.h"
+# include "xlat/futexwakeops.h"
+# include "xlat/futexwakecmps.h"
+
+static struct timespec *tmout;
+
+void futex_error(int *uaddr, int op, unsigned long val, unsigned long timeout,
+	int *uaddr2, unsigned long val3, int rc)
+{
+	perror_msg_and_fail("futex(%p, %#x, %#x, %#lx, %p, %#x) = %d",
+		uaddr, op, (unsigned) val, timeout, uaddr, (unsigned) val3, rc);
+}
+
+# define CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, \
+	enosys) \
+	do { \
+		rc = syscall(__NR_futex, (uaddr), (op), (val), (timeout), \
+			(uaddr2), (val3)); \
+		/* It is here due to EPERM on WAKE_OP on AArch64 */ \
+		if ((rc == -1) && (errno == EPERM)) \
+			break; \
+		if (enosys && (rc == -1) && (errno == ENOSYS)) \
+			break; \
+		if (!(check)) \
+			futex_error((uaddr), (op), (val), \
+				(unsigned long) (timeout), (int *) (uaddr2), \
+				(val3), rc); \
+	} while (0)
+
+# define CHECK_FUTEX_ENOSYS(uaddr, op, val, timeout, uaddr2, val3, check) \
+	CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, 1)
+
+# define CHECK_FUTEX(uaddr, op, val, timeout, uaddr2, val3, check) \
+	CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, 0)
+
+enum argmask {
+	ARG3 = 1 << 0,
+	ARG4 = 1 << 1,
+	ARG5 = 1 << 2,
+	ARG6 = 1 << 3,
+};
+
+void invalid_op(int *val, int op, uint32_t argmask, ...)
+{
+	static const unsigned long args[] = {
+		(unsigned long) 0xface1e55deadbee1ULL,
+		(unsigned long) 0xface1e56deadbee2ULL,
+		(unsigned long) 0xface1e57deadbee3ULL,
+		(unsigned long) 0xface1e58deadbee4ULL,
+	};
+	/* Since timeout value is copied before full op check, we should provide
+	 * some valid timeout address or NULL */
+	int cmd = op & FUTEX_CMD_MASK;
+	bool valid_timeout = (cmd == FUTEX_WAIT) || (cmd == FUTEX_LOCK_PI) ||
+		(cmd == FUTEX_WAIT_BITSET) || (cmd == FUTEX_WAIT_REQUEUE_PI);
+	bool timeout_is_val2 = (cmd == FUTEX_REQUEUE) ||
+		(cmd == FUTEX_CMP_REQUEUE) || (cmd == FUTEX_WAKE_OP) ||
+		(cmd == FUTEX_CMP_REQUEUE_PI);
+	const char *fmt;
+	int saved_errno;
+	int rc;
+	int i;
+	va_list ap;
+
+
+	CHECK_FUTEX(val, op, args[0], valid_timeout ? 0 : args[1], args[2],
+		args[3], (rc == -1) && (errno == ENOSYS));
+	saved_errno = errno;
+	printf("futex(%p, %#x /* FUTEX_??? */", val, op);
+
+	va_start(ap, argmask);
+
+	for (i = 0; i < 4; i++) {
+		if (argmask & (1 << i)) {
+			fmt = va_arg(ap, const char *);
+
+			printf(", ");
+
+			if (((1 << i) == ARG3) || ((1 << i) == ARG6) ||
+			    (((1 << i) == ARG4) && timeout_is_val2))
+				printf(fmt, (unsigned) args[i]);
+			else
+				printf(fmt, args[i]);
+		}
+	}
+
+	va_end(ap);
+
+	errno = saved_errno;
+	printf(") = -1 ENOSYS (%m)\n");
+}
+
+# define CHECK_INVALID_CLOCKRT(op, ...) \
+	do { \
+		invalid_op(uaddr, FUTEX_CLOCK_REALTIME | (op), __VA_ARGS__); \
+		invalid_op(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG | \
+			(op), __VA_ARGS__); \
+	} while (0)
+
+/* Value which differs from one stored in int *val */
+# define VAL     ((unsigned long) 0xbadda7a0facefeedLLU)
+# define VAL_PR  ((unsigned) VAL)
+
+# define VAL2    ((unsigned long) 0xbadda7a0ca7b100dLLU)
+# define VAL2_PR ((unsigned) VAL2)
+
+# define VAL3    ((unsigned long) 0xbadda7a09caffee1LLU)
+# define VAL3_PR ((unsigned) VAL3)
+
+int
+main(int argc, char *argv[])
+{
+	int *uaddr = tail_alloc(sizeof(*uaddr));
+	int *uaddr2 = tail_alloc(sizeof(*uaddr2));
+	int rc;
+	unsigned i;
+	unsigned j;
+
+	uaddr[0] = 0x1deadead;
+	uaddr2[0] = 0xbadf00d;
+
+	tmout = tail_alloc(sizeof(*tmout));
+	tmout->tv_sec = 123;
+	tmout->tv_nsec = 0xbadc0de;
+
+	/* FUTEX_WAIT - check whether uaddr == val and sleep
+	 * Possible flags: PRIVATE, CLOCK_RT (since 4.5)
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_WAIT
+	 * 3. val     - expected value
+	 * 4. timeout - address to timespec with timeout
+	 * 5. uaddr2  - not used
+	 * 6. val3    - not used
+	 */
+
+	/* uaddr is NULL */
+	CHECK_FUTEX(NULL, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
+		(rc == -1) && (errno == EFAULT));
+	printf("futex(NULL, FUTEX_WAIT, %u, {%jd, %jd}) = %s\n",
+		VAL_PR, (intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec,
+		sprintrc(rc));
+
+	/* uaddr is faulty */
+	CHECK_FUTEX(uaddr + 1, FUTEX_WAIT, VAL, tmout, uaddr2, VAL3,
+		(rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_WAIT, %u, {%jd, %jd}) = %s\n",
+		uaddr + 1, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, sprintrc(rc));
+
+	/* timeout is faulty */
+	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout + 1, uaddr2, VAL3,
+		(rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_WAIT, %u, %p) = %s\n",
+		uaddr, 0xfacefeed, tmout + 1, sprintrc(rc));
+
+	/* uaddr is not as provided; uaddr2 is faulty but ignored */
+	CHECK_FUTEX(uaddr, FUTEX_WAIT, VAL, tmout, uaddr2 + 1, VAL3,
+		(rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT, %u, {%jd, %jd}) = %s\n",
+		uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, sprintrc(rc));
+
+	/* uaddr is not as provided; uaddr2 is faulty but ignored */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT, VAL, tmout,
+		uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_PRIVATE, %u, {%jd, %jd}) = %s\n",
+		uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, sprintrc(rc));
+
+	/* Next 2 tests are with CLOCKRT bit set */
+
+	/* Valid after v4.4-rc2-27-g337f130 */
+	CHECK_FUTEX_ENOSYS(uaddr,
+		FUTEX_CLOCK_REALTIME | FUTEX_WAIT,
+		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT|FUTEX_CLOCK_REALTIME, %u, "
+		"{%jd, %jd}) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec,
+		sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr,
+		FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG | FUTEX_WAIT ,
+		VAL, tmout, uaddr2, 0, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_PRIVATE|FUTEX_CLOCK_REALTIME, %u, "
+		"{%jd, %jd}) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec,
+		sprintrc(rc));
+
+	/* FUTEX_WAIT_BITSET - FUTEX_WAIT which provides additional bitmask
+	 *                     which should be matched at least in one bit with
+	 *                     wake mask in order to wake.
+	 * Possible flags: PRIVATE, CLOCKRT
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_TRYLOCK_PI
+	 * 3. val     - expected value stored in uaddr
+	 * 4. timeout - timeout
+	 * 5. uaddr2  - not used
+	 * 6. val3    - bitmask
+	 */
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1,
+		VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {%jd, %jd}, %#x) = %s\n",
+		uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, VAL3_PR, sprintrc(rc));
+
+	/* val3 of 0 is invalid  */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1, 0,
+		(rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_WAIT_BITSET, %u, {%jd, %jd}, %#x) = %s\n",
+		uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, 0, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT_BITSET, VAL,
+		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_BITSET_PRIVATE, %u, {%jd, %jd}, %#x) = "
+		"%s\n", uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, VAL3_PR, sprintrc(rc));
+
+	/* Next 3 tests are with CLOCKRT bit set */
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_BITSET, VAL,
+		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %u, "
+		"{%jd, %jd}, %#x) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec, VAL3_PR,
+		sprintrc(rc));
+
+	/* val3 of 0 is invalid  */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_BITSET, VAL,
+		tmout, uaddr2 + 1, 0, (rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %u, "
+		"{%jd, %jd}, %#x) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec, 0,
+		sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG |
+		FUTEX_WAIT_BITSET, VAL, tmout, uaddr2 + 1, VAL3,
+		(rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, %u, "
+		"{%jd, %jd}, %#x) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec, VAL3_PR,
+		sprintrc(rc));
+
+	/* FUTEX_WAKE - wake val processes waiting for uaddr
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_WAKE
+	 * 3. val     - how many processes to wake
+	 * 4. timeout - not used
+	 * 5. uaddr2  - not used
+	 * 6. val3    - not used
+	 */
+
+	/* Zero processes to wake is not a good idea, but it should return 0 */
+	CHECK_FUTEX(uaddr, FUTEX_WAKE, 0, NULL, NULL, 0, (rc == 0));
+	printf("futex(%p, FUTEX_WAKE, %u) = %s\n", uaddr, 0, sprintrc(rc));
+
+	/* Trying to wake some processes, but there's nothing to wake */
+	CHECK_FUTEX(uaddr, FUTEX_WAKE, 10, NULL, NULL, 0, (rc == 0));
+	printf("futex(%p, FUTEX_WAKE, %u) = %s\n", uaddr, 10, sprintrc(rc));
+
+	/* Trying to wake some processes, but there's nothing to wake */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAKE, 10, NULL,
+		NULL, 0, (rc == 0));
+	printf("futex(%p, FUTEX_WAKE_PRIVATE, %u) = %s\n", uaddr, 10,
+		sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_WAKE, ARG3, "%u");
+
+	/* FUTEX_WAKE_BITSET - wake val processes waiting for uaddr which has at
+	 *                     least one common bit with bitset provided in
+	 *                     val3.
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_WAKE
+	 * 3. val     - how many processes to wake
+	 * 4. timeout - not used
+	 * 5. uaddr2  - not used
+	 * 6. val3    - bitmask
+	 */
+
+	/* Trying to wake some processes, but there's nothing to wake */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL,
+		VAL3, (rc == 0));
+	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %#x) = %s\n", uaddr, 10,
+		VAL3_PR, sprintrc(rc));
+
+	/* bitset 0 is invalid */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAKE_BITSET, 10, NULL, NULL, 0,
+		(rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_WAKE_BITSET, %u, %#x) = %s\n", uaddr, 10, 0,
+		sprintrc(rc));
+
+	/* Trying to wake some processes, but there's nothing to wake */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAKE_BITSET, 10,
+		NULL, NULL, VAL3, (rc == 0));
+	printf("futex(%p, FUTEX_WAKE_BITSET_PRIVATE, %u, %#x) = %s\n", uaddr,
+		10, VAL3_PR, sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_WAKE_BITSET, ARG3 | ARG6, "%u", "%#x");
+
+	/* FUTEX_FD - deprecated
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_FD
+	 * 3. val     - signal number
+	 * 4. timeout - not used
+	 * 5. uaddr2  - not used
+	 * 6. val3    - not used
+	 */
+
+	/* FUTEX_FD is not implemented since 2.6.26 */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_FD, VAL, NULL, NULL, VAL3,
+		(rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_FD, %u) = %s\n", uaddr, VAL_PR, sprintrc(rc));
+
+	/* FUTEX_FD is not implemented since 2.6.26 */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_FD, VAL, NULL,
+		NULL, VAL3, (rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_FD|FUTEX_PRIVATE_FLAG, %u) = %s\n", uaddr,
+		VAL_PR, sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_FD, ARG3, "%u");
+
+	/* FUTEX_REQUEUE - wake val processes and re-queue rest on uaddr2
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_REQUEUE
+	 * 3. val     - how many processes to wake
+	 * 4. val2    - amount of processes to re-queue on uadr2
+	 * 5. uaddr2  - another futex address, to re-queue waiting processes on
+	 * 6. val3    - not used
+	 */
+
+	/* Trying to re-queue some processes but there's nothing to re-queue */
+	CHECK_FUTEX(uaddr, FUTEX_REQUEUE, VAL, VAL2, uaddr2, VAL3,
+		(rc == 0));
+	printf("futex(%p, FUTEX_REQUEUE, %u, %u, %p) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, sprintrc(rc));
+
+	/* Trying to re-queue some processes but there's nothing to re-queue */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_REQUEUE, VAL, VAL2,
+		uaddr2, VAL3, (rc == 0));
+	printf("futex(%p, FUTEX_REQUEUE_PRIVATE, %u, %u, %p) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_REQUEUE, ARG3 | ARG4 | ARG5, "%u", "%u",
+		"%#lx");
+
+	/* FUTEX_CMP_REQUEUE - wake val processes and re-queue rest on uaddr2
+	 *                     if uaddr has value val3
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_CMP_REQUEUE
+	 * 3. val     - how many processes to wake
+	 * 4. val2    - amount of processes to re-queue on uadr2
+	 * 5. uaddr2  - another futex address, to re-queue waiting processes on
+	 * 6. val3    - expected value stored in uaddr
+	 */
+
+	/* Comparison re-queue with wrong val value */
+	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VAL, VAL2, uaddr2, VAL3,
+		(rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, VAL3_PR, sprintrc(rc));
+
+	/* Successful comparison re-queue */
+	CHECK_FUTEX(uaddr, FUTEX_CMP_REQUEUE, VAL, VAL2, uaddr2, *uaddr,
+		(rc == 0));
+	printf("futex(%p, FUTEX_CMP_REQUEUE, %u, %u, %p, %u) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
+
+	/* Successful comparison re-queue */
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE, VAL,
+		VAL2, uaddr2, *uaddr, (rc == 0));
+	printf("futex(%p, FUTEX_CMP_REQUEUE_PRIVATE, %u, %u, %p, %u) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_CMP_REQUEUE, ARG3 | ARG4 | ARG5 | ARG6,
+		"%u", "%u", "%#lx", "%u");
+
+	/* FUTEX_WAKE_OP - wake val processes waiting for uaddr, additionally
+	 *                 wake val2 processes waiting for uaddr2 in case
+	 *                 operation encoded in val3 (change of value at uaddr2
+	 *                 and comparison of previous value against provided
+	 *                 constant) succeedes with value at uaddr2. Operation
+	 *                 result is written to value of uaddr2 (in any case).
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_WAKE_OP
+	 * 3. val     - how many processes to wake
+	 * 4. val2    - amount of processes to wake in case operation encoded in
+	 *              val3 returns true
+	 * 5. uaddr2  - another futex address, for conditional wake of
+	 *              additional processes
+	 * 6. val3    - encoded operation:
+	 *                1. bit 31 - if 1 then value stored in field field 4
+	 *                            should be interpreted as power of 2.
+	 *                2. 28..30 - arithmetic operation which should be
+	 *                            applied to previous value stored in
+	 *                            uaddr2. Values available (from 2005 up to
+	 *                            2016): SET. ADD, OR, ANDN, XOR.
+	 *                3. 24..29 - comparison operation which should be
+	 *                            applied to the old value stored in uaddr2
+	 *                            (before arithmetic operation is applied).
+	 *                            Possible values: EQ, NE, LT, LE, GT, GE.
+	 *                4. 12..23 - Second operand for arithmetic operation.
+	 *                            If bit 31 is set, it is interpreted as
+	 *                            power of 2.
+	 *                5. 00..11 - Value against which old value stored in
+	 *                            uaddr2 is compared.
+	 */
+
+	static const struct {
+		uint32_t val;
+		const char *str;
+		int err;
+		const char *errstr;
+	} wake_ops[] = {
+		{ 0x00000000, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 0}" },
+		{ 0x00fff000, "{FUTEX_OP_SET, 4095, FUTEX_OP_CMP_EQ, 0}" },
+		{ 0x00000fff, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_EQ, 4095}" },
+		{ 0x00ffffff, "{FUTEX_OP_SET, 4095, FUTEX_OP_CMP_EQ, 4095}" },
+		{ 0x10000000, "{FUTEX_OP_ADD, 0, FUTEX_OP_CMP_EQ, 0}" },
+		{ 0x20000000, "{FUTEX_OP_OR, 0, FUTEX_OP_CMP_EQ, 0}" },
+		{ 0x30000000, "{FUTEX_OP_ANDN, 0, FUTEX_OP_CMP_EQ, 0}" },
+		{ 0x40000000, "{FUTEX_OP_XOR, 0, FUTEX_OP_CMP_EQ, 0}" },
+		{ 0x50000000, "{0x5 /* FUTEX_OP_??? */, 0, FUTEX_OP_CMP_EQ, 0}",
+			ENOSYS, "ENOSYS" },
+		{ 0x70000000, "{0x7 /* FUTEX_OP_??? */, 0, FUTEX_OP_CMP_EQ, 0}",
+			ENOSYS, "ENOSYS" },
+		{ 0x80000000, "{FUTEX_OP_OPARG_SHIFT|FUTEX_OP_SET, 0, "
+			"FUTEX_OP_CMP_EQ, 0}" },
+		{ 0xa0caffee, "{FUTEX_OP_OPARG_SHIFT|FUTEX_OP_OR, 3247, "
+			"FUTEX_OP_CMP_EQ, 4078}" },
+		{ 0x01000000, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_NE, 0}" },
+		{ 0x01234567, "{FUTEX_OP_SET, 564, FUTEX_OP_CMP_NE, 1383}" },
+		{ 0x02000000, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_LT, 0}" },
+		{ 0x03000000, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_LE, 0}" },
+		{ 0x04000000, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 0}" },
+		{ 0x05000000, "{FUTEX_OP_SET, 0, FUTEX_OP_CMP_GE, 0}" },
+		{ 0x06000000, "{FUTEX_OP_SET, 0, 0x6 /* FUTEX_OP_CMP_??? */, "
+			"0}", ENOSYS, "ENOSYS" },
+		{ 0x07000000, "{FUTEX_OP_SET, 0, 0x7 /* FUTEX_OP_CMP_??? */, "
+			"0}", ENOSYS, "ENOSYS" },
+		{ 0x08000000, "{FUTEX_OP_SET, 0, 0x8 /* FUTEX_OP_CMP_??? */, "
+			"0}", ENOSYS, "ENOSYS" },
+		{ 0x0f000000, "{FUTEX_OP_SET, 0, 0xf /* FUTEX_OP_CMP_??? */, "
+			"0}", ENOSYS, "ENOSYS" },
+		{ 0xbadfaced, "{FUTEX_OP_OPARG_SHIFT|FUTEX_OP_ANDN, "
+			"3578, 0xa /* FUTEX_OP_CMP_??? */, 3309}", ENOSYS,
+			"ENOSYS" },
+		{ 0xffffffff, "{FUTEX_OP_OPARG_SHIFT|0x7 /* FUTEX_OP_??? */, "
+			"4095, 0xf /* FUTEX_OP_CMP_??? */, 4095}", ENOSYS,
+			"ENOSYS" },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(wake_ops); i++) {
+		for (j = 0; j < 2; j++) {
+			CHECK_FUTEX_ENOSYS(uaddr,
+				j ? FUTEX_WAKE_OP_PRIVATE : FUTEX_WAKE_OP,
+				VAL, i, uaddr2, wake_ops[i].val, (rc == 0));
+			printf("futex(%p, FUTEX_WAKE_OP%s, %u, %u, %p, %s) = "
+				"%s\n", uaddr, j ? "_PRIVATE" : "", VAL_PR, i,
+				uaddr2, wake_ops[i].str, sprintrc(rc));
+		}
+	}
+
+	CHECK_INVALID_CLOCKRT(FUTEX_WAKE_OP, ARG3 | ARG4 | ARG5 | ARG6,
+		"%u", "%u", "%#lx",
+		/* Decoding of the 0xdeadbee4 value */
+		"{FUTEX_OP_OPARG_SHIFT|0x5 /* FUTEX_OP_??? */, 2779, "
+		"0xe /* FUTEX_OP_CMP_??? */, 3812}");
+
+	/* FUTEX_LOCK_PI - slow path for mutex lock with process inheritance
+	 *                 support. Expect that futex has 0 in unlocked case and
+	 *                 TID of owning process in locked case. Value can also
+	 *                 contain FUTEX_WAITERS bit signalling the presence of
+	 *                 waiters queue.
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_LOCK_PI
+	 * 3. val     - not used
+	 * 4. timeout - timeout
+	 * 5. uaddr2  - not used
+	 * 6. val3    - not used
+	 */
+
+	*uaddr = getpid();
+
+	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_LOCK_PI, VAL, tmout, uaddr2 + 1,
+		VAL3, (rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_LOCK_PI, {%jd, %jd}) = %s\n",
+		uaddr + 1, (intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec,
+		sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_LOCK_PI, VAL,
+		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_LOCK_PI_PRIVATE, {%jd, %jd}) = %s\n",
+		uaddr + 1, (intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec,
+		sprintrc(rc));
+
+	/* NULL is passed by invalid_op() in cases valid timeout address is
+	 * needed */
+	CHECK_INVALID_CLOCKRT(FUTEX_LOCK_PI, ARG4, "NULL");
+
+	/* FUTEX_UNLOCK_PI - slow path for mutex unlock with process inheritance
+	 *                   support. Expected to be called by process in case
+	 *                   it failed to execute fast path (it usually means
+	 *                   that FUTEX_WAITERS flag had been set while the lock
+	 *                   has been held).
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_UNLOCK_PI
+	 * 3. val     - not used
+	 * 4. timeout - not used
+	 * 5. uaddr2  - not used
+	 * 6. val3    - not used
+	 */
+
+	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_UNLOCK_PI, VAL, tmout, uaddr2 + 1,
+		VAL3, (rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_UNLOCK_PI) = %s\n", uaddr + 1, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_UNLOCK_PI, VAL,
+		tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_UNLOCK_PI_PRIVATE) = %s\n", uaddr +1,
+		sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_UNLOCK_PI, 0);
+
+	/* FUTEX_TRYLOCK_PI - slow path for mutex trylock with process
+	 *                 inheritance support.
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_TRYLOCK_PI
+	 * 3. val     - not used
+	 * 4. timeout - not used
+	 * 5. uaddr2  - not used
+	 * 6. val3    - not used
+	 */
+
+	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_TRYLOCK_PI, VAL, tmout, uaddr2 + 1,
+		VAL3, (rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_TRYLOCK_PI) = %s\n", uaddr + 1, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr + 1, FUTEX_PRIVATE_FLAG | FUTEX_TRYLOCK_PI,
+		VAL, tmout, uaddr2 + 1, VAL3, (rc == -1) && (errno == EFAULT));
+	printf("futex(%p, FUTEX_TRYLOCK_PI_PRIVATE) = %s\n", uaddr + 1,
+		sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_TRYLOCK_PI, 0);
+
+	/* FUTEX_WAIT_REQUEUE_PI - kernel-side handling of special case when
+	 *                         processes should be re-queued on PI-aware
+	 *                         futexes. This is so special since PI futexes
+	 *                         utilize rt_mutex and it should be at no time
+	 *                         left free with a wait queue, so this should
+	 *                         be performed atomically in-kernel.
+	 * Possible flags: PRIVATE, CLOCKRT
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_WAIT_REQUEUE_PI
+	 * 3. val     - expected value stored in uaddr
+	 * 4. timeout - timeout
+	 * 5. uaddr2  - (PI-aware) futex address to requeue process on
+	 * 6. val3    - not used (in kernel, it always initialized to
+	 *              FUTEX_BITSET_MATCH_ANY and passed to
+	 *              futex_wait_requeue_pi())
+	 */
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_WAIT_REQUEUE_PI, VAL, tmout, uaddr2,
+		VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI, %u, {%jd, %jd}, %p) = %s\n",
+		uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, uaddr2, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_WAIT_REQUEUE_PI,
+		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI_PRIVATE, %u, {%jd, %jd}, %p) "
+		"= %s\n", uaddr, VAL_PR, (intmax_t) tmout->tv_sec,
+		(intmax_t) tmout->tv_nsec, uaddr2, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_WAIT_REQUEUE_PI,
+		VAL, tmout, uaddr2, VAL3, (rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, %u, "
+		"{%jd, %jd}, %p) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec, uaddr2,
+		sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CLOCK_REALTIME | FUTEX_PRIVATE_FLAG |
+		FUTEX_WAIT_REQUEUE_PI, VAL, tmout, uaddr2, VAL3,
+		(rc == -1) && (errno == EAGAIN));
+	printf("futex(%p, FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME, "
+		"%u, {%jd, %jd}, %p) = %s\n", uaddr, VAL_PR,
+		(intmax_t) tmout->tv_sec, (intmax_t) tmout->tv_nsec, uaddr2,
+		sprintrc(rc));
+
+	/* FUTEX_CMP_REQUEUE_PI - version of FUTEX_CMP_REQUEUE which re-queues
+	 *                        on PI-aware futex.
+	 * Possible flags: PRIVATE
+	 * 1. uaddr   - futex address
+	 * 2. op      - FUTEX_CMP_REQUEUE
+	 * 3. val     - how many processes to wake
+	 * 4. val2    - amount of processes to re-queue on uadr2
+	 * 5. uaddr2  - (PI-aware) futex address, to re-queue waiting processes
+	 *              on
+	 * 6. val3    - expected value stored in uaddr
+	 */
+
+	/* All these should fail with EINVAL since we try to re-queue to  non-PI
+	 * futex.
+	 */
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CMP_REQUEUE_PI, VAL, VAL2, uaddr2, VAL3,
+		(rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_CMP_REQUEUE_PI, %u, %u, %p, %u) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, VAL3_PR, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_CMP_REQUEUE_PI, VAL, VAL2, uaddr2,
+		*uaddr, (rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_CMP_REQUEUE_PI, %u, %u, %p, %u) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
+
+	CHECK_FUTEX_ENOSYS(uaddr, FUTEX_PRIVATE_FLAG | FUTEX_CMP_REQUEUE_PI,
+		VAL, VAL2, uaddr2, *uaddr, (rc == -1) && (errno == EINVAL));
+	printf("futex(%p, FUTEX_CMP_REQUEUE_PI_PRIVATE, %u, %u, %p, %u) = %s\n",
+		uaddr, VAL_PR, VAL2_PR, uaddr2, *uaddr, sprintrc(rc));
+
+	CHECK_INVALID_CLOCKRT(FUTEX_CMP_REQUEUE_PI, ARG3 | ARG4 | ARG5 | ARG6,
+		"%u", "%u", "%#lx", "%u");
+
+	/*
+	 * Unknown commands
+	 */
+
+	CHECK_FUTEX(uaddr, 0xd, VAL, tmout + 1, uaddr2 + 1, VAL3,
+		(rc == -1) && (errno == ENOSYS));
+	printf("futex(%p, 0xd /* FUTEX_??? */, %u, %p, %p, %#x) = %s\n",
+		uaddr, VAL_PR, tmout + 1, uaddr2 + 1, VAL3_PR, sprintrc(rc));
+
+	CHECK_FUTEX(uaddr, 0xbefeeded, VAL, tmout + 1, uaddr2, VAL3,
+		(rc == -1) && (errno == ENOSYS));
+	printf("futex(%p, 0xbefeeded /* FUTEX_??? */, %u, %p, %p, %#x) = %s\n",
+		uaddr, VAL_PR, tmout + 1, uaddr2, VAL3_PR, sprintrc(rc));
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_futex")
+
+#endif
diff --git a/tests/futex.test b/tests/futex.test
new file mode 100755
index 0000000..fc98267
--- /dev/null
+++ b/tests/futex.test
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# Check futex syscall decoding.
+
+. "${srcdir=.}/init.sh"
+
+run_strace_match_diff -a27
+run_strace_match_diff -v -a27
diff --git a/tests/futimesat.c b/tests/futimesat.c
index 785c894..4e76cc8 100644
--- a/tests/futimesat.c
+++ b/tests/futimesat.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_futimesat
 
diff --git a/tests/get_mempolicy.c b/tests/get_mempolicy.c
index 6923a21..6be3ef2 100644
--- a/tests/get_mempolicy.c
+++ b/tests/get_mempolicy.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_get_mempolicy
 
diff --git a/tests/getcpu.c b/tests/getcpu.c
new file mode 100644
index 0000000..baef1bb
--- /dev/null
+++ b/tests/getcpu.c
@@ -0,0 +1,76 @@
+/*
+ * Check decoding of getcpu syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __NR_getcpu
+
+# include <stdio.h>
+# include <unistd.h>
+
+int
+main(void)
+{
+	static const unsigned *bogus_cpu =
+		(unsigned *) (unsigned long) 0xfffffeedfffffaceULL;
+	static const unsigned *bogus_node =
+		(unsigned *) (unsigned long) 0xfffffca7ffffc0deULL;
+	static const unsigned *bogus_tcache =
+		(unsigned *) (unsigned long) 0xffffda7affffdeadULL;
+
+	long res;
+	unsigned *cpu = tail_alloc(sizeof(*cpu));
+	unsigned *node = tail_alloc(sizeof(*node));
+	long * tcache = tail_alloc(128);
+
+	res = syscall(__NR_getcpu, NULL, NULL, NULL);
+	printf("getcpu(NULL, NULL, NULL) = %s\n", sprintrc(res));
+
+	res = syscall(__NR_getcpu, bogus_cpu, bogus_node, bogus_tcache);
+	printf("getcpu(%p, %p, %p) = %s\n",
+	       bogus_cpu, bogus_node, bogus_tcache, sprintrc(res));
+
+	res = syscall(__NR_getcpu, cpu, node, tcache);
+	if (res != 0)
+		perror_msg_and_skip("getcpu");
+
+	printf("getcpu([%u], [%u], %p) = 0\n", *cpu, *node, tcache);
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_getcpu");
+
+#endif
diff --git a/tests/getcpu.test b/tests/getcpu.test
new file mode 100755
index 0000000..fe21265
--- /dev/null
+++ b/tests/getcpu.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of getcpu syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a25
diff --git a/tests/getcwd.c b/tests/getcwd.c
index 3135df2..707c25c 100644
--- a/tests/getcwd.c
+++ b/tests/getcwd.c
@@ -1,6 +1,6 @@
 #include "tests.h"
 
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getcwd
 
@@ -13,6 +13,7 @@
 {
 	long res;
 	char cur_dir[PATH_MAX + 1];
+	static const size_t bogus_size = (size_t) 0xbadc0deddeadfaceULL;
 
 	res = syscall(__NR_getcwd, cur_dir, sizeof(cur_dir));
 
@@ -23,9 +24,15 @@
 	print_quoted_string(cur_dir);
 	printf("\", %zu) = %ld\n", sizeof(cur_dir), res);
 
-	syscall(__NR_getcwd, cur_dir, 0);
+	res = syscall(__NR_getcwd, cur_dir, 0);
+	printf("getcwd(%p, 0) = %s\n", cur_dir, sprintrc(res));
 
-	printf("getcwd(%p, 0) = -1 ERANGE (%m)\n", cur_dir);
+	res = syscall(__NR_getcwd, NULL, bogus_size);
+	printf("getcwd(NULL, %zu) = %s\n", bogus_size, sprintrc(res));
+
+	res = syscall(__NR_getcwd, (void *) -1L, sizeof(cur_dir));
+	printf("getcwd(%p, %zu) = %s\n",
+	       (void *) -1L, sizeof(cur_dir), sprintrc(res));
 
 	puts("+++ exited with 0 +++");
 
diff --git a/tests/getdents.c b/tests/getdents.c
index 7ea2067..5e64234 100644
--- a/tests/getdents.c
+++ b/tests/getdents.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getdents
 
diff --git a/tests/getdents64.c b/tests/getdents64.c
index 54149d2..2243b84 100644
--- a/tests/getdents64.c
+++ b/tests/getdents64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getdents64
 
diff --git a/tests/getegid.c b/tests/getegid.c
index 31e4b44..98f8b9c 100644
--- a/tests/getegid.c
+++ b/tests/getegid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getegid
 
diff --git a/tests/getegid32.c b/tests/getegid32.c
index 7dc358a..d995186 100644
--- a/tests/getegid32.c
+++ b/tests/getegid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getegid32
 
diff --git a/tests/geteuid.c b/tests/geteuid.c
index 0820656..ef8269f 100644
--- a/tests/geteuid.c
+++ b/tests/geteuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_geteuid
 
diff --git a/tests/geteuid32.c b/tests/geteuid32.c
index 7e731d0..4341e46 100644
--- a/tests/geteuid32.c
+++ b/tests/geteuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_geteuid32
 
diff --git a/tests/getgid.c b/tests/getgid.c
index 46969d3..2e06039 100644
--- a/tests/getgid.c
+++ b/tests/getgid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getgid
 
diff --git a/tests/getgid32.c b/tests/getgid32.c
index 11580d0..52e4d76 100644
--- a/tests/getgid32.c
+++ b/tests/getgid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getgid32
 
diff --git a/tests/getgroups.c b/tests/getgroups.c
index d70689c..4abcdef 100644
--- a/tests/getgroups.c
+++ b/tests/getgroups.c
@@ -36,7 +36,7 @@
 #else
 
 # include "tests.h"
-# include <sys/syscall.h>
+# include <asm/unistd.h>
 
 # ifdef __NR_getgroups
 
@@ -95,30 +95,18 @@
 	printf("%s(0, NULL) = %ld\n", SYSCALL_NAME, rc);
 
 	rc = syscall(SYSCALL_NR, -1U, 0);
-	printf("%s(%u, NULL) = %ld %s (%m)\n",
-	       SYSCALL_NAME, -1U, rc, errno2name());
+	printf("%s(%u, NULL) = %s\n", SYSCALL_NAME, -1U, sprintrc(rc));
 
 	rc = syscall(SYSCALL_NR, -1L, 0);
-	printf("%s(%u, NULL) = %ld %s (%m)\n",
-	       SYSCALL_NAME, -1U, rc, errno2name());
+	printf("%s(%u, NULL) = %s\n", SYSCALL_NAME, -1U, sprintrc(rc));
 
 	const unsigned int ngroups_max = sysconf(_SC_NGROUPS_MAX);
 
 	rc = syscall(SYSCALL_NR, ngroups_max, 0);
-	if (rc < 0)
-		printf("%s(%u, NULL) = %ld %s (%m)\n",
-		       SYSCALL_NAME, ngroups_max, rc, errno2name());
-	else
-		printf("%s(%u, NULL) = %ld\n",
-		       SYSCALL_NAME, ngroups_max, rc);
+	printf("%s(%u, NULL) = %s\n", SYSCALL_NAME, ngroups_max, sprintrc(rc));
 
 	rc = syscall(SYSCALL_NR, (long) 0xffffffff00000000ULL | ngroups_max, 0);
-	if (rc < 0)
-		printf("%s(%u, NULL) = %ld %s (%m)\n",
-		       SYSCALL_NAME, ngroups_max, rc, errno2name());
-	else
-		printf("%s(%u, NULL) = %ld\n",
-		       SYSCALL_NAME, ngroups_max, rc);
+	printf("%s(%u, NULL) = %s\n", SYSCALL_NAME, ngroups_max, sprintrc(rc));
 
 	/* check how the second argument is decoded */
 	GID_TYPE *const g1 =
@@ -132,9 +120,8 @@
 
 	if (ngroups) {
 		rc = syscall(SYSCALL_NR, ngroups, efault);
-		printf("%s(%u, %p) = %ld %s (%m)\n",
-		       SYSCALL_NAME, (unsigned) ngroups, efault,
-		       rc, errno2name());
+		printf("%s(%u, %p) = %s\n",
+		       SYSCALL_NAME, (unsigned) ngroups, efault, sprintrc(rc));
 	}
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/getgroups32.c b/tests/getgroups32.c
index 2576548..d0a356d 100644
--- a/tests/getgroups32.c
+++ b/tests/getgroups32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getgroups32
 
diff --git a/tests/getpgrp.c b/tests/getpgrp.c
index fd3139b..8b9d088 100644
--- a/tests/getpgrp.c
+++ b/tests/getpgrp.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getpgrp
 
diff --git a/tests/getrandom.c b/tests/getrandom.c
index 4c17c29..de1a087 100644
--- a/tests/getrandom.c
+++ b/tests/getrandom.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getrandom
 
diff --git a/tests/getresgid.c b/tests/getresgid.c
index 5827cdd..b8c687b 100644
--- a/tests/getresgid.c
+++ b/tests/getresgid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getresgid
 
diff --git a/tests/getresgid32.c b/tests/getresgid32.c
index ca337d8..71f1134 100644
--- a/tests/getresgid32.c
+++ b/tests/getresgid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getresgid32
 
diff --git a/tests/getresuid.c b/tests/getresuid.c
index bf4ada1..b00f20b 100644
--- a/tests/getresuid.c
+++ b/tests/getresuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getresuid
 
diff --git a/tests/getresuid32.c b/tests/getresuid32.c
index 3154e27..4c9a83d 100644
--- a/tests/getresuid32.c
+++ b/tests/getresuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getresuid32
 
diff --git a/tests/getrlimit.c b/tests/getrlimit.c
index 9fb668d..bd9d0b0 100644
--- a/tests/getrlimit.c
+++ b/tests/getrlimit.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getrlimit
 
diff --git a/tests/getrusage.c b/tests/getrusage.c
index 7fd9823..3c09aa6 100644
--- a/tests/getrusage.c
+++ b/tests/getrusage.c
@@ -27,7 +27,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getrusage
 
diff --git a/tests/getuid.c b/tests/getuid.c
index 25731c8..57311f7 100644
--- a/tests/getuid.c
+++ b/tests/getuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getuid
 
diff --git a/tests/getuid32.c b/tests/getuid32.c
index c6f68ae..397dd08 100644
--- a/tests/getuid32.c
+++ b/tests/getuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_getuid32
 
diff --git a/tests/getxxid.c b/tests/getxxid.c
index 1f2076c..6eee52c 100644
--- a/tests/getxxid.c
+++ b/tests/getxxid.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_getxpid && defined __NR_getxuid && defined __NR_getxgid
 
diff --git a/tests/init.sh b/tests/init.sh
index b6fa522..46a08f9 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -56,10 +56,11 @@
 	fi
 	args="$*"
 	"$@" || {
-		if [ $? -eq 77 ]; then
+		rc=$?
+		if [ $rc -eq 77 ]; then
 			skip_ "$args exited with code 77"
 		else
-			fail_ "$args failed"
+			fail_ "$args failed with code $rc"
 		fi
 	}
 }
@@ -68,7 +69,7 @@
 run_prog_skip_if_failed()
 {
 	args="$*"
-	"$@" || framework_skip_ "$args failed"
+	"$@" || framework_skip_ "$args failed with code $?"
 }
 
 run_strace()
@@ -76,7 +77,7 @@
 	> "$LOG" || fail_ "failed to write $LOG"
 	args="$*"
 	$STRACE -o "$LOG" "$@" ||
-		dump_log_and_fail_with "$STRACE $args failed"
+		dump_log_and_fail_with "$STRACE $args failed with code $?"
 }
 
 run_strace_merge()
@@ -84,7 +85,7 @@
 	rm -f -- "$LOG".[0-9]*
 	run_strace -ff -tt "$@"
 	"$srcdir"/../strace-log-merge "$LOG" > "$LOG" ||
-		dump_log_and_fail_with 'strace-log-merge failed'
+		dump_log_and_fail_with 'strace-log-merge failed with code $?'
 	rm -f -- "$LOG".[0-9]*
 }
 
diff --git a/tests/ioctl_block.c b/tests/ioctl_block.c
index 3dc030d..07e7d34 100644
--- a/tests/ioctl_block.c
+++ b/tests/ioctl_block.c
@@ -50,7 +50,7 @@
 	const unsigned int *end = addr + size - sizeof(int);
 
 	for (; p <= end; ++p)
-		*(unsigned int *) p = magic;
+		*(unsigned int *) p = magic + (p - (unsigned int *) addr);
 }
 
 static struct xlat block_argless[] = {
diff --git a/tests/ioctl_evdev-v.c b/tests/ioctl_evdev-v.c
index 6f1adcf..3860716 100644
--- a/tests/ioctl_evdev-v.c
+++ b/tests/ioctl_evdev-v.c
@@ -1,3 +1,3 @@
 /* This file is part of ioctl_evdev-v strace test. */
-#define VERBOSE_IOCTL
+#define VERBOSE 1
 #include "ioctl_evdev.c"
diff --git a/tests/ioctl_evdev.c b/tests/ioctl_evdev.c
index 5040b1c..892075d 100644
--- a/tests/ioctl_evdev.c
+++ b/tests/ioctl_evdev.c
@@ -51,7 +51,7 @@
 		*(unsigned int *) p = magic;
 }
 
-# ifdef VERBOSE_IOCTL
+# if VERBOSE
 static void
 print_envelope(const struct ff_envelope *const e)
 {
@@ -60,7 +60,7 @@
 	       e->attack_length, e->attack_level,
 	       e->fade_length, e->fade_level);
 }
-# endif /* VERBOSE_IOCTL */
+# endif /* VERBOSE */
 
 static void
 print_ffe_common(const struct ff_effect *const ffe, const char *const type_str)
@@ -68,12 +68,12 @@
 	printf("ioctl(-1, EVIOCSFF, {type=%s, id=%" PRIu16
 	       ", direction=%" PRIu16 ", ",
 	       type_str, ffe->id, ffe->direction);
-# ifdef VERBOSE_IOCTL
+# if VERBOSE
 	printf("trigger={button=%hu, interval=%hu}"
 	       ", replay={length=%hu, delay=%hu}",
 	       ffe->trigger.button, ffe->trigger.interval,
 	       ffe->replay.length, ffe->replay.delay);
-# endif /* VERBOSE_IOCTL */
+# endif /* VERBOSE */
 }
 
 # define TEST_NULL_ARG(cmd) \
@@ -189,7 +189,7 @@
 	ioctl(-1, EVIOCSKEYCODE_V2, ike);
 	printf("ioctl(-1, EVIOCSKEYCODE_V2, {flags=%" PRIu8
 	       ", len=%" PRIu8 ", ", ike->flags, ike->len);
-#  ifdef VERBOSE_IOCTL
+#  if VERBOSE
 	printf("index=%" PRIu16 ", keycode=%s, scancode=[",
 	       ike->index, "KEY_1");
 	unsigned int i;
@@ -213,7 +213,7 @@
 	ioctl(-1, EVIOCSFF, ffe);
 	print_ffe_common(ffe, "FF_CONSTANT");
 
-#  ifdef VERBOSE_IOCTL
+#  if VERBOSE
 	printf(", constant={level=%hd", ffe->u.constant.level);
 	print_envelope(&ffe->u.constant.envelope);
 	printf("}");
@@ -223,7 +223,7 @@
 	errno = EBADF;
 	printf("}) = -1 EBADF (%m)\n");
 
-#  ifdef VERBOSE_IOCTL
+#  if VERBOSE
 	ffe->type = FF_RAMP;
 	ioctl(-1, EVIOCSFF, ffe);
 	print_ffe_common(ffe, "FF_RAMP");
diff --git a/tests/ioctl_rtc-v.c b/tests/ioctl_rtc-v.c
index abdace1..62b1615 100644
--- a/tests/ioctl_rtc-v.c
+++ b/tests/ioctl_rtc-v.c
@@ -1,3 +1,3 @@
 /* This file is part of ioctl_rtc-v strace test. */
-#define VERBOSE_IOCTL
+#define VERBOSE 1
 #include "ioctl_rtc.c"
diff --git a/tests/ioctl_rtc.c b/tests/ioctl_rtc.c
index ee09955..ac96763 100644
--- a/tests/ioctl_rtc.c
+++ b/tests/ioctl_rtc.c
@@ -56,7 +56,7 @@
 	       ", tm_mday=%d, tm_mon=%d, tm_year=%d",
 	       rt->tm_sec, rt->tm_min, rt->tm_hour,
 	       rt->tm_mday, rt->tm_mon, rt->tm_year);
-#ifdef VERBOSE_IOCTL
+#if VERBOSE
 	printf(", tm_wday=%d, tm_yday=%d, tm_isdst=%d}",
 	       rt->tm_wday, rt->tm_yday, rt->tm_isdst);
 #else
diff --git a/tests/ioctl_uffdio.c b/tests/ioctl_uffdio.c
index 73a8a99..10b8b84 100644
--- a/tests/ioctl_uffdio.c
+++ b/tests/ioctl_uffdio.c
@@ -27,7 +27,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_userfaultfd && defined HAVE_LINUX_USERFAULTFD_H
 
diff --git a/tests/ioperm.c b/tests/ioperm.c
index f39bdf0..12342f3 100644
--- a/tests/ioperm.c
+++ b/tests/ioperm.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_ioperm
 
diff --git a/tests/iopl.c b/tests/iopl.c
index b547f3c..14ec29e 100644
--- a/tests/iopl.c
+++ b/tests/iopl.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_iopl
 
diff --git a/tests/ip_mreq.c b/tests/ip_mreq.c
index 0559b92..86cd2bc 100644
--- a/tests/ip_mreq.c
+++ b/tests/ip_mreq.c
@@ -29,50 +29,109 @@
 #include <netinet/in.h>
 
 #if defined IP_ADD_MEMBERSHIP && defined IPV6_ADD_MEMBERSHIP \
- && defined IPV6_JOIN_ANYCAST
+ && defined IPV6_JOIN_ANYCAST && defined HAVE_IF_INDEXTONAME
 
 # include <assert.h>
+# include <stdio.h>
 # include <unistd.h>
 # include <sys/socket.h>
 # include <arpa/inet.h>
+# include <net/if.h>
 
 int
 main(void)
 {
+	static const char multi4addr[] = "224.0.0.3";
+	static const char multi6addr[] = "ff01::c";
+	static const char interface[] = "127.0.0.1";
+
 	struct ip_mreq m4;
 	struct ipv6_mreq m6;
 
-	inet_pton(AF_INET, "224.0.0.3", &m4.imr_multiaddr);
-	inet_pton(AF_INET, "127.0.0.1", &m4.imr_interface);
-	inet_pton(AF_INET6, "ff01::c", &m6.ipv6mr_multiaddr);
-	m6.ipv6mr_interface = 1;
+	inet_pton(AF_INET, multi4addr, &m4.imr_multiaddr);
+	inet_pton(AF_INET, interface, &m4.imr_interface);
+	inet_pton(AF_INET6, multi6addr, &m6.ipv6mr_multiaddr);
+
+	m6.ipv6mr_interface = if_nametoindex("lo");
+	if (!m6.ipv6mr_interface)
+		perror_msg_and_skip("lo");
 
 	(void) close(0);
 	if (socket(AF_INET, SOCK_DGRAM, 0))
 		perror_msg_and_skip("socket");
 
-	assert(setsockopt(0, SOL_IP, IP_ADD_MEMBERSHIP, &m4, 1) == -1);
-	assert(setsockopt(0, SOL_IP, IP_DROP_MEMBERSHIP, &m4, 1) == -1);
 	if (setsockopt(0, SOL_IP, IP_ADD_MEMBERSHIP, &m4, sizeof(m4)) ||
 	    setsockopt(0, SOL_IP, IP_DROP_MEMBERSHIP, &m4, sizeof(m4)))
 		perror_msg_and_skip("setsockopt");
+	printf("setsockopt(0, SOL_IP, IP_ADD_MEMBERSHIP"
+	       ", {imr_multiaddr=inet_addr(\"%s\")"
+	       ", imr_interface=inet_addr(\"%s\")}, %u) = 0\n",
+	       multi4addr, interface, (unsigned) sizeof(m4));
+	printf("setsockopt(0, SOL_IP, IP_DROP_MEMBERSHIP"
+	       ", {imr_multiaddr=inet_addr(\"%s\")"
+	       ", imr_interface=inet_addr(\"%s\")}, %u) = 0\n",
+	       multi4addr, interface, (unsigned) sizeof(m4));
+
+	assert(setsockopt(0, SOL_IP, IP_ADD_MEMBERSHIP, &m4, 1) == -1);
+	printf("setsockopt(0, SOL_IP, IP_ADD_MEMBERSHIP, \"\\%hho\", 1)"
+	       " = -1 %s (%m)\n",
+	       * (unsigned char *) (void *) &m4, errno2name());
+
+	assert(setsockopt(0, SOL_IP, IP_DROP_MEMBERSHIP, &m4, 1) == -1);
+	printf("setsockopt(0, SOL_IP, IP_DROP_MEMBERSHIP, \"\\%hho\", 1)"
+	       " = -1 %s (%m)\n",
+	       * (unsigned char *) (void *) &m4, errno2name());
 
 	assert(setsockopt(0, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m6, 1) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_ADD_MEMBERSHIP, \"\\%hho\", 1)"
+	       " = -1 %s (%m)\n",
+	       * (unsigned char *) (void *) &m6, errno2name());
 	assert(setsockopt(0, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, 1) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_DROP_MEMBERSHIP, \"\\%hho\", 1)"
+	       " = -1 %s (%m)\n",
+	       * (unsigned char *) (void *) &m6, errno2name());
+
 	assert(setsockopt(0, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m6, sizeof(m6)) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_ADD_MEMBERSHIP"
+	       ", {ipv6mr_multiaddr=inet_pton(\"%s\")"
+	       ", ipv6mr_interface=if_nametoindex(\"lo\")}, 20) = -1 %s (%m)\n",
+	       multi6addr, errno2name());
+
 	assert(setsockopt(0, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, sizeof(m6)) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_DROP_MEMBERSHIP"
+	       ", {ipv6mr_multiaddr=inet_pton(\"%s\")"
+	       ", ipv6mr_interface=if_nametoindex(\"lo\")}, 20) = -1 %s (%m)\n",
+	       multi6addr, errno2name());
 
 	assert(setsockopt(0, SOL_IPV6, IPV6_JOIN_ANYCAST, &m6, 1) == -1);
-	assert(setsockopt(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, &m6, 1) == -1);
-	assert(setsockopt(0, SOL_IPV6, IPV6_JOIN_ANYCAST, &m6, sizeof(m6)) == -1);
-	assert(setsockopt(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, &m6, sizeof(m6)) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_JOIN_ANYCAST, \"\\%hho\", 1)"
+	       " = -1 %s (%m)\n",
+	       * (unsigned char *) (void *) &m6, errno2name());
 
+	assert(setsockopt(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, &m6, 1) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, \"\\%hho\", 1)"
+	       " = -1 %s (%m)\n",
+	       * (unsigned char *) (void *) &m6, errno2name());
+
+	assert(setsockopt(0, SOL_IPV6, IPV6_JOIN_ANYCAST, &m6, sizeof(m6)) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_JOIN_ANYCAST"
+	       ", {ipv6mr_multiaddr=inet_pton(\"%s\")"
+	       ", ipv6mr_interface=if_nametoindex(\"lo\")}, 20) = -1 %s (%m)\n",
+	       multi6addr, errno2name());
+
+	assert(setsockopt(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, &m6, sizeof(m6)) == -1);
+	printf("setsockopt(0, SOL_IPV6, IPV6_LEAVE_ANYCAST"
+	       ", {ipv6mr_multiaddr=inet_pton(\"%s\")"
+	       ", ipv6mr_interface=if_nametoindex(\"lo\")}, 20) = -1 %s (%m)\n",
+	       multi6addr, errno2name());
+
+	puts("+++ exited with 0 +++");
 	return 0;
 }
 
 #else
 
 SKIP_MAIN_UNDEFINED("IP_ADD_MEMBERSHIP && IPV6_ADD_MEMBERSHIP"
-		    " && IPV6_JOIN_ANYCAST")
+		    " && IPV6_JOIN_ANYCAST && HAVE_IF_INDEXTONAME")
 
 #endif
diff --git a/tests/ip_mreq.expected b/tests/ip_mreq.expected
deleted file mode 100644
index e694c73..0000000
--- a/tests/ip_mreq.expected
+++ /dev/null
@@ -1,12 +0,0 @@
-setsockopt\(0, SOL_IP, IP_ADD_MEMBERSHIP, "\\340", 1\) = -1 EINVAL .*
-setsockopt\(0, SOL_IP, IP_DROP_MEMBERSHIP, "\\340", 1\) = -1 EINVAL .*
-setsockopt\(0, SOL_IP, IP_ADD_MEMBERSHIP, \{imr_multiaddr=inet_addr\("224\.0\.0\.3"\), imr_interface=inet_addr\("127\.0\.0\.1"\)\}, 8\) = 0
-setsockopt\(0, SOL_IP, IP_DROP_MEMBERSHIP, \{imr_multiaddr=inet_addr\("224\.0\.0\.3"\), imr_interface=inet_addr\("127\.0\.0\.1"\)\}, 8\) = 0
-setsockopt\(0, SOL_IPV6, IPV6_ADD_MEMBERSHIP, "\\377", 1\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_DROP_MEMBERSHIP, "\\377", 1\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_ADD_MEMBERSHIP, \{ipv6mr_multiaddr=inet_pton\("ff01::c"\), ipv6mr_interface=if_nametoindex\("lo"\)\}, 20\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_DROP_MEMBERSHIP, \{ipv6mr_multiaddr=inet_pton\("ff01::c"\), ipv6mr_interface=if_nametoindex\("lo"\)\}, 20\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_JOIN_ANYCAST, "\\377", 1\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, "\\377", 1\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_JOIN_ANYCAST, \{ipv6mr_multiaddr=inet_pton\("ff01::c"\), ipv6mr_interface=if_nametoindex\("lo"\)\}, 20\) = -1 ENOPROTOOPT .*
-setsockopt\(0, SOL_IPV6, IPV6_LEAVE_ANYCAST, \{ipv6mr_multiaddr=inet_pton\("ff01::c"\), ipv6mr_interface=if_nametoindex\("lo"\)\}, 20\) = -1 ENOPROTOOPT .*
diff --git a/tests/ip_mreq.test b/tests/ip_mreq.test
index d423b1b..d0a9e0f 100755
--- a/tests/ip_mreq.test
+++ b/tests/ip_mreq.test
@@ -3,9 +3,4 @@
 # Check {IP,IPV6}_{ADD,DROP}_MEMBERSHIP setsockopt decoding.
 
 . "${srcdir=.}/init.sh"
-
-run_prog
-run_strace -e setsockopt $args
-match_grep
-
-exit 0
+run_strace_match_diff -e trace=setsockopt
diff --git a/tests/ipc.c b/tests/ipc.c
index d33a09f..f5b9ef5 100644
--- a/tests/ipc.c
+++ b/tests/ipc.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_ipc && defined HAVE_LINUX_IPC_H
 
diff --git a/tests/ipc_msg.c b/tests/ipc_msg.c
index 2fd7d4f..b493843 100644
--- a/tests/ipc_msg.c
+++ b/tests/ipc_msg.c
@@ -32,6 +32,26 @@
 #include <stdlib.h>
 #include <sys/msg.h>
 
+#include "xlat.h"
+#include "xlat/resource_flags.h"
+
+/*
+ * Before glibc-2.22-122-gbe48165, ppc64 code tried to retrieve data
+ * provided in third argument of msgctl call (in case of IPC_SET cmd)
+ * which led to segmentation fault.
+ */
+#undef TEST_MSGCTL_BOGUS_ADDR
+#if defined __GLIBC__ && defined POWERPC64
+# if !(defined __GLIBC_MINOR__) \
+   || ((__GLIBC__ << 16) + __GLIBC_MINOR__ < (2 << 16) + 23)
+#  define TEST_MSGCTL_BOGUS_ADDR 0
+# endif
+#endif /* __GLIBC__ && POWERPC64 */
+
+#ifndef TEST_MSGCTL_BOGUS_ADDR
+# define TEST_MSGCTL_BOGUS_ADDR 1
+#endif
+
 static int id = -1;
 
 static void
@@ -45,46 +65,72 @@
 int
 main(void)
 {
+	static const key_t private_key =
+		(key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
+	static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL;
+	static const int bogus_msgid = 0xfdb97531;
+	static const int bogus_cmd = 0xdeadbeef;
+#if TEST_MSGCTL_BOGUS_ADDR
+	static void * const bogus_addr = (void *) -1L;
+#endif
+	static const int bogus_flags = 0xface1e55 & ~IPC_CREAT;
+
 	int rc;
 	struct msqid_ds ds;
 
-	id = msgget(IPC_PRIVATE, 0600);
+	rc = msgget(bogus_key, bogus_flags);
+	printf("msgget\\(%#llx, %s%s%s%#x\\|%#04o\\) += %s\n",
+	       zero_extend_signed_to_ull(bogus_key),
+	       IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
+	       IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
+	       IPC_NOWAIT & bogus_flags ? "IPC_NOWAIT\\|" : "",
+	       bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | IPC_NOWAIT),
+	       bogus_flags & 0777, sprintrc_grep(rc));
+
+	id = msgget(private_key, 0600);
 	if (id < 0)
 		perror_msg_and_skip("msgget");
 	printf("msgget\\(IPC_PRIVATE, 0600\\) += %d\n", id);
 	atexit(cleanup);
 
+	rc = msgctl(bogus_msgid, bogus_cmd, NULL);
+	printf("msgctl\\(%d, (IPC_64\\|)?%#x /\\* MSG_\\?\\?\\? \\*/, NULL\\)"
+	       " += %s\n", bogus_msgid, bogus_cmd, sprintrc_grep(rc));
+
+#if TEST_MSGCTL_BOGUS_ADDR
+	rc = msgctl(bogus_msgid, IPC_SET, bogus_addr);
+	printf("msgctl\\(%d, (IPC_64\\|)?IPC_SET, %p\\) += %s\n",
+	       bogus_msgid, bogus_addr, sprintrc_grep(rc));
+#endif
+
 	if (msgctl(id, IPC_STAT, &ds))
 		perror_msg_and_skip("msgctl IPC_STAT");
-	printf("msgctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{msg_perm=\\{uid=%u, gid=%u, "
-		"mode=%#o, key=%u, cuid=%u, cgid=%u\\}, msg_stime=%u, msg_rtime=%u, "
-		"msg_ctime=%u, msg_qnum=%u, msg_qbytes=%u, msg_lspid=%u, "
-		"msg_lrpid=%u\\}\\) += 0\n",
-		id, (unsigned) ds.msg_perm.uid, (unsigned) ds.msg_perm.gid,
-		(unsigned) ds.msg_perm.mode, (unsigned) ds.msg_perm.__key,
-		(unsigned) ds.msg_perm.cuid, (unsigned) ds.msg_perm.cgid,
-		(unsigned) ds.msg_stime, (unsigned) ds.msg_rtime,
-		(unsigned) ds.msg_ctime, (unsigned) ds.msg_qnum,
-		(unsigned) ds.msg_qbytes, (unsigned) ds.msg_lspid,
-		(unsigned) ds.msg_lrpid);
+	printf("msgctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{msg_perm=\\{uid=%u"
+	       ", gid=%u, mode=%#o, key=%u, cuid=%u, cgid=%u\\}, msg_stime=%u"
+	       ", msg_rtime=%u, msg_ctime=%u, msg_qnum=%u, msg_qbytes=%u"
+	       ", msg_lspid=%u, msg_lrpid=%u\\}\\) += 0\n",
+	       id, (unsigned) ds.msg_perm.uid, (unsigned) ds.msg_perm.gid,
+	       (unsigned) ds.msg_perm.mode, (unsigned) ds.msg_perm.__key,
+	       (unsigned) ds.msg_perm.cuid, (unsigned) ds.msg_perm.cgid,
+	       (unsigned) ds.msg_stime, (unsigned) ds.msg_rtime,
+	       (unsigned) ds.msg_ctime, (unsigned) ds.msg_qnum,
+	       (unsigned) ds.msg_qbytes, (unsigned) ds.msg_lspid,
+	       (unsigned) ds.msg_lrpid);
 
-	int max = msgctl(0, MSG_INFO, &ds);
-	if (max < 0)
-		perror_msg_and_skip("msgctl MSG_INFO");
-	printf("msgctl\\(0, (IPC_64\\|)?MSG_INFO, %p\\) += %d\n", &ds, max);
+	if (msgctl(id, IPC_SET, &ds))
+		perror_msg_and_skip("msgctl IPC_SET");
+	printf("msgctl\\(%d, (IPC_64\\|)?IPC_SET, \\{msg_perm=\\{uid=%u"
+	       ", gid=%u, mode=%#o\\}, ...\\}\\) += 0\n",
+	       id, (unsigned) ds.msg_perm.uid, (unsigned) ds.msg_perm.gid,
+	       (unsigned) ds.msg_perm.mode);
+
+	rc = msgctl(0, MSG_INFO, &ds);
+	printf("msgctl\\(0, (IPC_64\\|)?MSG_INFO, %p\\) += %s\n",
+	       &ds, sprintrc_grep(rc));
 
 	rc = msgctl(id, MSG_STAT, &ds);
-	if (rc != id) {
-		/*
-		 * In linux < v2.6.24-rc1 the first argument must be
-		 * an index in the kernel's internal array.
-		 */
-		if (-1 != rc || EINVAL != errno)
-			perror_msg_and_skip("msgctl MSG_STAT");
-		printf("msgctl\\(%d, (IPC_64\\|)?MSG_STAT, %p\\) += -1 EINVAL \\(%m\\)\n", id, &ds);
-	} else {
-		printf("msgctl\\(%d, (IPC_64\\|)?MSG_STAT, %p\\) += %d\n", id, &ds, id);
-	}
+	printf("msgctl\\(%d, (IPC_64\\|)?MSG_STAT, %p\\) += %s\n",
+	       id, &ds, sprintrc_grep(rc));
 
 	return 0;
 }
diff --git a/tests/ipc_sem.c b/tests/ipc_sem.c
index afe74d2..926fa89 100644
--- a/tests/ipc_sem.c
+++ b/tests/ipc_sem.c
@@ -32,6 +32,9 @@
 #include <stdlib.h>
 #include <sys/sem.h>
 
+#include "xlat.h"
+#include "xlat/resource_flags.h"
+
 union semun {
 	int              val;    /* Value for SETVAL */
 	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
@@ -53,17 +56,48 @@
 int
 main(void)
 {
+	static const key_t private_key =
+		(key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
+	static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL;
+	static const int bogus_semid = 0xfdb97531;
+	static const int bogus_semnum = 0xeca86420;
+	static const int bogus_size = 0xdec0ded1;
+	static const int bogus_flags = 0xface1e55;
+	static const int bogus_cmd = 0xdeadbeef;
+	static const unsigned long bogus_arg =
+		(unsigned long) 0xbadc0dedfffffaceULL;
+
 	int rc;
 	union semun un;
 	struct semid_ds ds;
 	struct seminfo info;
 
-	id = semget(IPC_PRIVATE, 1, 0600);
+	rc = semget(bogus_key, bogus_size, bogus_flags);
+	printf("semget\\(%#llx, %d, %s%s%s%#x\\|%#04o\\) += %s\n",
+	       zero_extend_signed_to_ull(bogus_key), bogus_size,
+	       IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
+	       IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
+	       IPC_NOWAIT & bogus_flags ? "IPC_NOWAIT\\|" : "",
+	       bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | IPC_NOWAIT),
+	       bogus_flags & 0777, sprintrc_grep(rc));
+
+	id = semget(private_key, 1, 0600);
 	if (id < 0)
 		perror_msg_and_skip("semget");
 	printf("semget\\(IPC_PRIVATE, 1, 0600\\) += %d\n", id);
 	atexit(cleanup);
 
+	rc = semctl(bogus_semid, bogus_semnum, bogus_cmd, bogus_arg);
+#ifdef __GLIBC__
+# define SEMCTL_BOGUS_ARG_FMT "(%#lx|\\[(%#lx|0)\\])"
+#else
+# define SEMCTL_BOGUS_ARG_FMT "(%#lx|\\[(%#lx|0)\\]|0)"
+#endif
+	printf("semctl\\(%d, %d, (IPC_64\\|)?%#x /\\* SEM_\\?\\?\\? \\*/"
+	       ", " SEMCTL_BOGUS_ARG_FMT "\\) += %s\n",
+	       bogus_semid, bogus_semnum, bogus_cmd,
+	       bogus_arg, bogus_arg, sprintrc_grep(rc));
+
 	un.buf = &ds;
 	if (semctl(id, 0, IPC_STAT, un))
 		perror_msg_and_skip("semctl IPC_STAT");
@@ -71,27 +105,14 @@
 	       id, &ds);
 
 	un.__buf = &info;
-	int max = semctl(0, 0, SEM_INFO, un);
-	if (max < 0)
-		perror_msg_and_skip("semctl SEM_INFO");
-	printf("semctl\\(0, 0, (IPC_64\\|)?SEM_INFO, \\[?%p\\]?\\) += %d\n",
-	       &info, max);
+	rc = semctl(0, 0, SEM_INFO, un);
+	printf("semctl\\(0, 0, (IPC_64\\|)?SEM_INFO, \\[?%p\\]?\\) += %s\n",
+	       &info, sprintrc_grep(rc));
 
 	un.buf = &ds;
 	rc = semctl(id, 0, SEM_STAT, un);
-	if (rc != id) {
-		/*
-		 * In linux < v2.6.24-rc1 the first argument must be
-		 * an index in the kernel's internal array.
-		 */
-		if (-1 != rc || EINVAL != errno)
-			perror_msg_and_skip("semctl SEM_STAT");
-		printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\)"
-		       " += -1 EINVAL \\(%m\\)\n", id, &ds);
-	} else {
-		printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\)"
-		       " += %d\n", id, &ds, id);
-	}
+	printf("semctl\\(%d, 0, (IPC_64\\|)?SEM_STAT, \\[?%p\\]?\\) += %s\n",
+	       id, &ds, sprintrc_grep(rc));
 
 	return 0;
 }
diff --git a/tests/ipc_shm.c b/tests/ipc_shm.c
index 54723e2..66960ff 100644
--- a/tests/ipc_shm.c
+++ b/tests/ipc_shm.c
@@ -32,6 +32,9 @@
 #include <stdlib.h>
 #include <sys/shm.h>
 
+#include "xlat.h"
+#include "xlat/shm_resource_flags.h"
+
 static int id = -1;
 
 static void
@@ -45,15 +48,50 @@
 int
 main(void)
 {
+	static const key_t private_key =
+		(key_t) (0xffffffff00000000ULL | IPC_PRIVATE);
+	static const key_t bogus_key = (key_t) 0xeca86420fdb97531ULL;
+	static const int bogus_id = 0xdefaced1;
+	static const int bogus_cmd = 0xdefaced2;
+	static void * const bogus_addr = (void *) -1L;
+	static const size_t bogus_size =
+	/*
+	 * musl sets size to SIZE_MAX if size argument is greater than
+	 * PTRDIFF_MAX - musl/src/ipc/shmget.c
+	 */
+	#ifdef __GLIBC__
+		(size_t) 0xdec0ded1dec0ded2ULL;
+	#else
+		(size_t) 0x1e55c0de5dec0dedULL;
+	#endif
+	static const int bogus_flags = 0xface1e55;
+
 	int rc;
 	struct shmid_ds ds;
 
-	id = shmget(IPC_PRIVATE, 1, 0600);
+	rc = shmget(bogus_key, bogus_size, bogus_flags);
+	printf("shmget\\(%#llx, %zu, %s%s%s%#x\\|%#04o\\) += %s\n",
+	       zero_extend_signed_to_ull(bogus_key), bogus_size,
+	       IPC_CREAT & bogus_flags ? "IPC_CREAT\\|" : "",
+	       IPC_EXCL & bogus_flags ? "IPC_EXCL\\|" : "",
+	       SHM_HUGETLB & bogus_flags ? "SHM_HUGETLB\\|" : "",
+	       bogus_flags & ~(0777 | IPC_CREAT | IPC_EXCL | SHM_HUGETLB),
+	       bogus_flags & 0777, sprintrc_grep(rc));
+
+	id = shmget(private_key, 1, 0600);
 	if (id < 0)
 		perror_msg_and_skip("shmget");
 	printf("shmget\\(IPC_PRIVATE, 1, 0600\\) += %d\n", id);
 	atexit(cleanup);
 
+	rc = shmctl(bogus_id, bogus_cmd, NULL);
+	printf("shmctl\\(%d, (IPC_64\\|)?%#x /\\* SHM_\\?\\?\\? \\*/, NULL\\)"
+	       " += %s\n", bogus_id, bogus_cmd, sprintrc_grep(rc));
+
+	rc = shmctl(bogus_id, IPC_STAT, bogus_addr);
+	printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, %p\\) += %s\n",
+	       bogus_id, bogus_addr, sprintrc_grep(rc));
+
 	if (shmctl(id, IPC_STAT, &ds))
 		perror_msg_and_skip("shmctl IPC_STAT");
 	printf("shmctl\\(%d, (IPC_64\\|)?IPC_STAT, \\{shm_perm=\\{uid=%u, gid=%u, "
@@ -68,23 +106,20 @@
 		(unsigned) ds.shm_atime, (unsigned) ds.shm_dtime,
 		(unsigned) ds. shm_ctime);
 
-	int max = shmctl(0, SHM_INFO, &ds);
-	if (max < 0)
-		perror_msg_and_skip("shmctl SHM_INFO");
-	printf("shmctl\\(0, (IPC_64\\|)?SHM_INFO, %p\\) += %d\n", &ds, max);
+	if (shmctl(id, IPC_SET, &ds))
+		perror_msg_and_skip("shmctl IPC_SET");
+	printf("shmctl\\(%d, (IPC_64\\|)?IPC_SET, \\{shm_perm=\\{uid=%u, gid=%u"
+	       ", mode=%#o\\}, ...\\}\\) += 0\n",
+	       id, (unsigned) ds.shm_perm.uid, (unsigned) ds.shm_perm.gid,
+	       (unsigned) ds.shm_perm.mode);
+
+	rc = shmctl(0, SHM_INFO, &ds);
+	printf("shmctl\\(0, (IPC_64\\|)?SHM_INFO, %p\\) += %s\n",
+	       &ds, sprintrc_grep(rc));
 
 	rc = shmctl(id, SHM_STAT, &ds);
-	if (rc != id) {
-		/*
-		 * In linux < v2.6.24-rc1 the first argument must be
-		 * an index in the kernel's internal array.
-		 */
-		if (-1 != rc || EINVAL != errno)
-			perror_msg_and_skip("shmctl SHM_STAT");
-		printf("shmctl\\(%d, (IPC_64\\|)?SHM_STAT, %p\\) += -1 EINVAL \\(%m\\)\n", id, &ds);
-	} else {
-		printf("shmctl\\(%d, (IPC_64\\|)?SHM_STAT, %p\\) += %d\n", id, &ds, id);
-	}
+	printf("shmctl\\(%d, (IPC_64\\|)?SHM_STAT, %p\\) += %s\n",
+	       id, &ds, sprintrc_grep(rc));
 
 	return 0;
 }
diff --git a/tests/keyctl.c b/tests/keyctl.c
new file mode 100644
index 0000000..b580981
--- /dev/null
+++ b/tests/keyctl.c
@@ -0,0 +1,824 @@
+/*
+ * Check decoding of keyctl syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __NR_keyctl
+
+# include <linux/types.h>
+# include <linux/keyctl.h>
+
+# include <errno.h>
+# include <inttypes.h>
+# include <stdarg.h>
+# include <stdbool.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+
+# include <sys/uio.h>
+
+# include "kernel_types.h"
+
+/* This check should be before #include "xlat/keyctl_commands.h" */
+# ifndef KEYCTL_DH_COMPUTE
+struct keyctl_dh_params {
+	int32_t private;
+	int32_t prime;
+	int32_t base;
+};
+# endif
+
+# include "xlat.h"
+# include "xlat/keyctl_commands.h"
+
+# ifndef KEY_SPEC_REQKEY_AUTH_KEY
+#  define KEY_SPEC_REQKEY_AUTH_KEY   -7
+# endif
+
+# ifndef KEY_SPEC_REQUESTOR_KEYRING
+#  define KEY_SPEC_REQUESTOR_KEYRING -8
+# endif
+
+static const size_t limit = 10;
+
+/*
+ * Well, this is true for DESCRIBE and GET_SECURITY, and false for READ and
+ * DH_COMPUTE and I see no ability to pass this information without
+ * significantly breaking interface.
+ */
+bool nul_terminated_buf = true;
+bool buf_in_arg = false;
+
+/*
+ * When this is called with positive size, the buffer provided is an "out"
+ * argument and rc contains resulting size (globally defined nul_terminated_buf
+ * controls whether it is nul-terminated or not). If size is negative,
+ * it contains "in" argument.
+ */
+void
+print_quoted_string_limit(const char *str, size_t size, long rc)
+{
+	size_t print_size = ((rc >= 0) && (size > 0)) ?
+		((unsigned long) rc > size ? size :
+		(unsigned long) rc) : size;
+	size_t limited_size = print_size > limit ? limit : print_size;
+
+	if ((rc == -1) && !buf_in_arg) {
+		printf("%p", str);
+		return;
+	}
+
+	if (!nul_terminated_buf ||
+	    (strnlen(str, limited_size) == limited_size)) {
+		printf("\"");
+		print_quoted_memory(str, limited_size);
+		if (print_size > limit)
+			printf("\"...");
+		else
+			printf("\"");
+	} else {
+		printf("\"");
+		print_quoted_string(str);
+		printf("\"");
+	}
+}
+
+static void
+print_arg(kernel_ulong_t arg, const char *str, const char *fmt, size_t size,
+	long rc)
+{
+	if (size == (size_t) -1)
+		size = 0;
+
+	if (str) {
+		printf("%s", str);
+	} else {
+		if (size == sizeof(uint64_t))
+			printf(fmt, (uint64_t)arg);
+		else if (size == sizeof(uint32_t))
+			printf(fmt, (uint32_t)arg);
+		else
+			print_quoted_string_limit((void *)arg, size, rc);
+	}
+}
+
+/*
+ * Arguments are passed as sz, val, str, fmt. Arguments are read until 4
+ * arguments are retrieved or size of 0 is occurred.
+ *
+ * str == NULL && fmt == NULL && sz not in {4, 8} - print_quoted_string_limit is
+ *   used for argument printing. If sz is negative, in argument is assumed, out
+ *   otherwise.
+ */
+void
+do_keyctl(kernel_ulong_t cmd, const char *cmd_str, ...)
+{
+	kernel_ulong_t args[4] = {
+		(kernel_ulong_t) 0xdeadfee1badc0de5ULL,
+		(kernel_ulong_t) 0xdeadfee2badc0de6ULL,
+		(kernel_ulong_t) 0xdeadfee3badc0de7ULL,
+		(kernel_ulong_t) 0xdeadfee4badc0de8ULL,
+	};
+	const char *arg_str[4] = { NULL };
+	const char *arg_fmt[4] = { "%llu", "%llu", "%llu", "%llu" };
+	size_t arg_sz[4] = {
+		sizeof(kernel_ulong_t),
+		sizeof(kernel_ulong_t),
+		sizeof(kernel_ulong_t),
+		sizeof(kernel_ulong_t),
+	};
+	unsigned i;
+	unsigned cnt = 0;
+
+	va_list ap;
+
+	va_start(ap, cmd_str);
+
+	do {
+		arg_sz[cnt] = va_arg(ap, size_t);
+		if (!arg_sz[cnt])
+			break;
+
+		if (arg_sz[cnt] == sizeof(uint64_t))
+			args[cnt] = va_arg(ap, uint64_t);
+		else if (arg_sz[cnt] == sizeof(uint32_t))
+			args[cnt] = va_arg(ap, uint32_t);
+		else
+			args[cnt] = (uintptr_t) va_arg(ap, void *);
+
+		arg_str[cnt] = va_arg(ap, char *);
+		arg_fmt[cnt] = va_arg(ap, char *);
+	} while (++cnt < 4);
+
+	long rc = syscall(__NR_keyctl, cmd, args[0], args[1], args[2], args[3]);
+	const char *errstr = sprintrc(rc);
+	printf("keyctl(%s", cmd_str);
+	for (i = 0; i < cnt; i++) {
+		printf(", ");
+		print_arg(args[i], arg_str[i], arg_fmt[i], arg_sz[i], rc);
+	}
+	printf(") = %s\n", errstr);
+}
+
+# define ARG_STR(_arg) (_arg), #_arg
+
+int
+main(void)
+{
+	enum { PR_LIMIT = 10, IOV_SIZE = 11, IOV_STR_SIZE = 4096 };
+
+	static const char *kulong_fmt =
+		sizeof(kernel_ulong_t) == sizeof(uint64_t) ? "%#llx" : "%#x";
+	static const char *ksize_fmt =
+		sizeof(kernel_ulong_t) == sizeof(uint64_t) ? "%llu" : "%u";
+	static const char *ptr_fmt =
+		sizeof(void *) == sizeof(uint64_t) ? "%#llx" : "%#x";
+	static const char unterminated1[] = { '\1', '\2', '\3', '\4', '\5' };
+	static const char unterminated2[] = { '\6', '\7', '\10', '\11', '\12' };
+	static const char short_type_str[] = "shrt type";
+	static const char short_desc_str[] = "shrt desc";
+	static const char long_type_str[] = "overly long key type";
+	static const char long_desc_str[] = "overly long key description";
+	static const int32_t bogus_key1 = 0xdeadf00d;
+	static const int32_t bogus_key2 = 0x1eefdead;
+	static const kernel_ulong_t bogus_key3 =
+		(kernel_ulong_t) 0xdec0ded1dec0ded2ULL;
+	static const char *bogus_key3_str = "-557785390";
+
+	static const struct keyctl_dh_params kcdhp_data = {
+		KEY_SPEC_GROUP_KEYRING, 1234567890, 3141592653U };
+	static const char *kcdhp_str = "{private=KEY_SPEC_GROUP_KEYRING, "
+		"prime=1234567890, base=-1153374643}";
+
+	char *bogus_str = tail_memdup(unterminated1, sizeof(unterminated1));
+	char *bogus_desc = tail_memdup(unterminated2, sizeof(unterminated2));
+	char *short_type = tail_memdup(short_type_str, sizeof(short_type_str));
+	char *short_desc = tail_memdup(short_desc_str, sizeof(short_desc_str));
+	char *long_type = tail_memdup(long_type_str, sizeof(long_type_str));
+	char *long_desc = tail_memdup(long_desc_str, sizeof(long_desc_str));
+	char *kcdhp = tail_memdup(&kcdhp_data, sizeof(kcdhp_data));
+	struct iovec *key_iov = tail_alloc(sizeof(*key_iov) * IOV_SIZE);
+	char *bogus_buf1 = tail_alloc(9);
+	char *bogus_buf2 = tail_alloc(256);
+	char *key_iov_str1;
+	char *key_iov_str2 = tail_alloc(4096);
+	ssize_t ret;
+	ssize_t kis_size = 0;
+	int i;
+
+	key_iov[0].iov_base = short_type;
+	key_iov[0].iov_len = sizeof(short_type_str);
+	key_iov[1].iov_base = long_type;
+	key_iov[1].iov_len = sizeof(long_type_str);
+	key_iov[2].iov_base = short_desc;
+	key_iov[2].iov_len = sizeof(short_desc_str);
+	key_iov[3].iov_base = long_desc;
+	key_iov[3].iov_len = sizeof(long_desc_str);
+	key_iov[4].iov_base = bogus_str;
+	key_iov[4].iov_len = 32;
+
+	for (i = 5; i < IOV_SIZE; i++) {
+		key_iov[i].iov_base =
+			(void *) (uintptr_t) (0xfffffacefffff00dULL +
+			0x100000001ULL * i);
+		key_iov[i].iov_len = (size_t) (0xcaffeeeddefaced7ULL +
+			0x100000001ULL * i);
+	}
+
+	ret = asprintf(&key_iov_str1, "[{iov_base=%p, iov_len=%zu}, "
+		       "{iov_base=%p, iov_len=%zu}, "
+		       "{iov_base=%p, iov_len=%zu}, "
+		       "{iov_base=%p, iov_len=%zu}]",
+		       key_iov[IOV_SIZE - 4].iov_base,
+		       key_iov[IOV_SIZE - 4].iov_len,
+		       key_iov[IOV_SIZE - 3].iov_base,
+		       key_iov[IOV_SIZE - 3].iov_len,
+		       key_iov[IOV_SIZE - 2].iov_base,
+		       key_iov[IOV_SIZE - 2].iov_len,
+		       key_iov[IOV_SIZE - 1].iov_base,
+		       key_iov[IOV_SIZE - 1].iov_len);
+
+	if (ret < 0)
+		error_msg_and_fail("asprintf");
+
+	ret = snprintf(key_iov_str2, IOV_STR_SIZE,
+		       "[{iov_base=\"%s\\0\", iov_len=%zu}, "
+		       "{iov_base=\"%.10s\"..., iov_len=%zu}, "
+		       "{iov_base=\"%s\\0\", iov_len=%zu}, "
+		       "{iov_base=\"%.10s\"..., iov_len=%zu}, ",
+		       (char *) key_iov[0].iov_base, key_iov[0].iov_len,
+		       (char *) key_iov[1].iov_base, key_iov[1].iov_len,
+		       (char *) key_iov[2].iov_base, key_iov[2].iov_len,
+		       (char *) key_iov[3].iov_base, key_iov[3].iov_len);
+
+	if ((ret < 0) || (ret >= IOV_STR_SIZE))
+		error_msg_and_fail("snprintf");
+
+	for (i = 4; i < PR_LIMIT; i++) {
+		kis_size += ret;
+
+		ret = snprintf(key_iov_str2 + kis_size, IOV_STR_SIZE - kis_size,
+			       "{iov_base=%p, iov_len=%zu}, ",
+			       key_iov[i].iov_base, key_iov[i].iov_len);
+
+		if ((ret < 0) || (ret >= (IOV_STR_SIZE - kis_size)))
+			error_msg_and_fail("snprintf");
+	}
+
+	kis_size += ret;
+	snprintf(key_iov_str2 + kis_size, IOV_STR_SIZE - kis_size, "...]");
+
+
+	/* Invalid command */
+	do_keyctl((kernel_ulong_t) 0xbadc0dedfacefeedULL,
+		  "0xfacefeed /* KEYCTL_??? */",
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfee1badc0de5ULL, NULL, kulong_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfee2badc0de6ULL, NULL, kulong_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfee3badc0de7ULL, NULL, kulong_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfee4badc0de8ULL, NULL, kulong_fmt);
+
+
+	/* GET_KEYRING_ID */
+	do_keyctl(ARG_STR(KEYCTL_GET_KEYRING_ID),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xbadc0dedffffffffLLU, "-1",
+		  NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_KEYRING_ID),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), "%d",
+		  sizeof(int), 3141592653U, NULL, "%d",
+		  NULL, 0UL);
+
+
+	/* KEYCTL_JOIN_SESSION_KEYRING */
+	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
+		  sizeof(char *), ARG_STR(NULL), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
+		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
+		  sizeof(char *), bogus_str, NULL, ptr_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
+		  sizeof(char *), ARG_STR("bogus name"), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_JOIN_SESSION_KEYRING),
+		  sizeof(char *), "very long keyring name", "\"very long \"...",
+		  NULL, 0UL);
+
+
+	/* KEYCTL_UPDATE */
+
+	buf_in_arg = true;
+
+	do_keyctl(ARG_STR(KEYCTL_UPDATE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(char *), ARG_STR(NULL), NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_UPDATE),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfee4badc0de8ULL, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_UPDATE),
+		  sizeof(int32_t), bogus_key2, NULL, "%d",
+		  sizeof(char *), bogus_str, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfee4badc0de8ULL, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_UPDATE),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(short_desc_str), short_desc, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) sizeof(short_desc_str) - 1, NULL,
+			  ksize_fmt,
+		  0UL);
+
+	buf_in_arg = false;
+
+
+	/* KEYCTL_REVOKE */
+	do_keyctl(ARG_STR(KEYCTL_REVOKE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_REVOKE),
+		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_REVOKE),
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_REVOKE),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_CHOWN */
+	do_keyctl(ARG_STR(KEYCTL_CHOWN),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(uid_t), ARG_STR(-1), NULL,
+		  sizeof(gid_t), ARG_STR(-1), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_CHOWN),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(uid_t), 2718281828U, NULL, "%u",
+		  sizeof(gid_t), 3141592653U, NULL, "%u", 0UL);
+
+
+	/* KEYCTL_SETPERM */
+	do_keyctl(ARG_STR(KEYCTL_SETPERM),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQKEY_AUTH_KEY), NULL,
+		  sizeof(uint32_t), 0xffffffffU,
+		  "KEY_POS_VIEW|KEY_POS_READ|KEY_POS_WRITE|"
+		  "KEY_POS_SEARCH|KEY_POS_LINK|KEY_POS_SETATTR|"
+		  "KEY_USR_VIEW|KEY_USR_READ|KEY_USR_WRITE|"
+		  "KEY_USR_SEARCH|KEY_USR_LINK|KEY_USR_SETATTR|"
+		  "KEY_GRP_VIEW|KEY_GRP_READ|KEY_GRP_WRITE|"
+		  "KEY_GRP_SEARCH|KEY_GRP_LINK|KEY_GRP_SETATTR|"
+		  "KEY_OTH_VIEW|KEY_OTH_READ|KEY_OTH_WRITE|"
+		  "KEY_OTH_SEARCH|KEY_OTH_LINK|KEY_OTH_SETATTR|"
+		  "0xc0c0c0c0", NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_SETPERM),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(uint32_t), 0, NULL, "%#x", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_SETPERM),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(uint32_t), 0xc0c0c0c0, "0xc0c0c0c0 /* KEY_??? */",
+			  NULL,
+		  0UL);
+
+
+	/* KEYCTL_DESCRIBE */
+	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_DESCRIBE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) -4, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) -4, NULL, ksize_fmt, 0UL);
+
+
+	/* KEYCTL_CLEAR */
+	do_keyctl(ARG_STR(KEYCTL_CLEAR),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_CLEAR),
+		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_CLEAR),
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_CLEAR),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_LINK */
+	do_keyctl(ARG_STR(KEYCTL_LINK),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_LINK),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_LINK),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_UNLINK */
+	do_keyctl(ARG_STR(KEYCTL_UNLINK),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_UNLINK),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_UNLINK),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_SEARCH */
+	buf_in_arg = true;
+
+	do_keyctl(ARG_STR(KEYCTL_SEARCH),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_REQUESTOR_KEYRING), NULL,
+		  sizeof(char *), ARG_STR(NULL), NULL,
+		  sizeof(char *), ARG_STR(NULL), NULL,
+		  sizeof(int32_t), 0, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_SEARCH),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
+		  sizeof(char *), (char *) 0xfffff00dfffff157ULL, NULL, ptr_fmt,
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_USER_SESSION_KEYRING),
+			  NULL);
+	do_keyctl(ARG_STR(KEYCTL_SEARCH),
+		  sizeof(int32_t), bogus_key2, NULL, "%d",
+		  sizeof(char *), bogus_str, NULL, ptr_fmt,
+		  sizeof(char *), bogus_desc, NULL, ptr_fmt,
+		  sizeof(int32_t), bogus_key1, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_SEARCH),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(short_type_str), short_type, NULL, NULL,
+		  sizeof(short_desc_str), short_desc, NULL, NULL,
+		  sizeof(int32_t), bogus_key2, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_SEARCH),
+		  sizeof(int32_t), 0, NULL, "%d",
+		  sizeof(long_type_str), long_type, NULL, NULL,
+		  sizeof(long_type_str), long_desc, NULL, NULL,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
+
+	buf_in_arg = false;
+
+
+	/* KEYCTL_READ */
+	nul_terminated_buf = false;
+
+	/* Empty result is expected for these */
+	bogus_buf1[0] = '\377';
+	bogus_buf2[0] = '\377';
+
+	do_keyctl(ARG_STR(KEYCTL_READ),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_READ),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_READ),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_READ),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_READ),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) -4, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) -4, NULL, ksize_fmt, 0UL);
+
+	nul_terminated_buf = true;
+
+	/* KEYCTL_INSTANTIATE */
+	buf_in_arg = true;
+
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
+		  sizeof(int32_t), 0, NULL, "%d",
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  sizeof(int32_t), 0, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfeedLLU, NULL, ksize_fmt,
+		  sizeof(int32_t), bogus_key1, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
+		  sizeof(int32_t), bogus_key2, NULL, "%d",
+		  sizeof(char *), bogus_str, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 32LLU, NULL, ksize_fmt,
+		  sizeof(int32_t), bogus_key2, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(short_type_str), short_desc, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) sizeof(short_type_str) - 1, NULL,
+			  ksize_fmt,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL,
+		  sizeof(long_type_str), long_desc, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) sizeof(long_type_str), NULL, ksize_fmt,
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL);
+
+	buf_in_arg = false;
+
+
+	/* KEYCTL_NEGATE */
+	do_keyctl(ARG_STR(KEYCTL_NEGATE),
+		  sizeof(int32_t), 0, NULL, "%d",
+		  sizeof(uint32_t), 0, NULL, "%u",
+		  sizeof(int32_t), 0, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_NEGATE),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(uint32_t), 3141592653U, NULL, "%u",
+		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_NEGATE),
+		  sizeof(int32_t), bogus_key2, NULL, "%d",
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_NEGATE),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_SET_REQKEY_KEYRING */
+	do_keyctl(ARG_STR(KEYCTL_SET_REQKEY_KEYRING),
+		  sizeof(int32_t), ARG_STR(KEY_REQKEY_DEFL_NO_CHANGE), NULL,
+		  0UL);
+	/*
+	 * Keep it commented out until proper way of faking syscalls is not
+	 * implemented.
+	 */
+	/* do_keyctl(ARG_STR(KEYCTL_SET_REQKEY_KEYRING),
+		  sizeof(int32_t),
+		  ARG_STR(KEY_REQKEY_DEFL_REQUESTOR_KEYRING), NULL, 0UL); */
+	do_keyctl(ARG_STR(KEYCTL_SET_REQKEY_KEYRING),
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU,
+		  "0xbadc0ded /* KEY_REQKEY_DEFL_??? */", NULL, 0UL);
+
+
+	/* KEYCTL_SET_TIMEOUT */
+	do_keyctl(ARG_STR(KEYCTL_SET_TIMEOUT),
+		  sizeof(int32_t), 0, NULL, "%d",
+		  sizeof(uint32_t), 0, NULL, "%u", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_SET_TIMEOUT),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(uint32_t), 3141592653U, NULL, "%u", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_SET_TIMEOUT),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
+		  0UL);
+
+
+	/* KEYCTL_ASSUME_AUTHORITY */
+	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
+		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_ASSUME_AUTHORITY),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_GET_SECURITY */
+	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(uint32_t), 0xbadc0dedU, NULL, "%u", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_SECURITY),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_THREAD_KEYRING), NULL,
+		  (size_t) -4, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) -4, NULL, ksize_fmt, 0UL);
+
+
+	/* KEYCTL_SESSION_TO_PARENT */
+	do_keyctl(ARG_STR(KEYCTL_SESSION_TO_PARENT), 0UL);
+
+
+	/* KEYCTL_REJECT */
+	do_keyctl(ARG_STR(KEYCTL_REJECT),
+		  sizeof(int32_t), 0, NULL, "%d",
+		  sizeof(uint32_t), 0, NULL, "%u",
+		  sizeof(uint32_t), 0, NULL, "%u",
+		  sizeof(int32_t), 0, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_REJECT),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(uint32_t), 3141592653U, NULL, "%u",
+		  sizeof(uint32_t), 2718281828U, NULL, "%u",
+		  sizeof(int32_t), bogus_key1, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_REJECT),
+		  sizeof(int32_t), bogus_key2, NULL, "%d",
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadca75facef157LLU, "4207866199", NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
+		  sizeof(int32_t), bogus_key2, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_REJECT),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, "3134983661", NULL,
+		  sizeof(uint32_t), ARG_STR(ENODEV), NULL,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
+
+
+	/* KEYCTL_INSTANTIATE_IOV */
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
+		  sizeof(int32_t), 0, NULL, "%d",
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  sizeof(int32_t), 0, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
+		  sizeof(int32_t), bogus_key1, NULL, "%d",
+		  sizeof(char *), (char *) 0xfffffacefffffeedULL, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xdeadfeedLLU, NULL, ksize_fmt,
+		  sizeof(int32_t), bogus_key1, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
+		  sizeof(int32_t), bogus_key2, NULL, "%d",
+		  sizeof(char *), key_iov + IOV_SIZE, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 32LLU, NULL, ksize_fmt,
+		  sizeof(int32_t), bogus_key2, NULL, "%d");
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  sizeof(key_iov), key_iov + IOV_SIZE - 4, key_iov_str1, NULL,
+		  sizeof(kernel_ulong_t), (kernel_ulong_t) 4, NULL,
+			  ksize_fmt,
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL);
+	do_keyctl(ARG_STR(KEYCTL_INSTANTIATE_IOV),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL,
+		  sizeof(key_iov), key_iov, key_iov_str2, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) IOV_SIZE, NULL, ksize_fmt,
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL);
+
+
+	/* KEYCTL_INVALIDATE */
+	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
+		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
+		  sizeof(int32_t), bogus_key2, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_INVALIDATE),
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_GET_PERSISTENT */
+	do_keyctl(ARG_STR(KEYCTL_GET_PERSISTENT),
+		  sizeof(uid_t), ARG_STR(-1), NULL,
+		  sizeof(int32_t), ARG_STR(KEY_SPEC_GROUP_KEYRING), NULL, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_PERSISTENT),
+		  sizeof(uid_t), 2718281828U, NULL, "%u",
+		  sizeof(int32_t), bogus_key1, NULL, "%d", 0UL);
+	do_keyctl(ARG_STR(KEYCTL_GET_PERSISTENT),
+		  sizeof(uid_t), 2718281828U, NULL, "%u",
+		  sizeof(kernel_ulong_t), bogus_key3, bogus_key3_str, NULL,
+		  0UL);
+
+
+	/* KEYCTL_DH_COMPUTE */
+	nul_terminated_buf = false;
+
+	/* Empty result is expected for these */
+	bogus_buf1[0] = '\377';
+	bogus_buf2[0] = '\377';
+
+	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(char *), ARG_STR(NULL), ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
+		  sizeof(char *), kcdhp + 1, NULL, ptr_fmt,
+		  sizeof(char *), (char *) 0xfffff157ffffdeadULL, NULL, ptr_fmt,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 0xfeedf157badc0dedLLU, NULL, ksize_fmt,
+		  0UL);
+	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
+		  sizeof(kcdhp), kcdhp, kcdhp_str, NULL,
+		  (size_t) 9, (uintptr_t) bogus_buf1, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 9, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
+		  sizeof(kcdhp), kcdhp, kcdhp_str, NULL,
+		  (size_t) 256, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) 256, NULL, ksize_fmt, 0UL);
+	do_keyctl(ARG_STR(KEYCTL_DH_COMPUTE),
+		  sizeof(kcdhp), kcdhp, kcdhp_str, NULL,
+		  (size_t) -1, (uintptr_t) bogus_buf2, NULL, NULL,
+		  sizeof(kernel_ulong_t),
+		  (kernel_ulong_t) -1, NULL, ksize_fmt, 0UL);
+
+	nul_terminated_buf = true;
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_keyctl");
+
+#endif
diff --git a/tests/keyctl.test b/tests/keyctl.test
new file mode 100755
index 0000000..875a82d
--- /dev/null
+++ b/tests/keyctl.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of keyctl syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a31 -s10
diff --git a/tests/kill.c b/tests/kill.c
index 0755d68..0e07e1f 100644
--- a/tests/kill.c
+++ b/tests/kill.c
@@ -29,7 +29,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_kill
 
diff --git a/tests/ksysent.sed b/tests/ksysent.sed
index 56fe042..63ded4a 100644
--- a/tests/ksysent.sed
+++ b/tests/ksysent.sed
@@ -1,10 +1,10 @@
-#!/bin/sed -nf
+#!/bin/sed -rnf
 
 # should not have been exported at all
-/#define[[:space:]]\+__NR_\(sys_epoll_\|arch_specific_syscall\|syscalls\|syscall_count\|syscall_max\|available\|reserved\|unused\)/d
+/#define[[:space:]]+__NR_(sys_epoll_|arch_specific_syscall|syscalls|syscall_count|syscall_max|available|reserved|unused)/d
 
-# should not be named this way
-s/__NR_\(arm\|xtensa\)_fadvise64_64/__NR_fadvise64_64/
+# should not  have been named this way
+s/__NR_(arm|xtensa)_fadvise64_64/__NR_fadvise64_64/
 
 # legacy names
 s/__NR_get_cpu/__NR_getcpu/
@@ -12,4 +12,4 @@
 s/__NR_paccept/__NR_accept4/
 
 # generate
-s/#define[[:space:]]\+__NR_\([a-z_][^[:space:]]\+\)\([[:space:]].*\)\?$/#ifdef __NR_\1\n[__NR_\1 \& 0xffff] = "\1",\n#endif/p
+s/#define[[:space:]]+__NR_([a-z_][^[:space:]]+)([[:space:]].*)?$/#ifdef __NR_\1\n[__NR_\1 \& 0xffff] = "\1",\n#endif/p
diff --git a/tests/lchown.c b/tests/lchown.c
index a116901..a07c878 100644
--- a/tests/lchown.c
+++ b/tests/lchown.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_lchown
 
diff --git a/tests/lchown32.c b/tests/lchown32.c
index ff5ad3e..29cb01d 100644
--- a/tests/lchown32.c
+++ b/tests/lchown32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_lchown32
 
diff --git a/tests/libmmsg.c b/tests/libmmsg.c
index 07feb7c..b0db26d 100644
--- a/tests/libmmsg.c
+++ b/tests/libmmsg.c
@@ -29,7 +29,7 @@
 
 #include "tests.h"
 #include <errno.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifndef __NR_recvmmsg
 # define __NR_recvmmsg -1
diff --git a/tests/libsocketcall.c b/tests/libsocketcall.c
index 718b50e..04d6710 100644
--- a/tests/libsocketcall.c
+++ b/tests/libsocketcall.c
@@ -30,7 +30,7 @@
 #include "tests.h"
 #include <errno.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 /*
  * Invoke a socket syscall, either directly or via __NR_socketcall.
diff --git a/tests/link.c b/tests/link.c
index 4b84e41..d6550fd 100644
--- a/tests/link.c
+++ b/tests/link.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_link
 
diff --git a/tests/linkat.c b/tests/linkat.c
index 06d550e..2c3b8ba 100644
--- a/tests/linkat.c
+++ b/tests/linkat.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_linkat
 
diff --git a/tests/llseek.c b/tests/llseek.c
index e82535a..e687e94 100644
--- a/tests/llseek.c
+++ b/tests/llseek.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR__llseek
 
diff --git a/tests/lseek.c b/tests/lseek.c
index e5efaa3..84b2752 100644
--- a/tests/lseek.c
+++ b/tests/lseek.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_lseek
 
diff --git a/tests/lstat.c b/tests/lstat.c
index 663b638..76cb8a2 100644
--- a/tests/lstat.c
+++ b/tests/lstat.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_lstat
 
diff --git a/tests/lstat64.c b/tests/lstat64.c
index 4a1858b..68ef638 100644
--- a/tests/lstat64.c
+++ b/tests/lstat64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_lstat64
 
@@ -34,6 +34,7 @@
 # define TEST_SYSCALL_STR "lstat64"
 # define STRUCT_STAT struct stat64
 # define STRUCT_STAT_STR "struct stat64"
+# define STRUCT_STAT_IS_STAT64 1
 # define SAMPLE_SIZE ((libc_off_t) 43147718418)
 # include "lstatx.c"
 
diff --git a/tests/mbind.c b/tests/mbind.c
index b0f044d..94d4553 100644
--- a/tests/mbind.c
+++ b/tests/mbind.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_mbind
 
diff --git a/tests/membarrier.c b/tests/membarrier.c
index 7364d0f..adf24ef 100644
--- a/tests/membarrier.c
+++ b/tests/membarrier.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_membarrier
 
diff --git a/tests/memfd_create.c b/tests/memfd_create.c
index 9fe7f6d..ef49bed 100644
--- a/tests/memfd_create.c
+++ b/tests/memfd_create.c
@@ -1,13 +1,21 @@
 #include "tests.h"
-#include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_memfd_create
 
+# include <stdio.h>
+# include <unistd.h>
+
 int
 main(void)
 {
-	syscall(__NR_memfd_create, "strace", 7);
+	static const char text[] = "strace";
+	int rc = syscall(__NR_memfd_create, text, 7);
+
+	printf("memfd_create(\"%s\", %s) = %d %s (%m)\n",
+	       text, "MFD_CLOEXEC|MFD_ALLOW_SEALING|0x4", rc, errno2name());
+
+	puts("+++ exited with 0 +++");
 	return 0;
 }
 
diff --git a/tests/memfd_create.expected b/tests/memfd_create.expected
deleted file mode 100644
index 6fb938f..0000000
--- a/tests/memfd_create.expected
+++ /dev/null
@@ -1 +0,0 @@
-memfd_create\("strace", MFD_CLOEXEC\|MFD_ALLOW_SEALING\|0x4\) += -1 .*
diff --git a/tests/memfd_create.test b/tests/memfd_create.test
index 6a34fc1..4361dae 100755
--- a/tests/memfd_create.test
+++ b/tests/memfd_create.test
@@ -1,11 +1,6 @@
 #!/bin/sh
 
-# Check memfd_create syscall decoding.
+# Check decoding of memfd_create syscall.
 
 . "${srcdir=.}/init.sh"
-
-run_prog
-run_strace -e memfd_create $args
-match_grep
-
-exit 0
+run_strace_match_diff
diff --git a/tests/migrate_pages.c b/tests/migrate_pages.c
index 995723c..9f71b52 100644
--- a/tests/migrate_pages.c
+++ b/tests/migrate_pages.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_migrate_pages
 
diff --git a/tests/mkdir.c b/tests/mkdir.c
index dbb43c3..d971b18 100644
--- a/tests/mkdir.c
+++ b/tests/mkdir.c
@@ -1,23 +1,11 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_mkdir
 
-# include <stdio.h>
-# include <unistd.h>
-
-int
-main(void)
-{
-	static const char sample[] = "mkdir";
-
-	long rc = syscall(__NR_mkdir, sample, 0600);
-	printf("mkdir(\"%s\", 0600) = %ld %s (%m)\n",
-	       sample, rc, errno2name());
-
-	puts("+++ exited with 0 +++");
-	return 0;
-}
+# define TEST_SYSCALL_NR __NR_mkdir
+# define TEST_SYSCALL_STR "mkdir"
+# include "umode_t.c"
 
 #else
 
diff --git a/tests/mkdir.test b/tests/mkdir.test
index 98d5a52..38ed692 100755
--- a/tests/mkdir.test
+++ b/tests/mkdir.test
@@ -3,4 +3,4 @@
 # Check mkdir syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a21
+run_strace_match_diff -a20
diff --git a/tests/mkdirat.c b/tests/mkdirat.c
index cbdf16c..ce2e9c1 100644
--- a/tests/mkdirat.c
+++ b/tests/mkdirat.c
@@ -1,24 +1,13 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_mkdirat
 
-# include <stdio.h>
-# include <unistd.h>
-
-int
-main(void)
-{
-	static const char sample[] = "mkdirat.sample";
-	const long fd = (long) 0xdeadbeefffffffff;
-
-	long rc = syscall(__NR_mkdirat, fd, sample, 0600);
-	printf("mkdirat(%d, \"%s\", 0600) = %ld %s (%m)\n",
-	       (int) fd, sample, rc, errno2name());
-
-	puts("+++ exited with 0 +++");
-	return 0;
-}
+# define TEST_SYSCALL_NR		__NR_mkdirat
+# define TEST_SYSCALL_STR		"mkdirat"
+# define TEST_SYSCALL_PREFIX_ARGS	(long int) 0xdeadbeefffffffff,
+# define TEST_SYSCALL_PREFIX_STR	"-1, "
+# include "umode_t.c"
 
 #else
 
diff --git a/tests/mkdirat.test b/tests/mkdirat.test
index e41ce35..0fcb841 100755
--- a/tests/mkdirat.test
+++ b/tests/mkdirat.test
@@ -3,4 +3,4 @@
 # Check mkdirat syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a36
+run_strace_match_diff -a28
diff --git a/tests/mknod.c b/tests/mknod.c
index 91ce751..2d42874 100644
--- a/tests/mknod.c
+++ b/tests/mknod.c
@@ -1,51 +1,64 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_mknod
 
 # include <stdio.h>
 # include <sys/stat.h>
+# include <sys/sysmacros.h>
 # include <unistd.h>
 
-# ifdef MAJOR_IN_SYSMACROS
-#  include <sys/sysmacros.h>
-# endif
-# ifdef MAJOR_IN_MKDEV
-#  include <sys/mkdev.h>
-# endif
+static const char sample[] = "mknod";
 
-# define TMP_FILE "mknod"
+static long
+call_mknod(unsigned short mode, unsigned long dev)
+{
+	unsigned long lmode = (unsigned long) 0xffffffffffff0000 | mode;
+	return syscall(__NR_mknod, sample, lmode, dev);
+}
 
 int
 main(void)
 {
-	long rc = syscall(__NR_mknod, TMP_FILE, 0, 0xdeadbeef);
-	printf("mknod(\"%s\", 0) = %ld %s (%m)\n",
-	       TMP_FILE, rc, errno2name());
+	unsigned long dev = (unsigned long) 0xdeadbeefbadc0ded;
 
-	rc = syscall(__NR_mknod, TMP_FILE, -1L, 0xdeadbeef);
-	printf("mknod(\"%s\", %#o) = %ld %s (%m)\n",
-	       TMP_FILE, -1, rc, errno2name());
+	long rc = call_mknod(0, dev);
+	printf("mknod(\"%s\", 000) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
 
-	rc = syscall(__NR_mknod, TMP_FILE, S_IFREG|0600, 0);
-	printf("mknod(\"%s\", S_IFREG|0600) = %ld %s (%m)\n",
-	       TMP_FILE, rc, errno2name());
+	rc = call_mknod(0xffff, dev);
+	printf("mknod(\"%s\", %#03ho) = %ld %s (%m)\n",
+	       sample, (unsigned short) -1, rc, errno2name());
 
-	unsigned long dev =
-		(unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
+	rc = call_mknod(S_IFREG, 0);
+	printf("mknod(\"%s\", S_IFREG|000) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
 
-	rc = syscall(__NR_mknod, TMP_FILE, S_IFCHR | 0400, dev);
-	printf("mknod(\"%s\", S_IFCHR|0400, makedev(1, 7)) = %ld %s (%m)\n",
-	       TMP_FILE, rc, errno2name());
+	rc = call_mknod(S_IFDIR | 06, 0);
+	printf("mknod(\"%s\", S_IFDIR|006) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
 
-	const unsigned long mode =
-		((unsigned long) 0xfacefeedffffffff & ~S_IFMT) | S_IFBLK;
+	rc = call_mknod(S_IFLNK | 060, 0);
+	printf("mknod(\"%s\", S_IFLNK|060) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	rc = call_mknod(S_IFIFO | 0600, 0);
+	printf("mknod(\"%s\", S_IFIFO|0600) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	dev = (unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
+
+	rc = call_mknod(S_IFCHR | 024, dev);
+	printf("mknod(\"%s\", S_IFCHR|024, makedev(1, 7)) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	const unsigned short mode = (0xffff & ~S_IFMT) | S_IFBLK;
 	dev = (unsigned long) 0xdeadbeefbadc0ded;
 
-	rc = syscall(__NR_mknod, TMP_FILE, mode, dev);
-	printf("mknod(\"%s\", S_IFBLK|S_ISUID|S_ISGID|S_ISVTX|%#o"
+	rc = call_mknod(mode, dev);
+	printf("mknod(\"%s\", S_IFBLK|S_ISUID|S_ISGID|S_ISVTX|%#03ho"
 	       ", makedev(%u, %u)) = %ld %s (%m)\n",
-	       TMP_FILE, (unsigned) mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX),
+	       sample, mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX),
 	       major((unsigned) dev), minor((unsigned) dev),
 	       rc, errno2name());
 
diff --git a/tests/mknodat.c b/tests/mknodat.c
index 2cdc47c..614513e 100644
--- a/tests/mknodat.c
+++ b/tests/mknodat.c
@@ -1,34 +1,67 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_mknodat
 
 # include <stdio.h>
 # include <sys/stat.h>
+# include <sys/sysmacros.h>
 # include <unistd.h>
 
-# ifdef MAJOR_IN_SYSMACROS
-#  include <sys/sysmacros.h>
-# endif
-# ifdef MAJOR_IN_MKDEV
-#  include <sys/mkdev.h>
-# endif
+static const char sample[] = "mknodat_sample";
+static const long int fd = (long int) 0xdeadbeefffffffff;
+
+static long
+call_mknodat(unsigned short mode, unsigned long dev)
+{
+	unsigned long lmode = (unsigned long) 0xffffffffffff0000 | mode;
+	return syscall(__NR_mknodat, fd, sample, lmode, dev);
+}
 
 int
 main(void)
 {
-	static const char sample[] = "mknokat_sample";
-	const long int fd = (long int) 0xdeadbeefffffffff;
-	long rc = syscall(__NR_mknodat, fd, sample, S_IFREG|0600, 0);
-	printf("mknodat(%d, \"%s\", S_IFREG|0600) = %ld %s (%m)\n",
-	       (int) fd, sample, rc, errno2name());
+	unsigned long dev = (unsigned long) 0xdeadbeefbadc0ded;
 
-	const unsigned long dev =
-		(unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
+	long rc = call_mknodat(0, dev);
+	printf("mknodat(-1, \"%s\", 000) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
 
-	rc = syscall(__NR_mknodat, fd, sample, S_IFCHR | 0400, dev);
-	printf("mknodat(%d, \"%s\", S_IFCHR|0400, makedev(1, 7)) = %ld %s (%m)\n",
-	       (int) fd, sample, rc, errno2name());
+	rc = call_mknodat(0xffff, dev);
+	printf("mknodat(-1, \"%s\", %#03ho) = %ld %s (%m)\n",
+	       sample, (unsigned short) -1, rc, errno2name());
+
+	rc = call_mknodat(S_IFREG, 0);
+	printf("mknodat(-1, \"%s\", S_IFREG|000) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	rc = call_mknodat(S_IFDIR | 06, 0);
+	printf("mknodat(-1, \"%s\", S_IFDIR|006) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	rc = call_mknodat(S_IFLNK | 060, 0);
+	printf("mknodat(-1, \"%s\", S_IFLNK|060) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	rc = call_mknodat(S_IFIFO | 0600, 0);
+	printf("mknodat(-1, \"%s\", S_IFIFO|0600) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	dev = (unsigned long) 0xdeadbeef00000000 | makedev(1, 7);
+
+	rc = call_mknodat(S_IFCHR | 024, dev);
+	printf("mknodat(-1, \"%s\", S_IFCHR|024, makedev(1, 7)) = %ld %s (%m)\n",
+	       sample, rc, errno2name());
+
+	const unsigned short mode = (0xffff & ~S_IFMT) | S_IFBLK;
+	dev = (unsigned long) 0xdeadbeefbadc0ded;
+
+	rc = call_mknodat(mode, dev);
+	printf("mknodat(-1, \"%s\", S_IFBLK|S_ISUID|S_ISGID|S_ISVTX|%#03ho"
+	       ", makedev(%u, %u)) = %ld %s (%m)\n",
+	       sample, mode & ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX),
+	       major((unsigned) dev), minor((unsigned) dev),
+	       rc, errno2name());
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/mknodat.test b/tests/mknodat.test
index edf0498..1701a36 100755
--- a/tests/mknodat.test
+++ b/tests/mknodat.test
@@ -3,4 +3,4 @@
 # Check mknodat syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff
+run_strace_match_diff -a35
diff --git a/tests/mlock.c b/tests/mlock.c
index a56dc1f..be962e2 100644
--- a/tests/mlock.c
+++ b/tests/mlock.c
@@ -1,30 +1,22 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_mlock && defined __NR_munlock
 
 # include <stdio.h>
 # include <unistd.h>
 
-const int size = 1024;
-
 int
 main(void)
 {
+	const int size = 1024;
 	const char *addr = tail_alloc(size);
-	if (syscall(__NR_mlock, addr, size) == 0) {
-		printf("mlock(%p, %d) = 0\n", addr, size);
-	} else {
-		printf("mlock(%p, %d) = -1 %s (%m)\n",
-		       addr, size, errno2name());
-	}
 
-	if (syscall(__NR_munlock, addr, size) == 0) {
-		printf("munlock(%p, %d) = 0\n", addr, size);
-	} else {
-		printf("munlock(%p, %d) = -1 %s (%m)\n",
-		       addr, size, errno2name());
-	}
+	long rc = syscall(__NR_mlock, addr, size);
+	printf("mlock(%p, %d) = %s\n", addr, size, sprintrc(rc));
+
+	rc = syscall(__NR_munlock, addr, size);
+	printf("munlock(%p, %d) = %s\n", addr, size, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/mlock2.c b/tests/mlock2.c
index af63917..e557042 100644
--- a/tests/mlock2.c
+++ b/tests/mlock2.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_mlock2
 
@@ -36,9 +36,12 @@
 int
 main(void)
 {
-	long rc = syscall(__NR_mlock2, 0xdeadbeef, 0xdefaced, 0xffff);
-	printf("mlock2(0xdeadbeef, 233811181, MLOCK_ONFAULT|0xfffe)"
-	       " = %ld %s (%m)\n", rc, errno2name());
+	const unsigned long addr = (unsigned long) 0xfacefeeddeadbeefULL;
+	const unsigned long len = (unsigned long) 0xcafef00dbadc0dedULL;
+
+	long rc = syscall(__NR_mlock2, addr, len, -1UL);
+	printf("mlock2(%#lx, %lu, MLOCK_ONFAULT|0xfffffffe)"
+	       " = %ld %s (%m)\n", addr, len, rc, errno2name());
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/mlockall.c b/tests/mlockall.c
index cafa4d6..682d070 100644
--- a/tests/mlockall.c
+++ b/tests/mlockall.c
@@ -35,12 +35,11 @@
 int
 main(void)
 {
-	printf("mlockall(0) = %d EINVAL (%m)\n", mlockall(0));
+	int rc = mlockall(0);
+	printf("mlockall(0) = %s\n", sprintrc(rc));
 
-	if (mlockall(MCL_CURRENT) == 0)
-		puts("mlockall(MCL_CURRENT) = 0");
-	else
-		printf("mlockall(MCL_CURRENT) = -1 %s (%m)\n", errno2name());
+	rc = mlockall(MCL_CURRENT);
+	printf("mlockall(MCL_CURRENT) = %s\n", sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/mmsg_name-v.c b/tests/mmsg_name-v.c
index 60bd2bc..c663536 100644
--- a/tests/mmsg_name-v.c
+++ b/tests/mmsg_name-v.c
@@ -1,4 +1,4 @@
 /* This file is part of mmsg_name-v strace test. */
-#define VERBOSE_MMSGHDR
+#define VERBOSE 1
 #define TEST_NAME "mmsg_name-v"
 #include "mmsg_name.c"
diff --git a/tests/mmsg_name.c b/tests/mmsg_name.c
index f2b624a..a7a55c5 100644
--- a/tests/mmsg_name.c
+++ b/tests/mmsg_name.c
@@ -121,7 +121,7 @@
 		if (i)
 			printf(", ");
 		if (i >= IOV_MAX
-# ifndef VERBOSE_MMSGHDR
+# if !VERBOSE
 			|| i >= DEFAULT_STRLEN
 # endif
 		   ) {
@@ -165,7 +165,7 @@
 		if (i)
 			printf(", ");
 		if (i >= IOV_MAX
-#ifndef VERBOSE_MMSGHDR
+#if !VERBOSE
 			|| i >= DEFAULT_STRLEN
 #endif
 		   ) {
@@ -205,7 +205,7 @@
 	for (i = 0; i < rc; ++i) {
 		if (i)
 			printf(", ");
-#ifndef VERBOSE_MMSGHDR
+#if !VERBOSE
 		if (i >= DEFAULT_STRLEN) {
 			printf("...");
 			break;
diff --git a/tests/move_pages.c b/tests/move_pages.c
index 1059366..3be7446 100644
--- a/tests/move_pages.c
+++ b/tests/move_pages.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_move_pages
 
@@ -140,25 +140,19 @@
 
 	long rc = syscall(__NR_move_pages,
 			  pid, count, pages, NULL, status, flags);
+	const char *errstr = sprintrc(rc);
+	printf("move_pages(%d, %lu, ", (int) pid, count);
+	print_page_array(pages, count, 0);
+	printf(", NULL, ");
 	if (rc) {
-		int saved_errno = errno;
-		printf("move_pages(%d, %lu, ", (int) pid, count);
-		print_page_array(pages, count, 0);
-		printf(", NULL, ");
 		if (count)
 			printf("%p", status);
 		else
 			printf("[]");
-		errno = saved_errno;
-		printf(", MPOL_MF_MOVE) = %ld %s (%m)\n",
-		       rc, errno2name());
 	} else {
-		printf("move_pages(%d, %lu, ", (int) pid, count);
-		print_page_array(pages, count, 0);
-		printf(", NULL, ");
 		print_status_array(status, count);
-		printf(", MPOL_MF_MOVE) = 0\n");
 	}
+	printf(", MPOL_MF_MOVE) = %s\n", errstr);
 }
 
 static void
@@ -174,7 +168,7 @@
 
 	long rc = syscall(__NR_move_pages,
 			  pid, count, pages, nodes, status, flags);
-	int saved_errno = errno;
+	const char *errstr = sprintrc(rc);
 	printf("move_pages(%d, %lu, ", (int) pid, count);
 	print_page_array(pages, count, offset);
 	printf(", ");
@@ -184,13 +178,7 @@
 		printf("%p", status);
 	else
 		printf("[]");
-	printf(", MPOL_MF_MOVE_ALL) = ");
-	if (rc) {
-		errno = saved_errno;
-		printf("%ld %s (%m)\n", rc, errno2name());
-	} else {
-		puts("0");
-	}
+	printf(", MPOL_MF_MOVE_ALL) = %s\n", errstr);
 }
 
 int
diff --git a/tests/msg_control-v.c b/tests/msg_control-v.c
index d2a5653..b0afa52 100644
--- a/tests/msg_control-v.c
+++ b/tests/msg_control-v.c
@@ -1,3 +1,3 @@
 /* This file is part of msg_control-v strace test. */
-#define VERBOSE_MSGHDR
+#define VERBOSE 1
 #include "msg_control.c"
diff --git a/tests/msg_control.c b/tests/msg_control.c
index 4f23b2a..7540c3d 100644
--- a/tests/msg_control.c
+++ b/tests/msg_control.c
@@ -77,7 +77,7 @@
 	for (i = 0; i < nfd; ++i) {
 		if (i)
 			printf(", ");
-#ifndef VERBOSE_MSGHDR
+#if !VERBOSE
 		if (i >= DEFAULT_STRLEN) {
 			printf("...");
 			break;
@@ -479,7 +479,7 @@
 	for (i = 0; i < data_len; ++i) {
 		if (i)
 			printf(", ");
-#ifndef VERBOSE_MSGHDR
+#if !VERBOSE
 		if (i >= DEFAULT_STRLEN) {
 			printf("...");
 			break;
diff --git a/tests/nanosleep.c b/tests/nanosleep.c
index 6b5999b..db430e5 100644
--- a/tests/nanosleep.c
+++ b/tests/nanosleep.c
@@ -45,7 +45,7 @@
 		struct timespec ts;
 		uint32_t pad[2];
 	} req = {
-		.ts = { .tv_nsec = 0xc0de1 },
+		.ts.tv_nsec = 0xc0de1,
 		.pad = { 0xdeadbeef, 0xbadc0ded }
 	}, rem = {
 		.ts = { .tv_sec = 0xc0de2, .tv_nsec = 0xc0de3 },
diff --git a/tests/netlink_protocol.c b/tests/netlink_protocol.c
index aee9a87..34e114b 100644
--- a/tests/netlink_protocol.c
+++ b/tests/netlink_protocol.c
@@ -61,83 +61,65 @@
 		.magic = "abcd"
 	};
 	struct req *const req = tail_memdup(&c_req, sizeof(c_req));
+	long rc;
+	const char *errstr;
 
 	/* zero address */
-	if (sendto(fd, NULL, sizeof(*req), MSG_DONTWAIT, NULL, 0) != -1)
-		perror_msg_and_skip("sendto");
-
-	printf("sendto(%d, NULL, %u, MSG_DONTWAIT, NULL, 0) = -1 %s (%m)\n",
-	       fd, (unsigned) sizeof(*req), errno2name());
+	rc = sendto(fd, NULL, sizeof(*req), MSG_DONTWAIT, NULL, 0);
+	printf("sendto(%d, NULL, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
+	       fd, (unsigned) sizeof(*req), sprintrc(rc));
 
 	/* zero length */
-	if (sendto(fd, req, 0, MSG_DONTWAIT, NULL, 0) != 0)
-		perror_msg_and_skip("sendto");
-
-	printf("sendto(%d, \"\", 0, MSG_DONTWAIT, NULL, 0) = 0\n", fd);
+	rc = sendto(fd, req, 0, MSG_DONTWAIT, NULL, 0);
+	printf("sendto(%d, \"\", 0, MSG_DONTWAIT, NULL, 0) = %s\n",
+	       fd, sprintrc(rc));
 
 	/* zero address and length */
-	if (sendto(fd, NULL, 0, MSG_DONTWAIT, NULL, 0) != 0)
-		perror_msg_and_skip("sendto");
-
-	printf("sendto(%d, NULL, 0, MSG_DONTWAIT, NULL, 0) = 0\n", fd);
+	rc = sendto(fd, NULL, 0, MSG_DONTWAIT, NULL, 0);
+	printf("sendto(%d, NULL, 0, MSG_DONTWAIT, NULL, 0) = %s\n",
+	       fd, sprintrc(rc));
 
 	/* unfetchable struct nlmsghdr */
 	const void *const efault = tail_alloc(sizeof(struct nlmsghdr) - 1);
-	sendto(fd, efault, sizeof(struct nlmsghdr), MSG_DONTWAIT, NULL, 0);
-
-	printf("sendto(%d, %p, %u, MSG_DONTWAIT, NULL, 0) = -1 EFAULT (%m)\n",
-	       fd, efault, (unsigned) sizeof(struct nlmsghdr));
+	rc = sendto(fd, efault, sizeof(struct nlmsghdr), MSG_DONTWAIT, NULL, 0);
+	printf("sendto(%d, %p, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
+	       fd, efault, (unsigned) sizeof(struct nlmsghdr), sprintrc(rc));
 
 	/* whole message length < sizeof(struct nlmsghdr) */
-	if (sendto(fd, req->magic, sizeof(req->magic), MSG_DONTWAIT, NULL, 0)
-	    != (unsigned) sizeof(req->magic))
-		perror_msg_and_skip("sendto");
-
-	printf("sendto(%d, \"abcd\", %u, MSG_DONTWAIT, NULL, 0) = %u\n",
-	       fd, (unsigned) sizeof(req->magic), (unsigned) sizeof(req->magic));
+	rc = sendto(fd, req->magic, sizeof(req->magic), MSG_DONTWAIT, NULL, 0);
+	printf("sendto(%d, \"abcd\", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
+	       fd, (unsigned) sizeof(req->magic), sprintrc(rc));
 
 	/* a single message with some data */
-	if (sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0) !=
-	    (unsigned) sizeof(*req))
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
-	       ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+	       ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, req->nlh.nlmsg_len, NLM_F_DUMP,
-	       (unsigned) sizeof(*req), (unsigned) sizeof(*req));
+	       (unsigned) sizeof(*req), sprintrc(rc));
 
 	/* a single message without data */
 	req->nlh.nlmsg_len = sizeof(req->nlh);
-
-	if (sendto(fd, &req->nlh, sizeof(req->nlh), MSG_DONTWAIT, NULL, 0)
-	    != (unsigned) sizeof(req->nlh))
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, &req->nlh, sizeof(req->nlh), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
-	       ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+	       ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, req->nlh.nlmsg_len, NLM_F_DUMP,
-	       (unsigned) sizeof(req->nlh), (unsigned) sizeof(req->nlh));
+	       (unsigned) sizeof(req->nlh), sprintrc(rc));
 
 	/* nlmsg_len > whole message length */
 	req->nlh.nlmsg_len = sizeof(*req) + 8;
-	if (sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0) !=
-	    (unsigned) sizeof(*req))
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
-	       ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+	       ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, req->nlh.nlmsg_len, NLM_F_DUMP,
-	       (unsigned) sizeof(*req), (unsigned) sizeof(*req));
+	       (unsigned) sizeof(*req), sprintrc(rc));
 
 	/* nlmsg_len < sizeof(struct nlmsghdr) */
 	req->nlh.nlmsg_len = 8;
-	if (sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0) != sizeof(*req))
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
-	       ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+	       ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, req->nlh.nlmsg_len, NLM_F_DUMP,
-	       (unsigned) sizeof(*req), (unsigned) sizeof(*req));
+	       (unsigned) sizeof(*req), sprintrc(rc));
 
 	/* a sequence of two nlmsg objects */
 	struct reqs {
@@ -148,53 +130,47 @@
 	memcpy(&reqs->req1, &c_req, sizeof(c_req));
 	memcpy(&reqs->req2, &c_req, sizeof(c_req));
 
-	sendto(fd, reqs, sizeof(*reqs), MSG_DONTWAIT, NULL, 0);
-
+	rc = sendto(fd, reqs, sizeof(*reqs), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, [{{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
 	       ", seq=0, pid=0}, \"abcd\"}, {{len=%u, type=NLMSG_NOOP"
 	       ", flags=NLM_F_REQUEST|0x%x, seq=0, pid=0}, \"abcd\"}]"
-	       ", %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+	       ", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, reqs->req1.nlh.nlmsg_len, NLM_F_DUMP,
 	       reqs->req2.nlh.nlmsg_len, NLM_F_DUMP,
-	       (unsigned) sizeof(*reqs), (unsigned) sizeof(*reqs));
+	       (unsigned) sizeof(*reqs), sprintrc(rc));
 
 	/* unfetchable second struct nlmsghdr */
 	void *const efault2 = tail_memdup(&reqs->req1, sizeof(reqs->req1));
-	sendto(fd, efault2, sizeof(*reqs), MSG_DONTWAIT, NULL, 0);
-
+	rc = sendto(fd, efault2, sizeof(*reqs), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, [{{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
 	       ", seq=0, pid=0}, \"abcd\"}, %p], %u, MSG_DONTWAIT, NULL, 0)"
-	       " = -1 EFAULT (%m)\n",
+	       " = %s\n",
 	       fd, reqs->req1.nlh.nlmsg_len, NLM_F_DUMP,
-	       &((struct reqs *) efault2)->req2, (unsigned) sizeof(*reqs));
+	       &((struct reqs *) efault2)->req2, (unsigned) sizeof(*reqs),
+	       sprintrc(rc));
 
 	/* message length is not enough for the second struct nlmsghdr */
-	if (sendto(fd, reqs, sizeof(*reqs) - sizeof(req->nlh), MSG_DONTWAIT, NULL, 0)
-	    != sizeof(*reqs) - sizeof(req->nlh))
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, reqs, sizeof(*reqs) - sizeof(req->nlh), MSG_DONTWAIT,
+		    NULL, 0);
+	errstr = sprintrc(rc);
 	printf("sendto(%d, [{{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
 	       ", seq=0, pid=0}, \"abcd\"}, \"",
 	       fd, reqs->req1.nlh.nlmsg_len, NLM_F_DUMP);
 	print_quoted_memory((void *) &reqs->req2.nlh,
 			    sizeof(reqs->req2) - sizeof(req->nlh));
-	printf("\"], %u, MSG_DONTWAIT, NULL, 0) = %u\n",
-	       (unsigned) (sizeof(*reqs) - sizeof(req->nlh)),
-	       (unsigned) (sizeof(*reqs) - sizeof(req->nlh)));
+	printf("\"], %u, MSG_DONTWAIT, NULL, 0) = %s\n",
+	       (unsigned) (sizeof(*reqs) - sizeof(req->nlh)), errstr);
 
 	/* second nlmsg_len < sizeof(struct nlmsghdr) */
 	reqs->req2.nlh.nlmsg_len = 4;
-	if (sendto(fd, reqs, sizeof(*reqs), MSG_DONTWAIT, NULL, 0)
-	    != sizeof(*reqs))
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, reqs, sizeof(*reqs), MSG_DONTWAIT, NULL, 0);
 	printf("sendto(%d, [{{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
 	       ", seq=0, pid=0}, \"abcd\"}, {{len=%u, type=NLMSG_NOOP"
 	       ", flags=NLM_F_REQUEST|0x%x, seq=0, pid=0}}], %u"
-	       ", MSG_DONTWAIT, NULL, 0) = %u\n",
+	       ", MSG_DONTWAIT, NULL, 0) = %s\n",
 	       fd, reqs->req1.nlh.nlmsg_len, NLM_F_DUMP,
 	       reqs->req2.nlh.nlmsg_len, NLM_F_DUMP,
-	       (unsigned) sizeof(*reqs), (unsigned) sizeof(*reqs));
+	       (unsigned) sizeof(*reqs), sprintrc(rc));
 
 	/* abbreviated output */
 # define DEFAULT_STRLEN 32
@@ -210,9 +186,8 @@
 		msgs[i].nlmsg_pid = 0;
 	}
 
-	if (sendto(fd, msgs, msg_len, MSG_DONTWAIT, NULL, 0) != (int) msg_len)
-		perror_msg_and_skip("sendto");
-
+	rc = sendto(fd, msgs, msg_len, MSG_DONTWAIT, NULL, 0);
+	errstr = sprintrc(rc);
 	printf("sendto(%d, [", fd);
 	for (i = 0; i < DEFAULT_STRLEN; ++i) {
 		if (i)
@@ -221,7 +196,7 @@
 		       ", seq=%u, pid=0}}",
 		       msgs[i].nlmsg_len, NLM_F_DUMP, msgs[i].nlmsg_seq);
 	}
-	printf(", ...], %u, MSG_DONTWAIT, NULL, 0) = %u\n", msg_len, msg_len);
+	printf(", ...], %u, MSG_DONTWAIT, NULL, 0) = %s\n", msg_len, errstr);
 }
 
 int main(void)
diff --git a/tests/newfstatat.c b/tests/newfstatat.c
index 6fb34db..b501d88 100644
--- a/tests/newfstatat.c
+++ b/tests/newfstatat.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_newfstatat
 
diff --git a/tests/nsyscalls.c b/tests/nsyscalls.c
index c9c92c4..8e09acb 100644
--- a/tests/nsyscalls.c
+++ b/tests/nsyscalls.c
@@ -48,7 +48,7 @@
 #include "syscallent.h"
 };
 
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __X32_SYSCALL_BIT && defined __NR_read \
  && (__X32_SYSCALL_BIT & __NR_read) != 0
@@ -57,10 +57,8 @@
 # define SYSCALL_BIT 0
 #endif
 
-static const unsigned long nr = ARRAY_SIZE(syscallent) | SYSCALL_BIT;
-
-int
-main(void)
+static void
+test_syscall(const unsigned long nr)
 {
 	static const kernel_ulong_t a[] = {
 		(kernel_ulong_t) 0xface0fedbadc0ded,
@@ -71,14 +69,15 @@
 		(kernel_ulong_t) 0xface5fedbadc5ded
 	};
 
-	long rc = syscall(nr, a[0], a[1], a[2], a[3], a[4], a[5]);
+	long rc = syscall(nr | SYSCALL_BIT,
+			  a[0], a[1], a[2], a[3], a[4], a[5]);
 #ifdef LINUX_MIPSO32
 	printf("syscall(%#lx, %#lx, %#lx, %#lx, %#lx, %#lx, %#lx)"
-	       " = %ld ENOSYS (%m)\n", nr,
+	       " = %ld ENOSYS (%m)\n", nr | SYSCALL_BIT,
 	       a[0], a[1], a[2], a[3], a[4], a[5], rc);
 #else
 	printf("syscall_%lu(%#llx, %#llx, %#llx, %#llx, %#llx, %#llx)"
-	       " = %ld (errno %d)\n", nr & (~SYSCALL_BIT),
+	       " = %ld (errno %d)\n", nr,
 	       (unsigned long long) a[0],
 	       (unsigned long long) a[1],
 	       (unsigned long long) a[2],
@@ -87,6 +86,20 @@
 	       (unsigned long long) a[5],
 	       rc, errno);
 #endif
+}
+
+int
+main(void)
+{
+	test_syscall(ARRAY_SIZE(syscallent));
+
+#ifdef SYS_socket_subcall
+	test_syscall(SYS_socket_subcall + 1);
+#endif
+
+#ifdef SYS_ipc_subcall
+	test_syscall(SYS_ipc_subcall + 1);
+#endif
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/nsyscalls.test b/tests/nsyscalls.test
index 3760831..61f72d5 100755
--- a/tests/nsyscalls.test
+++ b/tests/nsyscalls.test
@@ -4,9 +4,10 @@
 
 . "${srcdir=.}/init.sh"
 
-case "$STRACE_ARCH" in
-	mips) syscall=syscall ;;
-	*) syscall=none ;;
-esac
+if [ "$MIPS_ABI" = "o32" ]; then
+	syscall=syscall
+else
+	syscall=none
+fi
 
 run_strace_match_diff -e trace=$syscall
diff --git a/tests/old_mmap.c b/tests/old_mmap.c
index 97051db..de1bafb 100644
--- a/tests/old_mmap.c
+++ b/tests/old_mmap.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 /*
  * On s390x, this is the mmap syscall used by glibc, so,
diff --git a/tests/oldselect.c b/tests/oldselect.c
index b8f265a..7413fc3 100644
--- a/tests/oldselect.c
+++ b/tests/oldselect.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_select && defined __NR__newselect \
  && __NR_select != __NR__newselect \
diff --git a/tests/open.c b/tests/open.c
index 726b1ec..01e89b0 100644
--- a/tests/open.c
+++ b/tests/open.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_open
 
@@ -38,27 +38,35 @@
 main(void)
 {
 	static const char sample[] = "open.sample";
-	int fd = syscall(__NR_open, sample, O_RDONLY|O_CREAT, 0400);
 
-	if (fd < 0) {
-		printf("open(\"%s\", O_RDONLY|O_CREAT, 0400)"
-		       " = %d %s (%m)\n", sample, fd, errno2name());
-	} else {
-		printf("open(\"%s\", O_RDONLY|O_CREAT, 0400) = %d\n",
-		       sample, fd);
+	long fd = syscall(__NR_open, sample, O_RDONLY|O_CREAT, 0400);
+	printf("open(\"%s\", O_RDONLY|O_CREAT, 0400) = %s\n",
+	       sample, sprintrc(fd));
+
+	if (fd != -1) {
 		close(fd);
 		if (unlink(sample))
 			perror_msg_and_fail("unlink");
 
 		fd = syscall(__NR_open, sample, O_RDONLY);
-		printf("open(\"%s\", O_RDONLY) = %d %s (%m)\n",
-		       sample, fd, errno2name());
+		printf("open(\"%s\", O_RDONLY) = %s\n", sample, sprintrc(fd));
 
 		fd = syscall(__NR_open, sample, O_WRONLY|O_NONBLOCK|0x80000000);
-		printf("open(\"%s\", O_WRONLY|O_NONBLOCK|0x80000000)"
-		       " = %d %s (%m)\n", sample, fd, errno2name());
+		printf("open(\"%s\", O_WRONLY|O_NONBLOCK|0x80000000) = %s\n",
+		       sample, sprintrc(fd));
 	}
 
+#ifdef O_TMPFILE
+# if O_TMPFILE == (O_TMPFILE & ~O_DIRECTORY)
+#  define STR_O_TMPFILE "O_TMPFILE"
+# else
+#  define STR_O_TMPFILE "O_DIRECTORY|O_TMPFILE"
+# endif
+	fd = syscall(__NR_open, sample, O_WRONLY|O_TMPFILE, 0600);
+	printf("open(\"%s\", O_WRONLY|%s, 0600) = %s\n",
+	       sample, STR_O_TMPFILE, sprintrc(fd));
+#endif /* O_TMPFILE */
+
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/openat.c b/tests/openat.c
index a3de1dd..1d6765c 100644
--- a/tests/openat.c
+++ b/tests/openat.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_openat
 
@@ -38,20 +38,19 @@
 main(void)
 {
 	static const char sample[] = "openat.sample";
-	int fd = syscall(__NR_openat, -100, sample, O_RDONLY|O_CREAT, 0400);
-	if (fd == -1) {
-		printf("openat(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400)"
-		       " = -1 %s (%m)\n", sample, errno2name());
-	} else {
-		printf("openat(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400)"
-		       " = %d\n", sample, fd);
+
+	long fd = syscall(__NR_openat, -100, sample, O_RDONLY|O_CREAT, 0400);
+	printf("openat(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400) = %s\n",
+	       sample, sprintrc(fd));
+
+	if (fd != -1) {
 		close(fd);
 		if (unlink(sample) == -1)
 			perror_msg_and_fail("unlink");
 
 		fd = syscall(__NR_openat, -100, sample, O_RDONLY);
-		printf("openat(AT_FDCWD, \"%s\", O_RDONLY) = %d %s (%m)\n",
-		       sample, fd, errno2name());
+		printf("openat(AT_FDCWD, \"%s\", O_RDONLY) = %s\n",
+		       sample, sprintrc(fd));
 	}
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/pause.c b/tests/pause.c
index 6dadd15..8687362 100644
--- a/tests/pause.c
+++ b/tests/pause.c
@@ -29,10 +29,11 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_pause
 
+# include <errno.h>
 # include <signal.h>
 # include <stdio.h>
 # include <sys/time.h>
@@ -60,8 +61,12 @@
 	if (setitimer(ITIMER_REAL, &itv, NULL))
 		perror_msg_and_fail("setitimer");
 
-	pause();
-	printf("pause() = ? ERESTARTNOHAND (To be restarted if no handler)\n");
+	syscall(__NR_pause);
+	if (errno == ENOSYS)
+		printf("pause() = -1 ENOSYS (%m)\n");
+	else
+		printf("pause() = ? ERESTARTNOHAND"
+		       " (To be restarted if no handler)\n");
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/pc.test b/tests/pc.test
index cc55878..beadb7d 100755
--- a/tests/pc.test
+++ b/tests/pc.test
@@ -37,13 +37,13 @@
 $STRACE $args 2> "$LOG" ||
 	dump_log_and_fail_with "$STRACE $args failed"
 
-len="$(sed -n 's/^\[[[:xdigit:]]\+\] write(-1, NULL, \([[:digit:]]\{1,2\}\))[[:space:]]\+= -1 .*/\1/p' "$LOG")" &&
+len="$(sed -r -n 's/^\[[[:xdigit:]]+\] write\(-1, NULL, ([[:digit:]]{1,2})\)[[:space:]]+= -1 .*/\1/p' "$LOG")" &&
 [ -n "$len" ] &&
-pid="$(sed -n 's/^\[[[:xdigit:]]\{'"$len"'\}\] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_\(KILLED\|DUMPED\), si_pid=\([[:digit:]]\+\), .*/\2/p' "$LOG")" &&
+pid="$(sed -r -n 's/^\[[[:xdigit:]]{'"$len"'}\] --- SIGCHLD \{si_signo=SIGCHLD, si_code=CLD_(KILLED|DUMPED), si_pid=([[:digit:]]+), .*/\2/p' "$LOG")" &&
 [ -n "$pid" ] &&
-ip="$(sed -n 's/^\[pid \+'"$pid"'\] \[\([[:xdigit:]]\{'"$len"'\}\)] --- SIGSEGV {.*} ---$/\1/p' "$LOG")" &&
+ip="$(sed -r -n 's/^\[pid +'"$pid"'\] \[([[:xdigit:]]{'"$len"'})] --- SIGSEGV \{.*\} ---$/\1/p' "$LOG")" &&
 [ -n "$ip" ] &&
-addr="$(echo "$ip" |sed 's/^0\+//')" &&
+addr="$(echo "$ip" |sed -r 's/^0+//')" &&
 [ -n "$addr" ] ||
 	dump_log_and_fail_with
 
diff --git a/tests/perf_event_open.c b/tests/perf_event_open.c
new file mode 100644
index 0000000..72f5d3c
--- /dev/null
+++ b/tests/perf_event_open.c
@@ -0,0 +1,113 @@
+/*
+ * Check decoding of perf_event_open syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <asm/unistd.h>
+
+#if defined(__NR_perf_event_open) && defined(HAVE_LINUX_PERF_EVENT_H)
+
+# include <limits.h>
+# include <stdio.h>
+# include <unistd.h>
+
+# include <linux/perf_event.h>
+
+# include "xlat.h"
+# include "xlat/perf_event_open_flags.h"
+
+#if ULONG_MAX > UINT_MAX
+#define LONG_STR_PREFIX "ffffffff"
+#else
+#define LONG_STR_PREFIX ""
+#endif
+
+static const char *printaddr(void *ptr)
+{
+	static char buf[sizeof("0x") + sizeof(void *) * 2];
+
+	if (ptr == NULL)
+		return "NULL";
+
+	snprintf(buf, sizeof(buf), "%#lx", (unsigned long)ptr);
+
+	return buf;
+}
+
+int
+main(void)
+{
+	struct perf_event_attr *attr = tail_alloc(sizeof(*attr));
+
+	attr->type = PERF_TYPE_HARDWARE;
+	attr->size = sizeof(*attr);
+
+	struct {
+		struct perf_event_attr *attr;
+		pid_t pid;
+		int cpu;
+		int group_fd;
+		unsigned long flags;
+		const char *flags_str;
+	} args[] = {
+		{ NULL,     0xfacef00d, 0xbadabba7, -1,
+			(unsigned long) 0xFFFFFFFFFFFFFFFFLLU,
+			"PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|"
+			"PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC|"
+			"0x" LONG_STR_PREFIX "fffffff0"
+			},
+		{ attr + 1, 0,          0,          0,
+			0, "0" },
+		{ attr,     -1,         -1,         1,
+			PERF_FLAG_FD_CLOEXEC, "PERF_FLAG_FD_CLOEXEC" },
+		{ attr - 1, -100,       100,        0xface1e55,
+			PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT |
+			PERF_FLAG_PID_CGROUP | PERF_FLAG_FD_CLOEXEC,
+			"PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|"
+			"PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC" },
+	};
+	size_t i;
+	int rc;
+
+	for (i = 0; i < ARRAY_SIZE(args); i++) {
+		rc = syscall(__NR_perf_event_open, args[i].attr, args[i].pid,
+			args[i].cpu, args[i].group_fd, args[i].flags);
+		printf("perf_event_open(%s, %d, %d, %d, %s) = %s\n",
+			printaddr(args[i].attr), args[i].pid, args[i].cpu,
+			args[i].group_fd, args[i].flags_str, sprintrc(rc));
+	}
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_perf_event_open && HAVE_LINUX_PERF_EVENT_H");
+
+#endif
diff --git a/tests/perf_event_open.test b/tests/perf_event_open.test
new file mode 100755
index 0000000..0e46556
--- /dev/null
+++ b/tests/perf_event_open.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of perf_event_open syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a34
diff --git a/tests/poll.c b/tests/poll.c
index 551e9b4..c47c97e 100644
--- a/tests/poll.c
+++ b/tests/poll.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_poll
 
diff --git a/tests/prctl-seccomp-filter-v.c b/tests/prctl-seccomp-filter-v.c
index a03f202..69316fb 100644
--- a/tests/prctl-seccomp-filter-v.c
+++ b/tests/prctl-seccomp-filter-v.c
@@ -32,7 +32,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef HAVE_PRCTL
 # include <sys/prctl.h>
diff --git a/tests/prctl-seccomp-strict.c b/tests/prctl-seccomp-strict.c
index 57387c9..a78f817 100644
--- a/tests/prctl-seccomp-strict.c
+++ b/tests/prctl-seccomp-strict.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #ifdef HAVE_PRCTL
 # include <sys/prctl.h>
 #endif
diff --git a/tests/preadv2-pwritev2.c b/tests/preadv2-pwritev2.c
index 1a607c9..032ac03 100644
--- a/tests/preadv2-pwritev2.c
+++ b/tests/preadv2-pwritev2.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_preadv2 && defined __NR_pwritev2
 
diff --git a/tests/prlimit64.c b/tests/prlimit64.c
index 6721d49..e62ea26 100644
--- a/tests/prlimit64.c
+++ b/tests/prlimit64.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_prlimit64
 
diff --git a/tests/pselect6.c b/tests/pselect6.c
index 49258a9..7dbc06a 100644
--- a/tests/pselect6.c
+++ b/tests/pselect6.c
@@ -35,7 +35,7 @@
 #include <signal.h>
 #include <unistd.h>
 #include <sys/select.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <sys/time.h>
 
 #ifdef __NR_pselect6
diff --git a/tests/ptrace.c b/tests/ptrace.c
index 7971b89..1dcfec3 100644
--- a/tests/ptrace.c
+++ b/tests/ptrace.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rt_sigprocmask
 
@@ -41,35 +41,37 @@
 # include "ptrace.h"
 # include <linux/audit.h>
 
+static const char *errstr;
+
 static long
 do_ptrace(unsigned long request, unsigned long pid,
 	  unsigned long addr, unsigned long data)
 {
-	return syscall(__NR_ptrace, request, pid, addr, data);
+	long rc = syscall(__NR_ptrace, request, pid, addr, data);
+	errstr = sprintrc(rc);
+	return rc;
 }
 
 static void
 test_peeksiginfo(unsigned long pid, const unsigned long bad_request)
 {
-	long rc = do_ptrace(PTRACE_PEEKSIGINFO, pid, 0, bad_request);
-	printf("ptrace(PTRACE_PEEKSIGINFO, %u, NULL, %#lx)"
-	       " = %ld %s (%m)\n", (unsigned) pid, bad_request, rc, errno2name());
+	do_ptrace(PTRACE_PEEKSIGINFO, pid, 0, bad_request);
+	printf("ptrace(PTRACE_PEEKSIGINFO, %u, NULL, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 
 	struct {
 		unsigned long long off;
 		unsigned int flags, nr;
 	} *const psi = tail_alloc(sizeof(*psi));
 
-	psi->off = 0xdeadbeeffacefeed;
+	psi->off = 0xdeadbeeffacefeedULL;
 	psi->flags = 1;
 	psi->nr = 42;
 
-	rc = do_ptrace(PTRACE_PEEKSIGINFO,
-		       pid, (unsigned long) psi, bad_request);
+	do_ptrace(PTRACE_PEEKSIGINFO, pid, (unsigned long) psi, bad_request);
 	printf("ptrace(PTRACE_PEEKSIGINFO, %u, {off=%llu"
-	       ", flags=PTRACE_PEEKSIGINFO_SHARED, nr=%u}, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, psi->off, psi->nr, bad_request, rc, errno2name());
+	       ", flags=PTRACE_PEEKSIGINFO_SHARED, nr=%u}, %#lx) = %s\n",
+	       (unsigned) pid, psi->off, psi->nr, bad_request, errstr);
 
 	pid = fork();
 	if ((pid_t) pid < 0)
@@ -132,28 +134,28 @@
 					   status);
 		}
 
-		rc = do_ptrace(PTRACE_PEEKSIGINFO, pid,
-			       (unsigned long) psi, (unsigned long) sigs);
+		long rc = do_ptrace(PTRACE_PEEKSIGINFO, pid,
+				    (unsigned long) psi, (unsigned long) sigs);
 		if (rc < 0) {
-			printf("ptrace(PTRACE_PEEKSIGINFO, %u, {off=%llu"
-			       ", flags=0, nr=%u}, %p) = %ld %s (%m)\n",
+			printf("ptrace(PTRACE_PEEKSIGINFO, %u"
+			       ", {off=%llu, flags=0, nr=%u}, %p) = %s\n",
 			       (unsigned) pid, psi->off, psi->nr, sigs,
-			       rc, errno2name());
+			       errstr);
 		} else {
-			printf("ptrace(PTRACE_PEEKSIGINFO, %u, {off=%llu"
-			       ", flags=0, nr=%u}"
+			printf("ptrace(PTRACE_PEEKSIGINFO, %u"
+			       ", {off=%llu, flags=0, nr=%u}"
 			       ", [{si_signo=SIGUSR1, si_code=SI_TKILL"
 			       ", si_pid=%u, si_uid=%u}"
 			       ", {si_signo=SIGUSR2, si_code=SI_TKILL"
 			       ", si_pid=%u, si_uid=%u}"
 			       ", {si_signo=SIGALRM, si_code=SI_TKILL"
 			       ", si_pid=%u, si_uid=%u}"
-			       "]) = %ld\n",
+			       "]) = %s\n",
 			       (unsigned) pid, psi->off, psi->nr,
 			       (unsigned) pid, (unsigned) uid,
 			       (unsigned) pid, (unsigned) uid,
 			       (unsigned) pid, (unsigned) uid,
-			       rc);
+			       errstr);
 		}
 
 		if (do_ptrace(PTRACE_CONT, pid, 0, 0)) {
@@ -170,11 +172,11 @@
 main(void)
 {
 	const unsigned long bad_request =
-		(unsigned long) 0xdeadbeeffffffeed;
+		(unsigned long) 0xdeadbeeffffffeedULL;
 	const unsigned long bad_data =
-		(unsigned long) 0xdeadcafefffff00d;
+		(unsigned long) 0xdeadcafefffff00dULL;
 	const unsigned long pid =
-		(unsigned long) 0xdefaced00000000 | (unsigned) getpid();
+		(unsigned long) 0xdefaced00000000ULL | (unsigned) getpid();
 
 	unsigned int sigset_size;
 
@@ -189,89 +191,73 @@
 	void *const k_set = tail_alloc(sigset_size);
 	siginfo_t *const sip = tail_alloc(sizeof(*sip));
 
-	long rc = do_ptrace(bad_request, pid, 0, 0);
-	printf("ptrace(%#lx /* PTRACE_??? */, %u, NULL, NULL) = %ld %s (%m)\n",
-	       bad_request, (unsigned) pid, rc, errno2name());
+	do_ptrace(bad_request, pid, 0, 0);
+	printf("ptrace(%#lx /* PTRACE_??? */, %u, NULL, NULL) = %s\n",
+	       bad_request, (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_PEEKDATA, pid, bad_request, bad_data);
+	do_ptrace(PTRACE_PEEKDATA, pid, bad_request, bad_data);
 # ifdef IA64
-	printf("ptrace(PTRACE_PEEKDATA, %u, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	printf("ptrace(PTRACE_PEEKDATA, %u, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 # else
-	printf("ptrace(PTRACE_PEEKDATA, %u, %#lx, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, bad_data, rc, errno2name());
+	printf("ptrace(PTRACE_PEEKDATA, %u, %#lx, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, bad_data, errstr);
 #endif
 
-	rc = do_ptrace(PTRACE_PEEKTEXT, pid, bad_request, bad_data);
+	do_ptrace(PTRACE_PEEKTEXT, pid, bad_request, bad_data);
 # ifdef IA64
-	printf("ptrace(PTRACE_PEEKTEXT, %u, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	printf("ptrace(PTRACE_PEEKTEXT, %u, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 # else
-	printf("ptrace(PTRACE_PEEKTEXT, %u, %#lx, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, bad_data, rc, errno2name());
+	printf("ptrace(PTRACE_PEEKTEXT, %u, %#lx, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, bad_data, errstr);
 #endif
 
-	rc = do_ptrace(PTRACE_PEEKUSER, pid, bad_request, bad_data);
+	do_ptrace(PTRACE_PEEKUSER, pid, bad_request, bad_data);
 # ifdef IA64
-	printf("ptrace(PTRACE_PEEKUSER, %u, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	printf("ptrace(PTRACE_PEEKUSER, %u, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 # else
-	printf("ptrace(PTRACE_PEEKUSER, %u, %#lx, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, bad_data, rc, errno2name());
+	printf("ptrace(PTRACE_PEEKUSER, %u, %#lx, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, bad_data, errstr);
 #endif
 
-	rc = do_ptrace(PTRACE_POKEUSER, pid, bad_request, bad_data);
-	printf("ptrace(PTRACE_POKEUSER, %u, %#lx, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, bad_data, rc, errno2name());
+	do_ptrace(PTRACE_POKEUSER, pid, bad_request, bad_data);
+	printf("ptrace(PTRACE_POKEUSER, %u, %#lx, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, bad_data, errstr);
 
-	rc = do_ptrace(PTRACE_ATTACH, pid, 0, 0);
-	printf("ptrace(PTRACE_ATTACH, %u) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_ATTACH, pid, 0, 0);
+	printf("ptrace(PTRACE_ATTACH, %u) = %s\n", (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_INTERRUPT, pid, 0, 0);
-	printf("ptrace(PTRACE_INTERRUPT, %u) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_INTERRUPT, pid, 0, 0);
+	printf("ptrace(PTRACE_INTERRUPT, %u) = %s\n", (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_KILL, pid, 0, 0);
-	printf("ptrace(PTRACE_KILL, %u) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_KILL, pid, 0, 0);
+	printf("ptrace(PTRACE_KILL, %u) = %s\n", (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_LISTEN, pid, 0, 0);
-	printf("ptrace(PTRACE_LISTEN, %u) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_LISTEN, pid, 0, 0);
+	printf("ptrace(PTRACE_LISTEN, %u) = %s\n", (unsigned) pid, errstr);
 
 	sigset_t libc_set;
 	sigemptyset(&libc_set);
 	sigaddset(&libc_set, SIGUSR1);
 	memcpy(k_set, &libc_set, sigset_size);
 
-	rc = do_ptrace(PTRACE_SETSIGMASK,
-		       pid, sigset_size, (unsigned long) k_set);
-	printf("ptrace(PTRACE_SETSIGMASK, %u, %u, [USR1])"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, sigset_size, rc, errno2name());
+	do_ptrace(PTRACE_SETSIGMASK, pid, sigset_size, (unsigned long) k_set);
+	printf("ptrace(PTRACE_SETSIGMASK, %u, %u, [USR1]) = %s\n",
+	       (unsigned) pid, sigset_size, errstr);
 
-	rc = do_ptrace(PTRACE_GETSIGMASK,
-		       pid, sigset_size, (unsigned long) k_set);
-	printf("ptrace(PTRACE_GETSIGMASK, %u, %u, %p)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, sigset_size, k_set, rc, errno2name());
+	do_ptrace(PTRACE_GETSIGMASK, pid, sigset_size, (unsigned long) k_set);
+	printf("ptrace(PTRACE_GETSIGMASK, %u, %u, %p) = %s\n",
+	       (unsigned) pid, sigset_size, k_set, errstr);
 
-	rc = do_ptrace(PTRACE_SECCOMP_GET_FILTER, pid, 42, 0);
-	printf("ptrace(PTRACE_SECCOMP_GET_FILTER, %u, 42, NULL)"
-	       " = %ld %s (%m)\n", (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_SECCOMP_GET_FILTER, pid, 42, 0);
+	printf("ptrace(PTRACE_SECCOMP_GET_FILTER, %u, 42, NULL) = %s\n",
+	       (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_GETEVENTMSG, pid, bad_request, bad_data);
-	printf("ptrace(PTRACE_GETEVENTMSG, %u, %#lx, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, bad_data, rc, errno2name());
+	do_ptrace(PTRACE_GETEVENTMSG, pid, bad_request, bad_data);
+	printf("ptrace(PTRACE_GETEVENTMSG, %u, %#lx, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, bad_data, errstr);
 
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGIO;
@@ -279,12 +265,10 @@
 	sip->si_errno = ENOENT;
 	sip->si_band = -2;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGIO"
-	       ", si_code=POLL_IN, si_errno=ENOENT, si_band=-2})"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	       ", si_code=POLL_IN, si_errno=ENOENT, si_band=-2}) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGTRAP;
@@ -294,52 +278,46 @@
 	sip->si_uid = 3;
 	sip->si_ptr = (void *) bad_request;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGTRAP"
 	       ", si_code=TRAP_BRKPT, si_errno=ENOENT, si_pid=2, si_uid=3"
-	       ", si_value={int=%d, ptr=%p}}) = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, sip->si_int, sip->si_ptr, rc, errno2name());
+	       ", si_value={int=%d, ptr=%p}}) = %s\n",
+	       (unsigned) pid, bad_request, sip->si_int, sip->si_ptr,
+	       errstr);
 
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGILL;
 	sip->si_code = 1;
 	sip->si_errno = ENOENT;
-	sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeef;
+	sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGILL"
-	       ", si_code=ILL_ILLOPC, si_errno=ENOENT, si_addr=%p})"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, sip->si_addr, rc, errno2name());
+	       ", si_code=ILL_ILLOPC, si_errno=ENOENT, si_addr=%p}) = %s\n",
+	       (unsigned) pid, bad_request, sip->si_addr, errstr);
 
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGFPE;
 	sip->si_code = 1;
 	sip->si_errno = ENOENT;
-	sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeef;
+	sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGFPE"
-	       ", si_code=FPE_INTDIV, si_errno=ENOENT, si_addr=%p})"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, sip->si_addr, rc, errno2name());
+	       ", si_code=FPE_INTDIV, si_errno=ENOENT, si_addr=%p}) = %s\n",
+	       (unsigned) pid, bad_request, sip->si_addr, errstr);
 
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGBUS;
 	sip->si_code = 1;
 	sip->si_errno = -2;
-	sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeef;
+	sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGBUS"
-	       ", si_code=BUS_ADRALN, si_errno=%d, si_addr=%p})"
-	       " = %ld %s (%m)\n",
+	       ", si_code=BUS_ADRALN, si_errno=%d, si_addr=%p}) = %s\n",
 	       (unsigned) pid, bad_request, sip->si_errno, sip->si_addr,
-	       rc, errno2name());
+	       errstr);
 
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGPROF;
@@ -349,31 +327,28 @@
 	sip->si_uid = 3;
 	sip->si_ptr = 0;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGPROF"
-	       ", si_code=%#x, si_errno=%d, si_pid=0, si_uid=3})"
-	       " = %ld %s (%m)\n",
+	       ", si_code=%#x, si_errno=%d, si_pid=0, si_uid=3}) = %s\n",
 	       (unsigned) pid, bad_request, sip->si_code, sip->si_errno,
-	       rc, errno2name());
+	       errstr);
 
 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
 	memset(sip, -1, sizeof(*sip));
 	sip->si_signo = SIGSYS;
 	sip->si_code = 1;
 	sip->si_errno = ENOENT;
-	sip->si_call_addr = (void *) (unsigned long) 0xfacefeeddeadbeef;
+	sip->si_call_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
 	sip->si_syscall = -1U;
 	sip->si_arch = AUDIT_ARCH_X86_64;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGSYS"
 	       ", si_code=SYS_SECCOMP, si_errno=ENOENT, si_call_addr=%p"
 	       ", si_syscall=__NR_syscall_%u, si_arch=AUDIT_ARCH_X86_64})"
-	       " = %ld %s (%m)\n",
+	       " = %s\n",
 	       (unsigned) pid, bad_request, sip->si_call_addr, sip->si_syscall,
-	       rc, errno2name());
+	       errstr);
 #endif
 
 #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
@@ -383,87 +358,77 @@
 	sip->si_errno = ENOENT;
 	sip->si_timerid = 0xdeadbeef;
 	sip->si_overrun = -1;
-	sip->si_ptr = (void *) (unsigned long) 0xfacefeeddeadbeef;
+	sip->si_ptr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
 
-	rc = do_ptrace(PTRACE_SETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_SETSIGINFO, %u, %#lx, {si_signo=SIGHUP"
 	       ", si_code=SI_TIMER, si_errno=ENOENT, si_timerid=%#x"
-	       ", si_overrun=%d, si_value={int=%d, ptr=%p}}) = %ld %s (%m)\n",
+	       ", si_overrun=%d, si_value={int=%d, ptr=%p}}) = %s\n",
 	       (unsigned) pid, bad_request, sip->si_timerid, sip->si_overrun,
-	       sip->si_int, sip->si_ptr, rc, errno2name());
+	       sip->si_int, sip->si_ptr, errstr);
 #endif
 
-	rc = do_ptrace(PTRACE_GETSIGINFO,
-		       pid, bad_request, (unsigned long) sip);
+	do_ptrace(PTRACE_GETSIGINFO, pid, bad_request, (unsigned long) sip);
 	printf("ptrace(PTRACE_GETSIGINFO, %u, %#lx, %p)"
-	       " = %ld %s (%m)\n", (unsigned) pid, bad_request, sip, rc, errno2name());
+	       " = %s\n", (unsigned) pid, bad_request, sip, errstr);
 
-	rc = do_ptrace(PTRACE_CONT, pid, 0, SIGUSR1);
-	printf("ptrace(PTRACE_CONT, %u, NULL, SIGUSR1) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_CONT, pid, 0, SIGUSR1);
+	printf("ptrace(PTRACE_CONT, %u, NULL, SIGUSR1) = %s\n",
+	       (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_DETACH, pid, 0, SIGUSR2);
-	printf("ptrace(PTRACE_DETACH, %u, NULL, SIGUSR2) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_DETACH, pid, 0, SIGUSR2);
+	printf("ptrace(PTRACE_DETACH, %u, NULL, SIGUSR2) = %s\n",
+	       (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_SYSCALL, pid, 0, SIGUSR1);
-	printf("ptrace(PTRACE_SYSCALL, %u, NULL, SIGUSR1) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_SYSCALL, pid, 0, SIGUSR1);
+	printf("ptrace(PTRACE_SYSCALL, %u, NULL, SIGUSR1) = %s\n",
+	       (unsigned) pid, errstr);
 
 #ifdef PTRACE_SINGLESTEP
-	rc = do_ptrace(PTRACE_SINGLESTEP, pid, 0, SIGUSR2);
-	printf("ptrace(PTRACE_SINGLESTEP, %u, NULL, SIGUSR2) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_SINGLESTEP, pid, 0, SIGUSR2);
+	printf("ptrace(PTRACE_SINGLESTEP, %u, NULL, SIGUSR2) = %s\n",
+	       (unsigned) pid, errstr);
 #endif
 
 #ifdef PTRACE_SINGLEBLOCK
-	rc = do_ptrace(PTRACE_SINGLEBLOCK, pid, 0, SIGUSR1);
-	printf("ptrace(PTRACE_SINGLEBLOCK, %u, NULL, SIGUSR1) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_SINGLEBLOCK, pid, 0, SIGUSR1);
+	printf("ptrace(PTRACE_SINGLEBLOCK, %u, NULL, SIGUSR1) = %s\n",
+	       (unsigned) pid, errstr);
 #endif
 
 #ifdef PTRACE_SYSEMU
-	rc = do_ptrace(PTRACE_SYSEMU, pid, 0, SIGUSR2);
-	printf("ptrace(PTRACE_SYSEMU, %u, NULL, SIGUSR2) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_SYSEMU, pid, 0, SIGUSR2);
+	printf("ptrace(PTRACE_SYSEMU, %u, NULL, SIGUSR2) = %s\n",
+	       (unsigned) pid, errstr);
 #endif
 #ifdef PTRACE_SYSEMU_SINGLESTEP
-	rc = do_ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, SIGUSR1);
-	printf("ptrace(PTRACE_SYSEMU_SINGLESTEP, %u, NULL, SIGUSR1)"
-	       " = %ld %s (%m)\n", (unsigned) pid, rc, errno2name());
+	do_ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, SIGUSR1);
+	printf("ptrace(PTRACE_SYSEMU_SINGLESTEP, %u, NULL, SIGUSR1) = %s\n",
+	       (unsigned) pid, errstr);
 #endif
 
-	rc = do_ptrace(PTRACE_SETOPTIONS,
-		       pid, 0, PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE);
+	do_ptrace(PTRACE_SETOPTIONS,
+		  pid, 0, PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE);
 	printf("ptrace(PTRACE_SETOPTIONS, %u, NULL"
-	       ", PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE) = %ld %s (%m)\n",
-	       (unsigned) pid, rc, errno2name());
+	       ", PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE) = %s\n",
+	       (unsigned) pid, errstr);
 
-	rc = do_ptrace(PTRACE_SEIZE,
-		       pid, bad_request, PTRACE_O_TRACESYSGOOD);
-	printf("ptrace(PTRACE_SEIZE, %u, %#lx"
-	       ", PTRACE_O_TRACESYSGOOD) = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	do_ptrace(PTRACE_SEIZE, pid, bad_request, PTRACE_O_TRACESYSGOOD);
+	printf("ptrace(PTRACE_SEIZE, %u, %#lx, PTRACE_O_TRACESYSGOOD) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 
-	rc = do_ptrace(PTRACE_SETREGSET, pid, 1, bad_request);
-	printf("ptrace(PTRACE_SETREGSET, %u, NT_PRSTATUS, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	do_ptrace(PTRACE_SETREGSET, pid, 1, bad_request);
+	printf("ptrace(PTRACE_SETREGSET, %u, NT_PRSTATUS, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 
-	rc = do_ptrace(PTRACE_GETREGSET, pid, 3, bad_request);
-	printf("ptrace(PTRACE_GETREGSET, %u, NT_PRPSINFO, %#lx)"
-	       " = %ld %s (%m)\n",
-	       (unsigned) pid, bad_request, rc, errno2name());
+	do_ptrace(PTRACE_GETREGSET, pid, 3, bad_request);
+	printf("ptrace(PTRACE_GETREGSET, %u, NT_PRPSINFO, %#lx) = %s\n",
+	       (unsigned) pid, bad_request, errstr);
 
 	test_peeksiginfo(pid, bad_request);
 
-	rc = do_ptrace(PTRACE_TRACEME, 0, 0, 0);
-	if (rc)
-		printf("ptrace(PTRACE_TRACEME) = %ld %s (%m)\n",
-		       rc, errno2name());
-	else
-		printf("ptrace(PTRACE_TRACEME) = 0\n");
+	do_ptrace(PTRACE_TRACEME, 0, 0, 0);
+	printf("ptrace(PTRACE_TRACEME) = %s\n", errstr);
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/qual_syscall.test b/tests/qual_syscall.test
index 1aff1cc..f7eb06d 100755
--- a/tests/qual_syscall.test
+++ b/tests/qual_syscall.test
@@ -1,25 +1,59 @@
 #!/bin/sh
 
-# Ensure that strace -e trace=set works.
+# Check how strace -e abbrev=set, -e raw=set, -e trace=set,
+# and -e verbose=set work.
 
 . "${srcdir=.}/init.sh"
 
-check_prog ls
-run_strace -e execve ls
+run_prog ./umovestr
+pattern_abbrev_verbose='execve("\./umovestr", \["\./umovestr"\], \[/\* [[:digit:]]* vars \*/\]) = 0'
+pattern_nonabbrev_verbose='execve("\./umovestr", \["\./umovestr"\], \[".*\"\(\.\.\.\)\?\]) = 0'
+pattern_nonverbose='execve("\./umovestr", 0x[[:xdigit:]]*, 0x[[:xdigit:]]*) = 0'
+pattern_raw='execve(0x[[:xdigit:]]*, 0x[[:xdigit:]]*, 0x[[:xdigit:]]*) = 0'
 
-grep '^execve(' "$LOG" > /dev/null ||
-	dump_log_and_fail_with "$STRACE $args output mismatch"
+check_output_mismatch()
+{
+	local pattern
+	pattern="$1"; shift
+	run_strace "$@" ./umovestr
+	LC_ALL=C grep -x "$pattern" "$LOG" > /dev/null || {
+		printf '%s\n%s\n' \
+			'Failed patterns of expected output:' "$pattern"
+		dump_log_and_fail_with "$STRACE $args output mismatch"
+	}
+}
 
-grep -v '^execve(' "$LOG" |
+check_output_mismatch "$pattern_abbrev_verbose" -e execve
+LC_ALL=C grep -v -x "$pattern_abbrev_verbose" "$LOG" |
 LC_ALL=C grep '^[[:alnum:]_]*(' > /dev/null &&
 	dump_log_and_fail_with "$STRACE $args unexpected output"
 
-run_strace -e trace=process ls
-
-grep '^execve(' "$LOG" > /dev/null ||
-	dump_log_and_fail_with "$STRACE $args output mismatch"
-
-grep '^open' "$LOG" > /dev/null &&
+check_output_mismatch "$pattern_abbrev_verbose" -e trace=process
+LC_ALL=C grep '^chdir' "$LOG" > /dev/null &&
 	dump_log_and_fail_with "$STRACE $args unexpected output"
 
+run_strace -e 42 ./umovestr
+LC_ALL=C grep '^[[:alnum:]_]*(' "$LOG" > /dev/null &&
+	dump_log_and_fail_with "$STRACE $args unexpected output"
+
+for a in execve \!chdir all \!none \
+	 file process \!desc \!ipc \!memory \!network \!signal; do
+	check_output_mismatch \
+		"$pattern_abbrev_verbose" -e abbrev="$a" -e execve
+	check_output_mismatch \
+		"$pattern_raw" -a22 -e raw="$a" -e execve
+	check_output_mismatch \
+		"$pattern_abbrev_verbose" -e verbose="$a" -e execve
+done
+
+for a in \!execve chdir 42 \!all none \
+	 \!file \!process desc ipc memory network signal; do
+	check_output_mismatch \
+		"$pattern_nonabbrev_verbose" -e abbrev="$a" -e execve
+	check_output_mismatch \
+		"$pattern_abbrev_verbose" -e raw="$a" -e execve
+	check_output_mismatch \
+		"$pattern_nonverbose" -a31 -e verbose="$a" -e execve
+done
+
 exit 0
diff --git a/tests/quotactl-v.c b/tests/quotactl-v.c
new file mode 100644
index 0000000..0013964
--- /dev/null
+++ b/tests/quotactl-v.c
@@ -0,0 +1,3 @@
+/* This file is part of quotactl-v strace test. */
+#define VERBOSE 1
+#include "quotactl.c"
diff --git a/tests/quotactl-v.test b/tests/quotactl-v.test
new file mode 100755
index 0000000..6adaf82
--- /dev/null
+++ b/tests/quotactl-v.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check non-abbreviated decoding of quotactl syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -v -e trace=quotactl
diff --git a/tests/quotactl-xfs-v.c b/tests/quotactl-xfs-v.c
new file mode 100644
index 0000000..21173d6
--- /dev/null
+++ b/tests/quotactl-xfs-v.c
@@ -0,0 +1,3 @@
+/* This file is part of quotactl-xfs-v strace test. */
+#define VERBOSE 1
+#include "quotactl-xfs.c"
diff --git a/tests/quotactl-xfs-v.test b/tests/quotactl-xfs-v.test
new file mode 100755
index 0000000..d5ffc7d
--- /dev/null
+++ b/tests/quotactl-xfs-v.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check non-abbreviated decoding of quotactl xfs subcommands.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -v -e trace=quotactl
diff --git a/tests/quotactl-xfs.c b/tests/quotactl-xfs.c
new file mode 100644
index 0000000..a08ccd2
--- /dev/null
+++ b/tests/quotactl-xfs.c
@@ -0,0 +1,351 @@
+/*
+ * Check decoding of quotactl xfs subcommands.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#if defined(__NR_quotactl) && \
+	(defined(HAVE_LINUX_QUOTA_H) || defined(HAVE_SYS_QUOTA_H)) && \
+	defined(HAVE_LINUX_DQBLK_XFS_H)
+
+# include <stdio.h>
+# include <string.h>
+# include <unistd.h>
+
+# include <linux/dqblk_xfs.h>
+
+# include "quotactl.h"
+
+# ifndef Q_GETNEXTQUOTA
+#  define Q_XGETNEXTQUOTA	XQM_CMD(0x9)
+# endif /* !Q_GETNEXTQUOTA */
+
+# ifndef Q_XGETQSTATV
+
+#  define Q_XGETQSTATV		XQM_CMD(8)
+#  define FS_QSTATV_VERSION1	1
+
+struct fs_qfilestatv {
+	uint64_t	qfs_ino;	/* inode number */
+	uint64_t	qfs_nblks;	/* number of BBs 512-byte-blks */
+	uint32_t	qfs_nextents;	/* number of extents */
+	uint32_t	qfs_pad;	/* pad for 8-byte alignment */
+};
+
+struct fs_quota_statv {
+	int8_t		qs_version;		/* version for future changes */
+	uint8_t		qs_pad1;		/* pad for 16bit alignment */
+	uint16_t	qs_flags;		/* XFS_QUOTA_.* flags */
+	uint32_t	qs_incoredqs;		/* number of dquots incore */
+	struct fs_qfilestatv	qs_uquota;	/* user quota information */
+	struct fs_qfilestatv	qs_gquota;	/* group quota information */
+	struct fs_qfilestatv	qs_pquota;	/* project quota information */
+	int32_t		qs_btimelimit;		/* limit for blks timer */
+	int32_t		qs_itimelimit;		/* limit for inodes timer */
+	int32_t		qs_rtbtimelimit; 	/* limit for rt blks timer */
+	uint16_t	qs_bwarnlimit;		/* limit for num warnings */
+	uint16_t	qs_iwarnlimit;		/* limit for num warnings */
+	uint64_t	qs_pad2[8];		/* for future proofing */
+};
+
+# endif /* !Q_XGETQSTATV */
+
+# include "xlat.h"
+# include "xlat/xfs_dqblk_flags.h"
+# if VERBOSE
+#  include "xlat/xfs_quota_flags.h"
+# endif
+
+
+void
+print_xdisk_quota(int rc, void *ptr, void *arg)
+{
+	struct fs_disk_quota *dq = ptr;
+	long out_arg = (long) arg;
+
+	if (((rc != 0) && out_arg) || (out_arg > 1)) {
+		printf("%p", dq);
+		return;
+	}
+
+	PRINT_FIELD_D("{", dq, d_version);
+	printf(", d_flags=");
+	printflags(xfs_dqblk_flags, (uint8_t) dq->d_flags, "XFS_???_QUOTA");
+
+	PRINT_FIELD_X(", ", dq, d_fieldmask);
+	PRINT_FIELD_U(", ", dq, d_id);
+	PRINT_FIELD_U(", ", dq, d_blk_hardlimit);
+	PRINT_FIELD_U(", ", dq, d_blk_softlimit);
+	PRINT_FIELD_U(", ", dq, d_ino_hardlimit);
+	PRINT_FIELD_U(", ", dq, d_ino_softlimit);
+	PRINT_FIELD_U(", ", dq, d_bcount);
+	PRINT_FIELD_U(", ", dq, d_icount);
+
+# if VERBOSE
+	PRINT_FIELD_D(", ", dq, d_itimer);
+	PRINT_FIELD_D(", ", dq, d_btimer);
+	PRINT_FIELD_U(", ", dq, d_iwarns);
+	PRINT_FIELD_U(", ", dq, d_bwarns);
+	PRINT_FIELD_U(", ", dq, d_rtb_hardlimit);
+	PRINT_FIELD_U(", ", dq, d_rtb_softlimit);
+	PRINT_FIELD_U(", ", dq, d_rtbcount);
+	PRINT_FIELD_D(", ", dq, d_rtbtimer);
+	PRINT_FIELD_U(", ", dq, d_rtbwarns);
+# else
+	printf(", ...");
+# endif /* !VERBOSE */
+	printf("}");
+}
+
+void
+print_xquota_stat(int rc, void *ptr, void *arg)
+{
+	struct fs_quota_stat *qs = ptr;
+	long out_arg = (long) arg;
+
+	if (((rc != 0) && out_arg) || (out_arg > 1)) {
+		printf("%p", qs);
+		return;
+	}
+
+	PRINT_FIELD_D("{", qs, qs_version);
+
+# if VERBOSE
+	printf(", qs_flags=");
+	printflags(xfs_quota_flags, qs->qs_flags, "XFS_QUOTA_???");
+	PRINT_FIELD_U(", qs_uquota={", &qs->qs_uquota, qfs_ino);
+	PRINT_FIELD_U(", ", &qs->qs_uquota, qfs_nblks);
+	PRINT_FIELD_U(", ", &qs->qs_uquota, qfs_nextents);
+	PRINT_FIELD_U("}, qs_gquota={", &qs->qs_gquota, qfs_ino);
+	PRINT_FIELD_U(", ", &qs->qs_gquota, qfs_nblks);
+	PRINT_FIELD_U(", ", &qs->qs_gquota, qfs_nextents);
+	PRINT_FIELD_U("}, ", qs, qs_incoredqs);
+	PRINT_FIELD_D(", ", qs, qs_btimelimit);
+	PRINT_FIELD_D(", ", qs, qs_itimelimit);
+	PRINT_FIELD_D(", ", qs, qs_rtbtimelimit);
+	PRINT_FIELD_U(", ", qs, qs_bwarnlimit);
+	PRINT_FIELD_U(", ", qs, qs_iwarnlimit);
+# else
+	printf(", ...");
+# endif /* !VERBOSE */
+	printf("}");
+}
+
+void
+print_xquota_statv(int rc, void *ptr, void *arg)
+{
+	struct fs_quota_statv *qs = ptr;
+	long out_arg = (long) arg;
+
+	if (((rc != 0) && out_arg) || (out_arg > 1)) {
+		printf("%p", qs);
+		return;
+	}
+
+	PRINT_FIELD_D("{", qs, qs_version);
+
+# if VERBOSE
+	printf(", qs_flags=");
+	printflags(xfs_quota_flags, qs->qs_flags, "XFS_QUOTA_???");
+	PRINT_FIELD_U(", ", qs, qs_incoredqs);
+	PRINT_FIELD_U(", qs_uquota={", &qs->qs_uquota, qfs_ino);
+	PRINT_FIELD_U(", ", &qs->qs_uquota, qfs_nblks);
+	PRINT_FIELD_U(", ", &qs->qs_uquota, qfs_nextents);
+	PRINT_FIELD_U("}, qs_gquota={", &qs->qs_gquota, qfs_ino);
+	PRINT_FIELD_U(", ", &qs->qs_gquota, qfs_nblks);
+	PRINT_FIELD_U(", ", &qs->qs_gquota, qfs_nextents);
+	PRINT_FIELD_U("}, qs_pquota={", &qs->qs_pquota, qfs_ino);
+	PRINT_FIELD_U(", ", &qs->qs_pquota, qfs_nblks);
+	PRINT_FIELD_U(", ", &qs->qs_pquota, qfs_nextents);
+	PRINT_FIELD_D("}, ", qs, qs_btimelimit);
+	PRINT_FIELD_D(", ", qs, qs_itimelimit);
+	PRINT_FIELD_D(", ", qs, qs_rtbtimelimit);
+	PRINT_FIELD_U(", ", qs, qs_bwarnlimit);
+	PRINT_FIELD_U(", ", qs, qs_iwarnlimit);
+# else
+	printf(", ...");
+# endif /* !VERBOSE */
+	printf("}");
+}
+
+int
+main(void)
+{
+	char bogus_special_str[sizeof(void *) * 2 + sizeof("0x")];
+	char bogus_addr_str[sizeof(void *) * 2 + sizeof("0x")];
+	char unterminated_str[sizeof(void *) * 2 + sizeof("0x")];
+
+	long rc;
+	struct fs_disk_quota *xdq = tail_alloc(sizeof(*xdq));
+	struct fs_quota_stat *xqstat = tail_alloc(sizeof(*xqstat));
+	struct fs_quota_statv *xqstatv = tail_alloc(sizeof(*xqstatv));
+	uint32_t *flags = tail_alloc(sizeof(*flags));
+	char *unterminated = tail_memdup(unterminated_data,
+		sizeof(unterminated_data));
+
+	snprintf(bogus_special_str, sizeof(bogus_special_str), "%p",
+		 bogus_special);
+	snprintf(bogus_addr_str, sizeof(bogus_addr_str), "%p",
+		 bogus_addr);
+	snprintf(unterminated_str, sizeof(unterminated_str), "%p",
+		 unterminated);
+
+
+	/* Q_XQUOTAON */
+
+	*flags = 0xdeadbeef;
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_XQUOTAON, USRQUOTA)),
+		    ARG_STR("/dev/bogus/"), flags,
+		    "[XFS_QUOTA_UDQ_ACCT|XFS_QUOTA_UDQ_ENFD"
+		    "|XFS_QUOTA_GDQ_ACCT|XFS_QUOTA_GDQ_ENFD"
+		    "|XFS_QUOTA_PDQ_ENFD|0xdeadbec0]");
+
+	rc = syscall(__NR_quotactl, QCMD(Q_XQUOTAON, 0xfacefeed), bogus_dev,
+		     bogus_id, bogus_addr);
+	printf("quotactl(QCMD(Q_XQUOTAON, %#x /* ???QUOTA */)"
+	       ", %s, %p) = %s\n",
+	       QCMD_TYPE(QCMD(Q_XQUOTAON, 0xfacefeed)),
+	       bogus_dev_str, bogus_addr, sprintrc(rc));
+
+
+	/* Q_XQUOTAOFF */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_XQUOTAOFF, USRQUOTA)),
+		    bogus_special, bogus_special_str,
+		    bogus_addr, bogus_addr_str);
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_XQUOTAOFF, GRPQUOTA)),
+		    ARG_STR("/dev/bogus/"),
+		    ARG_STR(NULL));
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    QCMD(Q_XQUOTAOFF, 3),
+		    "QCMD(Q_XQUOTAOFF, 0x3 /* ???QUOTA */)",
+		    ARG_STR("/dev/bogus/"), flags,
+		    "[XFS_QUOTA_UDQ_ACCT|XFS_QUOTA_UDQ_ENFD"
+		    "|XFS_QUOTA_GDQ_ACCT|XFS_QUOTA_GDQ_ENFD"
+		    "|XFS_QUOTA_PDQ_ENFD|0xdeadbec0]");
+
+
+	/* Q_XGETQUOTA */
+
+	/* Trying our best to get successful result */
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETQUOTA, USRQUOTA)),
+		    ARG_STR("/dev/sda1"), getuid(), xdq, print_xdisk_quota,
+		    (intptr_t) 1);
+
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETQUOTA, GRPQUOTA)),
+		    ARG_STR(NULL), -1, xdq, print_xdisk_quota, (intptr_t) 2);
+
+
+	/* Q_XGETNEXTQUOTA */
+
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XGETNEXTQUOTA, USRQUOTA)),
+		    ARG_STR("/dev/sda1"), 0, xdq, print_xdisk_quota,
+		    (intptr_t) 1);
+
+
+	/* Q_XSETQLIM */
+
+	check_quota(CQF_NONE, ARG_STR(QCMD(Q_XSETQLIM, PRJQUOTA)),
+		    bogus_special, bogus_special_str, 0, bogus_addr);
+
+	fill_memory_ex((char *) xdq, sizeof(*xdq), 0x8e);
+
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_XSETQLIM, PRJQUOTA)),
+		    bogus_dev, bogus_dev_str, 3141592653U,
+		    xdq, print_xdisk_quota, (intptr_t) 0);
+
+
+	/* Q_XGETQSTAT */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_XGETQSTAT, USRQUOTA)),
+		    ARG_STR("/dev/sda1"), xqstat, print_xquota_stat, (intptr_t) 1);
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_XGETQSTATV, PRJQUOTA)),
+		    unterminated, unterminated_str,
+		    xqstat + 1, print_xquota_stat, (intptr_t) 2);
+
+
+	/* Q_XGETQSTATV */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_XGETQSTAT, USRQUOTA)),
+		    ARG_STR("/dev/sda1"), xqstatv, print_xquota_statv, 1);
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_XGETQSTATV, GRPQUOTA)),
+		    ARG_STR(NULL), xqstatv, print_xquota_statv, (intptr_t) 2);
+
+
+	/* Q_XQUOTARM */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_XQUOTARM, PRJQUOTA)),
+		    bogus_special, bogus_special_str, ARG_STR(NULL));
+	check_quota(CQF_ID_SKIP,
+		    ARG_STR(QCMD(Q_XQUOTARM, USRQUOTA)),
+		    unterminated, unterminated_str, flags + 1);
+
+	*flags = 0xdeadbeef;
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_XQUOTARM, GRPQUOTA)),
+		    ARG_STR(NULL), flags,
+		    "[XFS_USER_QUOTA|XFS_PROJ_QUOTA"
+		    "|XFS_GROUP_QUOTA|0xdeadbee8]");
+
+
+	/* Q_XQUOTASYNC */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    ARG_STR(QCMD(Q_XQUOTASYNC, USRQUOTA)),
+		    bogus_special, bogus_special_str);
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    QCMD(Q_XQUOTASYNC, 0xfff),
+		    "QCMD(Q_XQUOTASYNC, 0xff /* ???QUOTA */)",
+		    ARG_STR(NULL));
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_quotactl && "
+	"(HAVE_LINUX_QUOTA_H || HAVE_SYS_QUOTA_H) && "
+	"HAVE_LINUX_DQBLK_XFS_H");
+
+#endif
diff --git a/tests/quotactl-xfs.test b/tests/quotactl-xfs.test
new file mode 100755
index 0000000..404a737
--- /dev/null
+++ b/tests/quotactl-xfs.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of quotactl xfs subcommands.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -e trace=quotactl
diff --git a/tests/quotactl.c b/tests/quotactl.c
new file mode 100644
index 0000000..d68c4ec
--- /dev/null
+++ b/tests/quotactl.c
@@ -0,0 +1,317 @@
+/*
+ * Check decoding of quotactl syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#if defined(__NR_quotactl) && \
+	(defined(HAVE_LINUX_QUOTA_H) || defined(HAVE_SYS_QUOTA_H))
+
+# include <inttypes.h>
+# include <stdint.h>
+# include <stdio.h>
+# include <string.h>
+# include <unistd.h>
+
+# include "quotactl.h"
+
+# ifndef HAVE_LINUX_QUOTA_H
+/* Some dirty hacks in order to make sys/quota.h usable as a backup */
+
+#  define if_dqblk dqblk
+#  define if_nextdqblk nextdqblk
+#  define if_dqinfo dqinfo
+
+# endif /* !HAVE_LINUX_QUOTA_H */
+
+# ifndef Q_GETNEXTQUOTA
+
+#  define Q_GETNEXTQUOTA 0x800009
+
+struct if_nextdqblk {
+	uint64_t dqb_bhardlimit;
+	uint64_t dqb_bsoftlimit;
+	uint64_t dqb_curspace;
+	uint64_t dqb_ihardlimit;
+	uint64_t dqb_isoftlimit;
+	uint64_t dqb_curinodes;
+	uint64_t dqb_btime;
+	uint64_t dqb_itime;
+	uint32_t dqb_valid;
+	uint32_t dqb_id;
+};
+# endif /* !Q_GETNEXTQUOTA */
+
+# include "xlat.h"
+# include "xlat/quota_formats.h"
+# include "xlat/if_dqblk_valid.h"
+# include "xlat/if_dqinfo_flags.h"
+# include "xlat/if_dqinfo_valid.h"
+
+void
+print_dqblk(long rc, void *ptr, void *arg)
+{
+	struct if_dqblk *db = ptr;
+	long out_arg = (long) arg;
+
+	if (((rc != 0) && out_arg) || (out_arg > 1)) {
+		printf("%p", db);
+		return;
+	}
+
+	PRINT_FIELD_U("{", db, dqb_bhardlimit);
+	PRINT_FIELD_U(", ", db, dqb_bsoftlimit);
+	PRINT_FIELD_U(", ", db, dqb_curspace);
+	PRINT_FIELD_U(", ", db, dqb_ihardlimit);
+	PRINT_FIELD_U(", ", db, dqb_isoftlimit);
+	PRINT_FIELD_U(", ", db, dqb_curinodes);
+
+# if VERBOSE
+	PRINT_FIELD_U(", ", db, dqb_btime);
+	PRINT_FIELD_U(", ", db, dqb_itime);
+
+	printf(", dqb_valid=");
+	printflags(if_dqblk_valid, db->dqb_valid, "QIF_???");
+# else
+	printf(", ...");
+# endif /* !VERBOSE */
+	printf("}");
+}
+
+void
+print_nextdqblk(long rc, void *ptr, void *arg)
+{
+	struct if_nextdqblk *db = ptr;
+	long out_arg = (long) arg;
+
+	if (((rc != 0) && out_arg) || (out_arg > 1)) {
+		printf("%p", db);
+		return;
+	}
+
+	PRINT_FIELD_U("{", db, dqb_bhardlimit);
+	PRINT_FIELD_U(", ", db, dqb_bsoftlimit);
+	PRINT_FIELD_U(", ", db, dqb_curspace);
+	PRINT_FIELD_U(", ", db, dqb_ihardlimit);
+	PRINT_FIELD_U(", ", db, dqb_isoftlimit);
+	PRINT_FIELD_U(", ", db, dqb_curinodes);
+
+# if VERBOSE
+	PRINT_FIELD_U(", ", db, dqb_btime);
+	PRINT_FIELD_U(", ", db, dqb_itime);
+
+	printf(", dqb_valid=");
+	printflags(if_dqblk_valid, db->dqb_valid, "QIF_???");
+
+	PRINT_FIELD_U(", ", db, dqb_id);
+# else
+	PRINT_FIELD_U(", ", db, dqb_id);
+	printf(", ...");
+# endif /* !VERBOSE */
+	printf("}");
+}
+
+void
+print_dqinfo(long rc, void *ptr, void *arg)
+{
+	struct if_dqinfo *di = ptr;
+	long out_arg = (long) arg;
+
+	if (((rc != 0) && out_arg) || (out_arg > 1)) {
+		printf("%p", di);
+		return;
+	}
+
+	PRINT_FIELD_U("{", di, dqi_bgrace);
+	PRINT_FIELD_U(", ", di, dqi_igrace);
+
+	printf(", dqi_flags=");
+	printflags(if_dqinfo_flags, di->dqi_flags, "DQF_???");
+	printf(", dqi_valid=");
+	printflags(if_dqinfo_valid, di->dqi_valid, "IIF_???");
+	printf("}");
+}
+
+
+int
+main(void)
+{
+	char bogus_special_str[sizeof(void *) * 2 + sizeof("0x")];
+	char unterminated_str[sizeof(void *) * 2 + sizeof("0x")];
+
+	long rc;
+	char *unterminated = tail_memdup(unterminated_data,
+					 sizeof(unterminated_data));
+	struct if_dqblk *dqblk = tail_alloc(sizeof(*dqblk));
+	struct if_dqinfo *dqinfo = tail_alloc(sizeof(*dqinfo));
+	uint32_t *fmt = tail_alloc(sizeof(*fmt));
+	struct if_nextdqblk *nextdqblk = tail_alloc(sizeof(*nextdqblk));
+
+
+	snprintf(bogus_special_str, sizeof(bogus_special_str), "%p",
+		bogus_special);
+	snprintf(unterminated_str, sizeof(unterminated_str), "%p",
+		unterminated);
+
+
+	/* Invalid commands */
+
+	rc = syscall(__NR_quotactl, bogus_cmd, bogus_special, bogus_id,
+		     bogus_addr);
+	printf("quotactl(QCMD(%#x /* Q_??? */, %#x /* ???QUOTA */)"
+	       ", %p, %u, %p) = %s\n",
+	       QCMD_CMD(bogus_cmd), QCMD_TYPE(bogus_cmd),
+	       bogus_special, bogus_id, bogus_addr, sprintrc(rc));
+
+	rc = syscall(__NR_quotactl, 0, NULL, -1, NULL);
+	printf("quotactl(QCMD(0 /* Q_??? */, USRQUOTA), NULL, -1, NULL) = %s\n",
+	       sprintrc(rc));
+
+
+	/* Q_QUOTAON */
+
+	check_quota(CQF_ID_STR | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_QUOTAON, USRQUOTA)),
+		    ARG_STR("/dev/bogus/"), ARG_STR(QFMT_VFS_OLD),
+		    ARG_STR("/tmp/bogus/"));
+
+	rc = syscall(__NR_quotactl, QCMD(Q_QUOTAON, 0xfacefeed), bogus_dev,
+		     bogus_id, bogus_addr);
+	printf("quotactl(QCMD(Q_QUOTAON, %#x /* ???QUOTA */)"
+	       ", %s, %#x /* QFMT_VFS_??? */, %p) = %s\n",
+	       QCMD_TYPE(QCMD(Q_QUOTAON, 0xfacefeed)),
+	       bogus_dev_str, bogus_id, bogus_addr, sprintrc(rc));
+
+
+	/* Q_QUOTAOFF */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    ARG_STR(QCMD(Q_QUOTAOFF, USRQUOTA)),
+		    bogus_special, bogus_special_str);
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    ARG_STR(QCMD(Q_QUOTAOFF, GRPQUOTA)),
+		    ARG_STR("/dev/bogus/"));
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    ARG_STR(QCMD(Q_QUOTAOFF, PRJQUOTA)), ARG_STR(NULL));
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    QCMD(Q_QUOTAOFF, 3), "QCMD(Q_QUOTAOFF, 0x3 /* ???QUOTA */)",
+		    ARG_STR(NULL));
+
+
+	/* Q_GETQUOTA */
+
+	/* Trying our best to get successful result */
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETQUOTA, USRQUOTA)),
+		    ARG_STR("/dev/sda1"), getuid(), dqblk, print_dqblk,
+		    (intptr_t) 1);
+
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETQUOTA, GRPQUOTA)),
+		    ARG_STR(NULL), -1, dqblk, print_dqblk, (intptr_t) 2);
+
+
+	/* Q_GETNEXTQUOTA */
+
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_GETNEXTQUOTA, USRQUOTA)),
+		    ARG_STR("/dev/sda1"), 0, nextdqblk, print_nextdqblk,
+		    (intptr_t) 1);
+
+
+	/* Q_SETQUOTA */
+
+	fill_memory((char *) dqblk, sizeof(*dqblk));
+
+	check_quota(CQF_NONE, ARG_STR(QCMD(Q_SETQUOTA, PRJQUOTA)),
+		    bogus_special, bogus_special_str, 0, bogus_addr);
+
+	check_quota(CQF_ADDR_CB, ARG_STR(QCMD(Q_SETQUOTA, PRJQUOTA)),
+		    ARG_STR("/dev/bogus/"), 3141592653U, dqblk, print_dqblk,
+		    (intptr_t) 0);
+
+
+	/* Q_GETINFO */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_GETINFO, GRPQUOTA)),
+		    ARG_STR("/dev/sda1"), dqinfo, print_dqinfo, (intptr_t) 1);
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_GETINFO, GRPQUOTA)),
+		    bogus_special, bogus_special_str, dqinfo,
+		    print_dqinfo, (intptr_t) 2);
+
+	/* Q_SETINFO */
+
+	fill_memory((char *) dqinfo, sizeof(*dqinfo));
+	/* In order to check flag printing correctness */
+	dqinfo->dqi_flags = 0xdeadabcd;
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_SETINFO, PRJQUOTA)),
+		    bogus_special, bogus_special_str, ARG_STR(NULL));
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_CB,
+		    ARG_STR(QCMD(Q_SETINFO, USRQUOTA)),
+		    ARG_STR("/dev/bogus/"), dqinfo, print_dqinfo, (intptr_t) 0);
+
+
+	/* Q_GETFMT */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_STR,
+		    ARG_STR(QCMD(Q_GETFMT, PRJQUOTA)),
+		    bogus_special, bogus_special_str, ARG_STR(NULL));
+	check_quota(CQF_ID_SKIP,
+		    ARG_STR(QCMD(Q_GETFMT, USRQUOTA)),
+		    unterminated, unterminated_str, fmt + 1);
+	check_quota(CQF_ID_SKIP,
+		    ARG_STR(QCMD(Q_GETFMT, GRPQUOTA)),
+		    ARG_STR("/dev/sda1"), fmt);
+
+
+	/* Q_SYNC */
+
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    ARG_STR(QCMD(Q_SYNC, USRQUOTA)),
+		    bogus_special, bogus_special_str);
+	check_quota(CQF_ID_SKIP | CQF_ADDR_SKIP,
+		    QCMD(Q_SYNC, 0xfff), "QCMD(Q_SYNC, 0xff /* ???QUOTA */)",
+		    ARG_STR(NULL));
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_quotactl && "
+	"(HAVE_LINUX_QUOTA_H || HAVE_SYS_QUOTA_H)");
+
+#endif
diff --git a/tests/quotactl.h b/tests/quotactl.h
new file mode 100644
index 0000000..49a6f87
--- /dev/null
+++ b/tests/quotactl.h
@@ -0,0 +1,188 @@
+/*
+ * Common definitions for Linux and XFS quota tests.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRACE_TESTS_QUOTACTL_H
+#define STRACE_TESTS_QUOTACTL_H
+
+# include <inttypes.h>
+# include <stdarg.h>
+# include <stdio.h>
+
+# ifdef HAVE_LINUX_QUOTA_H
+/* Broken in CentOS 5: has extern spinlock_t dq_data_lock; declaration */
+#  include <linux/quota.h>
+# else
+#  include <linux/types.h>
+/* Broken in some new glibc versions: have Q_GETNEXTQUOTA definition but no
+ * struct nextdqblk defined. Fixed in glibc-2.24-106-g4d72808. */
+#  include <sys/quota.h>
+# endif
+
+# ifndef QCMD_CMD
+#  define QCMD_CMD(_val) ((unsigned) (_val) >> SUBCMDSHIFT)
+# endif /* !QCMD_CMD */
+
+# ifndef QCMD_TYPE
+#  define QCMD_TYPE(_val) ((unsigned) (_val) & SUBCMDMASK)
+# endif /* !QCMD_TYPE */
+
+# ifndef PRJQUOTA
+#  define PRJQUOTA 2
+# endif
+
+# define PRINT_FIELD_D(prefix, where, field)	\
+	printf("%s%s=%lld", (prefix), #field,	\
+	       sign_extend_unsigned_to_ll((where)->field))
+
+# define PRINT_FIELD_U(prefix, where, field)	\
+	printf("%s%s=%llu", (prefix), #field,	\
+	       zero_extend_signed_to_ull((where)->field))
+
+# define PRINT_FIELD_X(prefix, where, field)	\
+	printf("%s%s=%#llx", (prefix), #field,	\
+	       zero_extend_signed_to_ull((where)->field))
+
+# define ARG_STR(_arg) (_arg), #_arg
+
+typedef void (*print_cb)(long rc, void *addr, void *arg);
+
+enum check_quotactl_flag_bits {
+	CQF_ID_SKIP_BIT,
+	CQF_ID_STR_BIT,
+	CQF_ADDR_SKIP_BIT,
+	CQF_ADDR_STR_BIT,
+	CQF_ADDR_CB_BIT,
+};
+
+enum check_quotactl_flags {
+	CQF_NONE,
+	CQF_ID_SKIP   = 1 << CQF_ID_SKIP_BIT,
+	CQF_ID_STR    = 1 << CQF_ID_STR_BIT,
+	CQF_ADDR_SKIP = 1 << CQF_ADDR_SKIP_BIT,
+	CQF_ADDR_STR  = 1 << CQF_ADDR_STR_BIT,
+	CQF_ADDR_CB   = 1 << CQF_ADDR_CB_BIT,
+};
+
+
+static inline void
+fill_memory_ex(char *ptr, size_t size, unsigned char start)
+{
+	size_t i;
+
+	for (i = 0; i < size; i++) {
+		ptr[i] = start + i % 80;
+	}
+}
+
+static inline void
+fill_memory(char *ptr, size_t size)
+{
+	fill_memory_ex(ptr, size, 0x80);
+}
+
+static inline void
+check_quota(uint32_t flags, int cmd, const char *cmd_str,
+	const char *special, const char *special_str, ...)
+{
+	long rc;
+	const char *addr_str = NULL;
+	const char *id_str = NULL;
+	void *addr = NULL;
+	print_cb addr_cb = NULL;
+	void *addr_cb_arg = NULL;
+	uint32_t id = -1;
+
+	va_list ap;
+
+	va_start(ap, special_str);
+
+	if (!(flags & CQF_ID_SKIP)) {
+		id = va_arg(ap, uint32_t);
+
+		if (flags & CQF_ID_STR)
+			id_str = va_arg(ap, const char *);
+	}
+
+	if (!(flags & CQF_ADDR_SKIP)) {
+		addr = va_arg(ap, void *);
+
+		if (flags & CQF_ADDR_CB) {
+			addr_cb = va_arg(ap, print_cb);
+			addr_cb_arg = va_arg(ap, void *);
+		} else if (flags & CQF_ADDR_STR) {
+			addr_str = va_arg(ap, const char *);
+		}
+	}
+
+	va_end(ap);
+
+	rc = syscall(__NR_quotactl, cmd, special, id, addr);
+	printf("quotactl(%s, %s", cmd_str, special_str);
+
+	if (!(flags & CQF_ID_SKIP)) {
+		if (flags & CQF_ID_STR) {
+			printf(", %s", id_str);
+		} else {
+			if (id == (uint32_t)-1)
+				printf(", -1");
+			else
+				printf(", %u", id);
+		}
+	}
+
+	if (!(flags & CQF_ADDR_SKIP)) {
+		if (flags & CQF_ADDR_CB) {
+			printf(", ");
+			addr_cb(rc, addr, addr_cb_arg);
+		} else if (flags & CQF_ADDR_STR) {
+			printf(", %s", addr_str);
+		} else {
+			printf(", %p", addr);
+		}
+	}
+
+	printf(") = %s\n", sprintrc(rc));
+}
+
+
+static const int bogus_cmd = 0xbadc0ded;
+static const char * const bogus_special =
+	(const char *) (unsigned long) 0xfffffca7ffffc0deULL;
+static const int bogus_id = 0xca7faced;
+static void * const bogus_addr =
+	(void *) (unsigned long) 0xffffda7affffdeadULL;
+
+/* It is invalid anyway due to the flash in the end */
+static const char *bogus_dev = "/dev/bogus/";
+static const char *bogus_dev_str = "\"/dev/bogus/\"";
+
+static const char unterminated_data[] = { '\1', '\2', '\3' };
+
+#endif /* !STRACE_TESTS_QUOTACTL_H */
diff --git a/tests/quotactl.test b/tests/quotactl.test
new file mode 100755
index 0000000..d0101f4
--- /dev/null
+++ b/tests/quotactl.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of quotactl syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff
diff --git a/tests/readahead.c b/tests/readahead.c
new file mode 100644
index 0000000..5677c1e
--- /dev/null
+++ b/tests/readahead.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <asm/unistd.h>
+
+#ifdef HAVE_READAHEAD
+# ifdef __GLIBC__
+/*
+ * Check for glibc readahead off64_t argument passing bug,
+ * see https://sourceware.org/bugzilla/show_bug.cgi?id=5208
+ */
+#  if !(defined __GLIBC_MINOR__ && \
+        (__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 8)
+#   undef HAVE_READAHEAD
+#  endif
+# endif /* __GLIBC__ */
+#endif /* HAVE_READAHEAD */
+
+#ifdef HAVE_READAHEAD
+
+# include <fcntl.h>
+# include <stdio.h>
+
+static const int fds[] = {
+	-0x80000000,
+	-100,
+	-1,
+	0,
+	1,
+	2,
+	0x7fffffff,
+};
+
+static const off64_t offsets[] = {
+	-0x8000000000000000LL,
+	-0x5060708090a0b0c0LL,
+	-1LL,
+	 0,
+	 1,
+	 0xbadfaced,
+	 0x7fffffffffffffffLL,
+};
+
+static const unsigned long counts[] = {
+	0UL,
+	0xdeadca75,
+	(unsigned long) 0xface1e55beeff00dULL,
+	(unsigned long) 0xffffffffffffffffULL,
+};
+
+int
+main(void)
+{
+	unsigned i;
+	unsigned j;
+	unsigned k;
+	ssize_t rc;
+
+	for (i = 0; i < ARRAY_SIZE(fds); i++)
+		for (j = 0; j < ARRAY_SIZE(offsets); j++)
+			for (k = 0; k < ARRAY_SIZE(counts); k++) {
+				rc = readahead(fds[i], offsets[j], counts[k]);
+
+				printf("readahead(%d, %lld, %lu) = %s\n",
+					fds[i], (long long) offsets[j],
+					counts[k], sprintrc(rc));
+			}
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("HAVE_READAHEAD")
+
+#endif
diff --git a/tests/readahead.test b/tests/readahead.test
new file mode 100755
index 0000000..397c690
--- /dev/null
+++ b/tests/readahead.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check readahead syscall decoding.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a1
diff --git a/tests/readdir.c b/tests/readdir.c
index 85170aa..8c48362 100644
--- a/tests/readdir.c
+++ b/tests/readdir.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_readdir
 
diff --git a/tests/readlink.c b/tests/readlink.c
index 85777e4..4ddf5fa 100644
--- a/tests/readlink.c
+++ b/tests/readlink.c
@@ -27,7 +27,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_readlink
 
diff --git a/tests/readlinkat.c b/tests/readlinkat.c
index 5ca9e72..4d3b516 100644
--- a/tests/readlinkat.c
+++ b/tests/readlinkat.c
@@ -27,7 +27,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_readlinkat
 
diff --git a/tests/reboot.c b/tests/reboot.c
index eedc2a6..9b09e64 100644
--- a/tests/reboot.c
+++ b/tests/reboot.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_reboot
 
diff --git a/tests/signalfd.c b/tests/redirect-fds.c
similarity index 65%
copy from tests/signalfd.c
copy to tests/redirect-fds.c
index 7b1d6ce..fc1073a 100644
--- a/tests/signalfd.c
+++ b/tests/redirect-fds.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,29 +26,49 @@
  */
 
 #include "tests.h"
-#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/stat.h>
 
-#if defined HAVE_SYS_SIGNALFD_H && defined HAVE_SIGNALFD && defined O_CLOEXEC
+#define N_FDS 3
 
-# include <signal.h>
-# include <unistd.h>
-# include <sys/signalfd.h>
-
-int
-main(void)
+/*
+ * Do not print any messages, indicate errors with return codes.
+ */
+static int
+check_fd(int fd, const char *fname)
 {
-	sigset_t mask;
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGUSR2);
-	sigaddset(&mask, SIGCHLD);
-	(void) close(0);
-	if (signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK))
-		perror_msg_and_skip("signalfd");
+	const int should_be_closed = (fname[0] == '\0');
+
+	struct stat st_fd, st_fn;
+
+	if (fstat(fd, &st_fd)) {
+		if (!should_be_closed)
+			return 10 + fd;
+	} else {
+		if (should_be_closed)
+			return 20 + fd;
+
+		if (stat(fname, &st_fn))
+			return 30 + fd;
+
+		if (st_fd.st_dev != st_fn.st_dev
+		    || st_fd.st_ino != st_fn.st_ino)
+			return 40 + fd;
+	}
+
 	return 0;
 }
 
-#else
+int
+main(int ac, char **av)
+{
+	assert(ac == 1 + N_FDS);
 
-SKIP_MAIN_UNDEFINED("HAVE_SYS_SIGNALFD_H && HAVE_SIGNALFD && O_CLOEXEC")
+	int rc = 0, fd;
+	for (fd = 1; fd < 1 + N_FDS; ++fd)
+		if ((rc = check_fd(fd - 1, av[fd])))
+			break;
 
-#endif
+	return rc;
+}
diff --git a/tests/redirect-fds.test b/tests/redirect-fds.test
new file mode 100755
index 0000000..a451917
--- /dev/null
+++ b/tests/redirect-fds.test
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Check that strace does not leak placeholder descriptors.
+#
+# Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+. "${srcdir=.}/init.sh"
+
+fd0="$LOG.fd0"
+fd1="$LOG.fd1"
+fd2="$LOG.fd2"
+
+check_prog touch
+
+check_fd()
+{
+	local a1 a2 a3
+	a1="$1"
+	a2="$2"
+	a3="$3"
+
+	touch "$LOG" "$fd0" ||
+		framework_skip_ 'failed to create files'
+
+	set -- "\"./$NAME\"" "\"$1\"" "\"$2\"" "\"$3\""
+	eval "$@" "<${a1:-&-}" ">${a2:-&-}" "2>${a3:-&-}" ||
+			fail_ "$* failed with code $rc"
+
+	set -- "$STRACE" -o"$LOG" -echdir "$@"
+	eval "$@" "<${a1:-&-}" ">${a2:-&-}" "2>${a3:-&-}" ||
+		dump_log_and_fail_with "$* failed with code $?"
+
+	rm -f "$LOG" "$fd0" "$fd1" "$fd2"
+}
+
+check_fd "$fd0" "$fd1" "$fd2"
+check_fd ''     "$fd1" "$fd2"
+check_fd "$fd0" ''     "$fd2"
+check_fd "$fd0" "$fd1" ''
+check_fd ''     ''     "$fd2"
+check_fd ''     "$fd1" ''
+check_fd "$fd0" ''     ''
+check_fd ''     ''     ''
diff --git a/tests/remap_file_pages.c b/tests/remap_file_pages.c
index 8aa099e..9298f28 100644
--- a/tests/remap_file_pages.c
+++ b/tests/remap_file_pages.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_remap_file_pages
 
diff --git a/tests/rename.c b/tests/rename.c
index a2a9209..2a2a4e0 100644
--- a/tests/rename.c
+++ b/tests/rename.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rename
 
diff --git a/tests/renameat.c b/tests/renameat.c
index da38f23..d201578 100644
--- a/tests/renameat.c
+++ b/tests/renameat.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_renameat
 
diff --git a/tests/renameat2.c b/tests/renameat2.c
index 28a1b5b..ea57185 100644
--- a/tests/renameat2.c
+++ b/tests/renameat2.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_renameat2
 
diff --git a/tests/request_key.c b/tests/request_key.c
new file mode 100644
index 0000000..361bf52
--- /dev/null
+++ b/tests/request_key.c
@@ -0,0 +1,152 @@
+/*
+ * Check decoding of request_key syscall.
+ *
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+
+#include <asm/unistd.h>
+
+#ifdef __NR_request_key
+
+# include <inttypes.h>
+# include <stdio.h>
+# include <unistd.h>
+
+void
+print_val_str(const void *ptr, const char *str)
+{
+	if (str)
+		printf("%s, ", str);
+	else
+		printf("%p, ", ptr);
+}
+
+void
+do_request_key(const char *type, const char *type_str, const char *desc,
+	const char *desc_str, const char *info, const char *info_str,
+	int32_t keyring, const char *keyring_str)
+{
+	long rc = syscall(__NR_request_key, type, desc, info, keyring);
+	const char *errstr = sprintrc(rc);
+	printf("request_key(");
+	print_val_str(type, type_str);
+	print_val_str(desc, desc_str);
+	print_val_str(info, info_str);
+	if (keyring_str)
+		printf("%s", keyring_str);
+	else
+		printf("%d", keyring);
+	printf(") = %s\n", errstr);
+}
+
+# define _STR(_arg) #_arg
+# define ARG_STR(_arg) (_arg), #_arg
+
+int
+main(void)
+{
+	static const char unterminated1[] = { '\1', '\2', '\3', '\4', '\5' };
+	static const char unterminated2[] = { '\6', '\7', '\10', '\11', '\12' };
+	static const char unterminated3[] =
+		{ '\16', '\17', '\20', '\21', '\22' };
+
+	char *bogus_type = tail_memdup(unterminated1, sizeof(unterminated1));
+	char *bogus_desc = tail_memdup(unterminated2, sizeof(unterminated2));
+	char *bogus_info = tail_memdup(unterminated3, sizeof(unterminated3));
+
+	unsigned i;
+	unsigned j;
+	unsigned k;
+	unsigned l;
+
+	struct {
+		const char *type;
+		const char *str;
+	} types[] = {
+		{ ARG_STR(NULL) },
+		{ (const char *) 0xfffffee1fffffbadULL, NULL },
+		{ bogus_type, NULL },
+		{ ARG_STR("\20\21\22\23\24") },
+		{ ARG_STR("user") },
+	};
+
+	struct {
+		const char *desc;
+		const char *str;
+	} descs[] = {
+		{ ARG_STR(NULL) },
+		{ (const char *) 0xfffff00dfffffca7ULL, NULL },
+		{ bogus_desc, NULL },
+		{ ARG_STR("\25\26\27\30\31") },
+		{ ARG_STR("desc") },
+		{ "overly long description", _STR("overly long ") "..." },
+	};
+
+	struct {
+		const char *info;
+		const char *str;
+	} infos[] = {
+		{ ARG_STR(NULL) },
+		{ (const char *) 0xfffffacefffff157ULL, NULL },
+		{ bogus_info, NULL },
+		{ ARG_STR("\32\33\34\35\36") },
+		{ ARG_STR("info") },
+		{ "overly long info", _STR("overly long ") "..." },
+	};
+
+	struct {
+		uint32_t keyring;
+		const char *str;
+	} keyrings[] = {
+		{ ARG_STR(0) },
+		{ ARG_STR(1234567890) },
+		{ ARG_STR(-1234567890) },
+		{ -1, "KEY_SPEC_THREAD_KEYRING" },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(types); i++)
+		for (j = 0; j < ARRAY_SIZE(descs); j++)
+			for (k = 0; k < ARRAY_SIZE(infos); k++)
+				for (l = 0; l < ARRAY_SIZE(keyrings); l++)
+					do_request_key(
+						types[i].type, types[i].str,
+						descs[j].desc, descs[j].str,
+						infos[k].info, infos[k].str,
+						keyrings[l].keyring,
+						keyrings[l].str);
+
+	puts("+++ exited with 0 +++");
+
+	return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_request_key");
+
+#endif
diff --git a/tests/request_key.test b/tests/request_key.test
new file mode 100755
index 0000000..9812a18
--- /dev/null
+++ b/tests/request_key.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of request_key syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff -a33 -s12
diff --git a/tests/rmdir.c b/tests/rmdir.c
index e5a7f1d..20952d8 100644
--- a/tests/rmdir.c
+++ b/tests/rmdir.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rmdir
 
diff --git a/tests/rt_sigpending.c b/tests/rt_sigpending.c
index a6381cd..accf691 100644
--- a/tests/rt_sigpending.c
+++ b/tests/rt_sigpending.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rt_sigpending
 
diff --git a/tests/rt_sigprocmask.c b/tests/rt_sigprocmask.c
index ab92cde..27e357f 100644
--- a/tests/rt_sigprocmask.c
+++ b/tests/rt_sigprocmask.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rt_sigprocmask
 
diff --git a/tests/rt_sigsuspend.c b/tests/rt_sigsuspend.c
index b96a8c9..73e1336 100644
--- a/tests/rt_sigsuspend.c
+++ b/tests/rt_sigsuspend.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rt_sigsuspend
 
diff --git a/tests/rt_sigtimedwait.c b/tests/rt_sigtimedwait.c
index 6136b7c..ee6d3b9 100644
--- a/tests/rt_sigtimedwait.c
+++ b/tests/rt_sigtimedwait.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rt_sigtimedwait
 
diff --git a/tests/rt_tgsigqueueinfo.c b/tests/rt_tgsigqueueinfo.c
index 0926fb1..ebfb719 100644
--- a/tests/rt_tgsigqueueinfo.c
+++ b/tests/rt_tgsigqueueinfo.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_rt_tgsigqueueinfo
 
@@ -67,7 +67,8 @@
 	info->si_value.sival_ptr = (void *) (unsigned long) 0xdeadbeeffacefeed;
 
 	if (k_tgsigqueueinfo(info->si_pid, SIGUSR1, info))
-		perror_msg_and_fail("rt_tgsigqueueinfo");
+		(errno == ENOSYS ? perror_msg_and_skip : perror_msg_and_fail)(
+			"rt_tgsigqueueinfo");
 
 	printf("rt_tgsigqueueinfo(%u, %u, %s, {si_signo=%s"
 		", si_code=SI_QUEUE, si_errno=ENOENT, si_pid=%u"
diff --git a/tests/sched_get_priority_mxx.c b/tests/sched_get_priority_mxx.c
index 7145317..fc14b27 100644
--- a/tests/sched_get_priority_mxx.c
+++ b/tests/sched_get_priority_mxx.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined(__NR_sched_get_priority_min) \
  && defined(__NR_sched_get_priority_max)
diff --git a/tests/sched_rr_get_interval.c b/tests/sched_rr_get_interval.c
index dd069e2..99943e7 100644
--- a/tests/sched_rr_get_interval.c
+++ b/tests/sched_rr_get_interval.c
@@ -1,8 +1,9 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_sched_rr_get_interval
 
+# include <stdint.h>
 # include <stdio.h>
 # include <sched.h>
 # include <unistd.h>
@@ -11,9 +12,24 @@
 main(void)
 {
 	struct timespec *const tp = tail_alloc(sizeof(struct timespec));
-	long rc = syscall(__NR_sched_rr_get_interval, -1, tp);
-	printf("sched_rr_get_interval(-1, %p) = %ld %s (%m)\n",
-	       tp, rc, errno2name());
+	long rc;
+
+	rc = syscall(__NR_sched_rr_get_interval, 0, NULL);
+	printf("sched_rr_get_interval(0, NULL) = %s\n", sprintrc(rc));
+
+	rc = syscall(__NR_sched_rr_get_interval, 0, tp + 1);
+	printf("sched_rr_get_interval(0, %p) = %s\n", tp + 1, sprintrc(rc));
+
+	rc = syscall(__NR_sched_rr_get_interval, -1, tp);
+	printf("sched_rr_get_interval(-1, %p) = %s\n", tp, sprintrc(rc));
+
+	rc = syscall(__NR_sched_rr_get_interval, 0, tp);
+	if (rc == 0)
+		printf("sched_rr_get_interval(0, {%jd, %jd}) = 0\n",
+			(intmax_t)tp->tv_sec, (intmax_t)tp->tv_nsec);
+	else
+		printf("sched_rr_get_interval(-1, %p) = %s\n", tp,
+			sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/sched_xetaffinity.c b/tests/sched_xetaffinity.c
index 8851a4a..195f3af 100644
--- a/tests/sched_xetaffinity.c
+++ b/tests/sched_xetaffinity.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <sched.h>
 
 #if defined __NR_sched_getaffinity && defined __NR_sched_setaffinity \
diff --git a/tests/sched_xetattr.c b/tests/sched_xetattr.c
index c06e9b2..1b48491 100644
--- a/tests/sched_xetattr.c
+++ b/tests/sched_xetattr.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_sched_getattr && defined __NR_sched_setattr
 
@@ -37,44 +37,89 @@
 int
 main(void)
 {
-	static union {
-		struct {
-			uint32_t size;
-			uint32_t sched_policy;
-			uint64_t sched_flags;
-			uint32_t sched_nice;
-			uint32_t sched_priority;
-			uint64_t sched_runtime;
-			uint64_t sched_deadline;
-			uint64_t sched_period;
-		} attr;
-		char buf[256];
-	} sched;
+	struct {
+		uint32_t size;
+		uint32_t sched_policy;
+		uint64_t sched_flags;
+		int32_t  sched_nice;
+		uint32_t sched_priority;
+		uint64_t sched_runtime;
+		uint64_t sched_deadline;
+		uint64_t sched_period;
+	} *sched_attr = tail_alloc(sizeof(*sched_attr));
 
-	if (syscall(__NR_sched_getattr, 0, &sched, sizeof(sched), 0))
+	long rc = syscall(__NR_sched_getattr, 0xdeadface, NULL, 0, 0);
+	printf("sched_getattr\\(%d, NULL, 0, 0\\) += %s\n",
+		0xdeadface, sprintrc_grep(rc));
+
+	rc = syscall(__NR_sched_getattr, -1,
+		     sched_attr, 0xbadfaced, 0xc0defeed);
+	printf("sched_getattr\\(-1, %p, %u, %u\\) += %s\n",
+		sched_attr, 0xbadfaced, 0xc0defeed, sprintrc_grep(rc));
+
+	rc = syscall(__NR_sched_getattr, 0,
+		     sched_attr + 1, sizeof(*sched_attr), 0);
+	printf("sched_getattr\\(0, %p, %u, 0\\) += %s\n",
+		sched_attr + 1, (unsigned)sizeof(*sched_attr),
+		sprintrc_grep(rc));
+
+	if (syscall(__NR_sched_getattr, 0, sched_attr, sizeof(*sched_attr), 0))
 		perror_msg_and_skip("sched_getattr");
 
-	printf("sched_getattr\\(0, \\{size=%u, sched_policy=SCHED_[A-Z]+, sched_flags=%s, sched_nice=%u, sched_priority=%u, sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 "\\}, 256, 0\\) += 0\n",
-		sched.attr.size,
-		sched.attr.sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
-		sched.attr.sched_nice,
-		sched.attr.sched_priority,
-		sched.attr.sched_runtime,
-		sched.attr.sched_deadline,
-		sched.attr.sched_period);
+	printf("sched_getattr\\(0, \\{size=%u, sched_policy=SCHED_[A-Z]+"
+	       ", sched_flags=%s, sched_nice=%d, sched_priority=%u"
+	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
+	       ", sched_period=%" PRIu64 "\\}, %u, 0\\) += 0\n",
+	       sched_attr->size,
+	       sched_attr->sched_flags ? "SCHED_FLAG_RESET_ON_FORK" : "0",
+	       sched_attr->sched_nice,
+	       sched_attr->sched_priority,
+	       sched_attr->sched_runtime,
+	       sched_attr->sched_deadline,
+	       sched_attr->sched_period,
+	       (unsigned) sizeof(*sched_attr));
 
-	sched.attr.sched_flags |= 1;
-	if (syscall(__NR_sched_setattr, 0, &sched, 0))
+	sched_attr->sched_flags |= 1;
+	if (syscall(__NR_sched_setattr, 0, sched_attr, 0))
 		perror_msg_and_skip("sched_setattr");
 
-	printf("sched_setattr\\(0, \\{size=%u, sched_policy=SCHED_[A-Z]+, sched_flags=%s, sched_nice=%u, sched_priority=%u, sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 "\\}, 0\\) += 0\n",
-		sched.attr.size,
-		"SCHED_FLAG_RESET_ON_FORK",
-		sched.attr.sched_nice,
-		sched.attr.sched_priority,
-		sched.attr.sched_runtime,
-		sched.attr.sched_deadline,
-		sched.attr.sched_period);
+	printf("sched_setattr\\(0, \\{size=%u, sched_policy=SCHED_[A-Z]+"
+	       ", sched_flags=%s, sched_nice=%d, sched_priority=%u"
+	       ", sched_runtime=%" PRIu64 ", sched_deadline=%" PRIu64
+	       ", sched_period=%" PRIu64 "\\}, 0\\) += 0\n",
+	       sched_attr->size,
+	       "SCHED_FLAG_RESET_ON_FORK",
+	       sched_attr->sched_nice,
+	       sched_attr->sched_priority,
+	       sched_attr->sched_runtime,
+	       sched_attr->sched_deadline,
+	       sched_attr->sched_period);
+
+	sched_attr->size = 0x90807060;
+	sched_attr->sched_policy = 0xca7faced;
+	sched_attr->sched_flags = 0xbadc0ded1057da7aULL;
+	sched_attr->sched_nice = 0xafbfcfdf;
+	sched_attr->sched_priority = 0xb8c8d8e8;
+	sched_attr->sched_runtime = 0xbadcaffedeadf157ULL;
+	sched_attr->sched_deadline = 0xc0de70a57badac75ULL;
+	sched_attr->sched_period = 0xded1ca7edda7aca7ULL;
+
+	rc = syscall(__NR_sched_setattr, 0xfacec0de, sched_attr, 0xbeeff00d);
+
+	printf("sched_setattr\\(%d, \\{size=%u, "
+		"sched_policy=%#x /\\* SCHED_\\?\\?\\? \\*/, "
+		"sched_flags=%#" PRIx64 " /\\* SCHED_FLAG_\\?\\?\\? \\*/, "
+		"sched_nice=%d, sched_priority=%u, sched_runtime=%" PRIu64 ", "
+		"sched_deadline=%" PRIu64 ", sched_period=%" PRIu64 "\\}, "
+		"%u\\) += %s\n",
+		0xfacec0de, sched_attr->size,
+		sched_attr->sched_policy,
+		sched_attr->sched_flags,
+		sched_attr->sched_nice,
+		sched_attr->sched_priority,
+		sched_attr->sched_runtime,
+		sched_attr->sched_deadline,
+		sched_attr->sched_period, 0xbeeff00d, sprintrc_grep(rc));
 
 	return 0;
 }
diff --git a/tests/sched_xetparam.c b/tests/sched_xetparam.c
index cb30818..e761a9d 100644
--- a/tests/sched_xetparam.c
+++ b/tests/sched_xetparam.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_sched_getparam && defined __NR_sched_setparam
 
diff --git a/tests/sched_xetscheduler.c b/tests/sched_xetscheduler.c
index f86adfa..7faee8c 100644
--- a/tests/sched_xetscheduler.c
+++ b/tests/sched_xetscheduler.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_sched_getscheduler && defined __NR_sched_setscheduler
 
@@ -46,10 +46,29 @@
 	printf("sched_getscheduler(0) = %ld (%s)\n",
 	       rc, scheduler);
 
+	rc = syscall(__NR_sched_getscheduler, -1);
+	printf("sched_getscheduler(-1) = %s\n", sprintrc(rc));
+
 	param->sched_priority = -1;
+
+	rc = syscall(__NR_sched_setscheduler, 0, SCHED_FIFO, NULL);
+	printf("sched_setscheduler(0, SCHED_FIFO, NULL) = %s\n", sprintrc(rc));
+
+	rc = syscall(__NR_sched_setscheduler, 0, SCHED_FIFO, param + 1);
+	printf("sched_setscheduler(0, SCHED_FIFO, %p) = %s\n", param + 1,
+	       sprintrc(rc));
+
+	rc = syscall(__NR_sched_setscheduler, 0, 0xfaceda7a, param);
+	printf("sched_setscheduler(0, %#x /* SCHED_??? */, [%d]) = %s\n",
+	       0xfaceda7a, param->sched_priority, sprintrc(rc));
+
+	rc = syscall(__NR_sched_setscheduler, -1, SCHED_FIFO, param);
+	printf("sched_setscheduler(-1, SCHED_FIFO, [%d]) = %s\n",
+	       param->sched_priority, sprintrc(rc));
+
 	rc = syscall(__NR_sched_setscheduler, 0, SCHED_FIFO, param);
-	printf("sched_setscheduler(0, SCHED_FIFO, [%d]) = %ld %s (%m)\n",
-	       param->sched_priority, rc, errno2name());
+	printf("sched_setscheduler(0, SCHED_FIFO, [%d]) = %s\n",
+	       param->sched_priority, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/sched_yield.c b/tests/sched_yield.c
index ed25722..355e7e8 100644
--- a/tests/sched_yield.c
+++ b/tests/sched_yield.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_sched_yield
 
diff --git a/tests/seccomp-filter-v.c b/tests/seccomp-filter-v.c
index ef69c0d..dbf686d 100644
--- a/tests/seccomp-filter-v.c
+++ b/tests/seccomp-filter-v.c
@@ -32,7 +32,7 @@
 #include <errno.h>
 #include <stddef.h>
 #include <stdio.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <unistd.h>
 
 #ifdef HAVE_PRCTL
diff --git a/tests/seccomp-filter.c b/tests/seccomp-filter.c
index 0326f6e..d4d76dd 100644
--- a/tests/seccomp-filter.c
+++ b/tests/seccomp-filter.c
@@ -30,7 +30,7 @@
 #include "tests.h"
 
 #include <stdio.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <unistd.h>
 
 #ifdef HAVE_LINUX_SECCOMP_H
diff --git a/tests/seccomp-strict.c b/tests/seccomp-strict.c
index c145567..47d909d 100644
--- a/tests/seccomp-strict.c
+++ b/tests/seccomp-strict.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_seccomp && defined __NR_exit
 
diff --git a/tests/select.c b/tests/select.c
index fa551a6..b5ff259 100644
--- a/tests/select.c
+++ b/tests/select.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_select && !defined __NR__newselect
 
diff --git a/tests/semop.c b/tests/semop.c
index 214ce32..f9b7444 100644
--- a/tests/semop.c
+++ b/tests/semop.c
@@ -1,11 +1,14 @@
 #include "tests.h"
-#include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "xlat.h"
+#include "xlat/semop_flags.h"
+
 union semun
 {
 	int val;
@@ -26,6 +29,15 @@
 int
 main(void)
 {
+	static const int bogus_semid = 0xfdb97531;
+	static void * const bogus_sops = (void *) -1L;
+	static const size_t bogus_nsops = (size_t) 0xdefaceddeadbeefULL;
+
+	static const struct timespec ts_data = { 1, 123456789 };
+
+	struct timespec *ts = tail_memdup(&ts_data, sizeof(*ts));
+	int rc;
+
 	id = semget(IPC_PRIVATE, 1, 0600);
 	if (id < 0)
 		perror_msg_and_skip("semget");
@@ -36,10 +48,32 @@
 		perror_msg_and_skip("semctl");
 
 	struct sembuf *const sem_b = tail_alloc(sizeof(*sem_b));
+	struct sembuf *const sem_b2 = tail_alloc(sizeof(*sem_b2));
+
+	rc = semop(bogus_semid, NULL, bogus_nsops);
+	printf("semop(%d, NULL, %u) = %s\n",
+		bogus_semid, (unsigned) bogus_nsops, sprintrc(rc));
+
+	rc = semop(bogus_semid, bogus_sops, 1);
+	printf("semop(%d, %p, %u) = %s\n",
+		bogus_semid, bogus_sops, 1, sprintrc(rc));
+
 	sem_b->sem_num = 0;
 	sem_b->sem_op = 1;
 	sem_b->sem_flg = SEM_UNDO;
 
+	sem_b2->sem_num = 0xface;
+	sem_b2->sem_op = 0xf00d;
+	sem_b2->sem_flg = 0xbeef;
+
+	rc = semop(bogus_semid, sem_b2, 2);
+	printf("semop(%d, [{%hu, %hd, %s%s%#hx}, %p], %u) = %s\n",
+		bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
+		sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
+		sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
+		sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT),
+		sem_b2 + 1, 2, sprintrc(rc));
+
 	if (semop(id, sem_b, 1))
 		perror_msg_and_skip("semop, 1");
 	printf("semop(%d, [{0, 1, SEM_UNDO}], 1) = 0\n", id);
@@ -49,6 +83,36 @@
 		perror_msg_and_skip("semop, -1");
 	printf("semop(%d, [{0, -1, SEM_UNDO}], 1) = 0\n", id);
 
+	rc = semtimedop(bogus_semid, NULL, bogus_nsops, NULL);
+	printf("semtimedop(%d, NULL, %u, NULL) = %s\n",
+		bogus_semid, (unsigned) bogus_nsops, sprintrc(rc));
+
+	rc = semtimedop(id, sem_b + 1, 1, ts + 1);
+	printf("semtimedop(%d, %p, 1, %p) = %s\n",
+		id, sem_b + 1, ts + 1, sprintrc(rc));
+
+	rc = semtimedop(bogus_semid, sem_b2, 2, ts);
+	printf("semtimedop(%d, [{%hu, %hd, %s%s%#hx}, %p], %u, {%jd, %jd}) = "
+		"%s\n",
+		bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
+		sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
+		sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
+		sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT),
+		sem_b2 + 1, 2,
+		(intmax_t) ts->tv_sec, (intmax_t) ts->tv_nsec,
+		sprintrc(rc));
+
+	sem_b->sem_op = 1;
+	if (semtimedop(id, sem_b, 1, NULL))
+		perror_msg_and_skip("semtimedop, 1");
+	printf("semtimedop(%d, [{0, 1, SEM_UNDO}], 1, NULL) = 0\n", id);
+
+	sem_b->sem_op = -1;
+	if (semtimedop(id, sem_b, 1, ts))
+		perror_msg_and_skip("semtimedop, -1");
+	printf("semtimedop(%d, [{0, -1, SEM_UNDO}], 1, {%jd, %jd}) = 0\n", id,
+		(intmax_t) ts->tv_sec, (intmax_t) ts->tv_nsec);
+
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/semop.test b/tests/semop.test
index 7e8f32c..3e77d2f 100755
--- a/tests/semop.test
+++ b/tests/semop.test
@@ -3,4 +3,4 @@
 # Check semop syscall decoding.
 
 . "${srcdir=.}/init.sh"
-run_strace_match_diff -a32
+run_strace_match_diff -a32 -e trace=semop,semtimedop
diff --git a/tests/sendfile.c b/tests/sendfile.c
index b1c7574..61f9212 100644
--- a/tests/sendfile.c
+++ b/tests/sendfile.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_sendfile
 
diff --git a/tests/sendfile64.c b/tests/sendfile64.c
index 7c4a6f5..f757963 100644
--- a/tests/sendfile64.c
+++ b/tests/sendfile64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_sendfile64
 
diff --git a/tests/set_mempolicy.c b/tests/set_mempolicy.c
index e59e89f..3802eaf 100644
--- a/tests/set_mempolicy.c
+++ b/tests/set_mempolicy.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_set_mempolicy
 
@@ -58,7 +58,7 @@
 	memset(nodemask, 0, size);
 
 	long rc = syscall(__NR_set_mempolicy, 0, nodemask, maxnode);
-	int saved_errno = errno;
+	const char *errstr = sprintrc(rc);
 
 	fputs("set_mempolicy(MPOL_DEFAULT, ", stdout);
 
@@ -88,13 +88,7 @@
 			printf("[]");
 	}
 
-	printf(", %lu) = ", maxnode);
-	if (rc) {
-		errno = saved_errno;
-		printf("%ld %s (%m)\n", rc, errno2name());
-	} else {
-		puts("0");
-	}
+	printf(", %lu) = %s\n", maxnode, errstr);
 }
 
 static void
@@ -135,8 +129,8 @@
 	const unsigned long *nodemask = (void *) 0xfacefeedfffffffe;
 	const unsigned long maxnode = (unsigned long) 0xcafef00dbadc0ded;
 	long rc = syscall(__NR_set_mempolicy, 1, nodemask, maxnode);
-	printf("set_mempolicy(MPOL_PREFERRED, %p, %lu) = %ld %s (%m)\n",
-	       nodemask, maxnode, rc, errno2name());
+	printf("set_mempolicy(MPOL_PREFERRED, %p, %lu) = %s\n",
+	       nodemask, maxnode, sprintrc(rc));
 
 	test_offset(0);
 	test_offset(1);
diff --git a/tests/setdomainname.c b/tests/setdomainname.c
index 1d83ffd..f3e2484 100644
--- a/tests/setdomainname.c
+++ b/tests/setdomainname.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setdomainname
 
diff --git a/tests/setfsgid.c b/tests/setfsgid.c
index 9f3a279..871f4b3 100644
--- a/tests/setfsgid.c
+++ b/tests/setfsgid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setfsgid
 
diff --git a/tests/setfsgid32.c b/tests/setfsgid32.c
index 149b767..6279abd 100644
--- a/tests/setfsgid32.c
+++ b/tests/setfsgid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setfsgid32
 
diff --git a/tests/setfsuid.c b/tests/setfsuid.c
index 7c77f50..d6faf97 100644
--- a/tests/setfsuid.c
+++ b/tests/setfsuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setfsuid
 
diff --git a/tests/setfsuid32.c b/tests/setfsuid32.c
index cb72d7c..b71cf23 100644
--- a/tests/setfsuid32.c
+++ b/tests/setfsuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setfsuid32
 
diff --git a/tests/setgid.c b/tests/setgid.c
index aa3f898..8794a0a 100644
--- a/tests/setgid.c
+++ b/tests/setgid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setgid
 
diff --git a/tests/setgid32.c b/tests/setgid32.c
index c9f1221..17f43c5 100644
--- a/tests/setgid32.c
+++ b/tests/setgid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setgid32
 
diff --git a/tests/setgroups.c b/tests/setgroups.c
index 8355301..5068ff4 100644
--- a/tests/setgroups.c
+++ b/tests/setgroups.c
@@ -36,7 +36,7 @@
 #else
 
 # include "tests.h"
-# include <sys/syscall.h>
+# include <asm/unistd.h>
 
 # ifdef __NR_setgroups
 
@@ -61,103 +61,86 @@
 main(void)
 {
 	/* check how the first argument is decoded */
-	if (syscall(SYSCALL_NR, 0, 0))
-		printf("%s(0, NULL) = -1 %s (%m)\n", SYSCALL_NAME, errno2name());
-	else
-		printf("%s(0, NULL) = 0\n", SYSCALL_NAME);
+	long rc = syscall(SYSCALL_NR, 0, 0);
+	printf("%s(0, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
 
-	if (syscall(SYSCALL_NR, (long) 0xffffffff00000000ULL, 0))
-		printf("%s(0, NULL) = -1 %s (%m)\n",
-		       SYSCALL_NAME, errno2name());
-	else
-		printf("%s(0, NULL) = 0\n", SYSCALL_NAME);
+	rc = syscall(SYSCALL_NR, (long) 0xffffffff00000000ULL, 0);
+	printf("%s(0, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
 
-	syscall(SYSCALL_NR, 1, 0);
-	printf("%s(1, NULL) = -1 %s (%m)\n", SYSCALL_NAME, errno2name());
+	rc = syscall(SYSCALL_NR, 1, 0);
+	printf("%s(1, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
 
-	syscall(SYSCALL_NR, (long) 0xffffffff00000001ULL, 0);
-	printf("%s(1, NULL) = -1 %s (%m)\n", SYSCALL_NAME, errno2name());
+	rc = syscall(SYSCALL_NR, (long) 0xffffffff00000001ULL, 0);
+	printf("%s(1, NULL) = %s\n", SYSCALL_NAME, sprintrc(rc));
 
-	syscall(SYSCALL_NR, -1U, 0);
-	printf("%s(%u, NULL) = -1 %s (%m)\n", SYSCALL_NAME, -1U, errno2name());
+	rc = syscall(SYSCALL_NR, -1U, 0);
+	printf("%s(%u, NULL) = %s\n", SYSCALL_NAME, -1U, sprintrc(rc));
 
-	syscall(SYSCALL_NR, -1L, 0);
-	printf("%s(%u, NULL) = -1 %s (%m)\n", SYSCALL_NAME, -1U, errno2name());
+	rc = syscall(SYSCALL_NR, -1L, 0);
+	printf("%s(%u, NULL) = %s\n", SYSCALL_NAME, -1U, sprintrc(rc));
 
 	/* check how the second argument is decoded */
 	const GID_TYPE *const g1 = tail_alloc(sizeof(*g1));
 	GID_TYPE *const g2 = tail_alloc(sizeof(*g2) * 2);
 	GID_TYPE *const g3 = tail_alloc(sizeof(*g3) * 3);
 
-	if (syscall(SYSCALL_NR, 0, g1 + 1))
-		printf("%s(0, []) = -1 %s (%m)\n",
-		       SYSCALL_NAME, errno2name());
-	else
-		printf("%s(0, []) = 0\n", SYSCALL_NAME);
+	rc = syscall(SYSCALL_NR, 0, g1 + 1);
+	printf("%s(0, []) = %s\n", SYSCALL_NAME, sprintrc(rc));
 
-	if (syscall(SYSCALL_NR, 1, g1))
-		printf("%s(1, [%u]) = -1 %s (%m)\n",
-		       SYSCALL_NAME, (unsigned) *g1, errno2name());
-	else
-		printf("%s(1, [%u]) = 0\n",
-		       SYSCALL_NAME, (unsigned) *g1);
+	rc = syscall(SYSCALL_NR, 1, g1);
+	printf("%s(1, [%u]) = %s\n",
+	       SYSCALL_NAME, (unsigned) *g1, sprintrc(rc));
 
-	syscall(SYSCALL_NR, 1, g1 + 1);
-	printf("%s(1, %p) = -1 %s (%m)\n",
-	       SYSCALL_NAME, g1 + 1, errno2name());
+	rc = syscall(SYSCALL_NR, 1, g1 + 1);
+	printf("%s(1, %p) = %s\n", SYSCALL_NAME, g1 + 1, sprintrc(rc));
 
-	syscall(SYSCALL_NR, 1, -1L);
-	printf("%s(1, %#lx) = -1 %s (%m)\n", SYSCALL_NAME, -1L, errno2name());
+	rc = syscall(SYSCALL_NR, 1, -1L);
+	printf("%s(1, %#lx) = %s\n", SYSCALL_NAME, -1L, sprintrc(rc));
 
-	syscall(SYSCALL_NR, 2, g1);
-	printf("%s(2, [%u, %p]) = -1 %s (%m)\n",
-	       SYSCALL_NAME, (unsigned) *g1, g1 + 1, errno2name());
+	rc = syscall(SYSCALL_NR, 2, g1);
+	printf("%s(2, [%u, %p]) = %s\n",
+	       SYSCALL_NAME, (unsigned) *g1, g1 + 1, sprintrc(rc));
 
 	g2[0] = -2;
 	g2[1] = -3;
-	if (syscall(SYSCALL_NR, 2, g2))
-		printf("%s(2, [%u, %u]) = -1 %s (%m)\n", SYSCALL_NAME,
-		       (unsigned) g2[0], (unsigned) g2[1], errno2name());
-	else
-		printf("%s(2, [%u, %u]) = 0\n", SYSCALL_NAME,
-		       (unsigned) g2[0], (unsigned) g2[1]);
+	rc = syscall(SYSCALL_NR, 2, g2);
+	printf("%s(2, [%u, %u]) = %s\n", SYSCALL_NAME,
+	       (unsigned) g2[0], (unsigned) g2[1], sprintrc(rc));
 
-	syscall(SYSCALL_NR, 3, g2);
-	printf("%s(3, [%u, %u, %p]) = -1 %s (%m)\n", SYSCALL_NAME,
-	       (unsigned) g2[0], (unsigned) g2[1], g2 + 2, errno2name());
+	rc = syscall(SYSCALL_NR, 3, g2);
+	printf("%s(3, [%u, %u, %p]) = %s\n", SYSCALL_NAME,
+	       (unsigned) g2[0], (unsigned) g2[1], g2 + 2, sprintrc(rc));
 
 	g3[0] = 0;
 	g3[1] = 1;
-	if (syscall(SYSCALL_NR, 3, g3))
-		printf("%s(3, [%u, %u, ...]) = -1 %s (%m)\n", SYSCALL_NAME,
-		       (unsigned) g3[0], (unsigned) g3[1], errno2name());
-	else
-		printf("%s(3, [%u, %u]) = 0\n", SYSCALL_NAME,
-		       (unsigned) g3[0], (unsigned) g3[1]);
+	rc = syscall(SYSCALL_NR, 3, g3);
+	printf("%s(3, [%u, %u%s]) = %s\n", SYSCALL_NAME,
+	       (unsigned) g3[0], (unsigned) g3[1], rc ? ", ..." : "",
+	       sprintrc(rc));
 
-	syscall(SYSCALL_NR, 4, g3);
-	printf("%s(4, [%u, %u, ...]) = -1 %s (%m)\n", SYSCALL_NAME,
-	       (unsigned) g3[0], (unsigned) g3[1], errno2name());
+	rc = syscall(SYSCALL_NR, 4, g3);
+	printf("%s(4, [%u, %u, ...]) = %s\n", SYSCALL_NAME,
+	       (unsigned) g3[0], (unsigned) g3[1], sprintrc(rc));
 
-	long rc = sysconf(_SC_NGROUPS_MAX);
+	rc = sysconf(_SC_NGROUPS_MAX);
 	const unsigned ngroups_max = rc;
 
 	if ((unsigned long) rc == ngroups_max && (int) ngroups_max > 0) {
-		syscall(SYSCALL_NR, ngroups_max, g3);
-		printf("%s(%u, [%u, %u, ...]) = -1 %s (%m)\n", SYSCALL_NAME,
+		rc = syscall(SYSCALL_NR, ngroups_max, g3);
+		printf("%s(%u, [%u, %u, ...]) = %s\n", SYSCALL_NAME,
 		       ngroups_max, (unsigned) g3[0], (unsigned) g3[1],
-		       errno2name());
+		       sprintrc(rc));
 
 		const unsigned long size =
 			(unsigned long) 0xffffffff00000000ULL | ngroups_max;
-		syscall(SYSCALL_NR, size, g3);
-		printf("%s(%u, [%u, %u, ...]) = -1 %s (%m)\n", SYSCALL_NAME,
+		rc = syscall(SYSCALL_NR, size, g3);
+		printf("%s(%u, [%u, %u, ...]) = %s\n", SYSCALL_NAME,
 		       ngroups_max, (unsigned) g3[0], (unsigned) g3[1],
-		       errno2name());
+		       sprintrc(rc));
 
-		syscall(SYSCALL_NR, ngroups_max + 1, g3);
-		printf("%s(%u, %p) = -1 %s (%m)\n", SYSCALL_NAME,
-		       ngroups_max + 1, g3, errno2name());
+		rc = syscall(SYSCALL_NR, ngroups_max + 1, g3);
+		printf("%s(%u, %p) = %s\n", SYSCALL_NAME,
+		       ngroups_max + 1, g3, sprintrc(rc));
 	}
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/setgroups32.c b/tests/setgroups32.c
index bd0a1fd..ecf00bb 100644
--- a/tests/setgroups32.c
+++ b/tests/setgroups32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setgroups32
 
diff --git a/tests/sethostname.c b/tests/sethostname.c
index 65d0a78..dfa9d1a 100644
--- a/tests/sethostname.c
+++ b/tests/sethostname.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_sethostname
 
diff --git a/tests/setregid.c b/tests/setregid.c
index 6efa388..e1da786 100644
--- a/tests/setregid.c
+++ b/tests/setregid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setregid
 
diff --git a/tests/setregid32.c b/tests/setregid32.c
index 0d0ebed..3cf0daf 100644
--- a/tests/setregid32.c
+++ b/tests/setregid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setregid32
 
diff --git a/tests/setresgid.c b/tests/setresgid.c
index 6754c2f..8701df8 100644
--- a/tests/setresgid.c
+++ b/tests/setresgid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setresgid
 
diff --git a/tests/setresgid32.c b/tests/setresgid32.c
index 29a8042..dfce457 100644
--- a/tests/setresgid32.c
+++ b/tests/setresgid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setresgid32
 
diff --git a/tests/setresuid.c b/tests/setresuid.c
index b924f91..3a9dbd1 100644
--- a/tests/setresuid.c
+++ b/tests/setresuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setresuid
 
diff --git a/tests/setresuid32.c b/tests/setresuid32.c
index d4187dd..387268a 100644
--- a/tests/setresuid32.c
+++ b/tests/setresuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setresuid32
 
diff --git a/tests/setreuid.c b/tests/setreuid.c
index dc13038..68e7519 100644
--- a/tests/setreuid.c
+++ b/tests/setreuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setreuid
 
diff --git a/tests/setreuid32.c b/tests/setreuid32.c
index 43b7b91..ba01762 100644
--- a/tests/setreuid32.c
+++ b/tests/setreuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setreuid32
 
diff --git a/tests/setrlimit.c b/tests/setrlimit.c
index b5a14c6..95dd898 100644
--- a/tests/setrlimit.c
+++ b/tests/setrlimit.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setrlimit
 
@@ -43,8 +43,7 @@
 	for (xlat = resources; xlat->str; ++xlat) {
 		unsigned long res = 0xfacefeed00000000 | xlat->val;
 		long rc = syscall(__NR_setrlimit, res, 0);
-		printf("setrlimit(%s, NULL) = %ld %s (%m)\n",
-		       xlat->str, rc, errno2name());
+		printf("setrlimit(%s, NULL) = %s\n", xlat->str, sprintrc(rc));
 
 		struct rlimit libc_rlim = {};
 		if (getrlimit((int) res, &libc_rlim))
@@ -53,16 +52,11 @@
 		rlimit[1] = libc_rlim.rlim_max;
 
 		rc = syscall(__NR_setrlimit, res, rlimit);
-		int saved_errno = errno;
-		printf("setrlimit(%s, {rlim_cur=%s, rlim_max=%s})",
+		const char *errstr = sprintrc(rc);
+		printf("setrlimit(%s, {rlim_cur=%s, rlim_max=%s}) = %s\n",
 		       xlat->str,
-		       sprint_rlim(rlimit[0]), sprint_rlim(rlimit[1]));
-		if (rc) {
-			errno = saved_errno;
-			printf(" = %ld %s (%m)\n", rc, errno2name());
-		} else {
-			printf(" = 0\n");
-		}
+		       sprint_rlim(rlimit[0]), sprint_rlim(rlimit[1]),
+		       errstr);
 	}
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/setuid.c b/tests/setuid.c
index c9e97e0..df2e46b 100644
--- a/tests/setuid.c
+++ b/tests/setuid.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setuid
 
diff --git a/tests/setuid32.c b/tests/setuid32.c
index 9247cb2..c837d54 100644
--- a/tests/setuid32.c
+++ b/tests/setuid32.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_setuid32
 
diff --git a/tests/shmxt.c b/tests/shmxt.c
index 8e087f3..23cc7cc 100644
--- a/tests/shmxt.c
+++ b/tests/shmxt.c
@@ -21,11 +21,23 @@
 int
 main(void)
 {
+	static const int bogus_shmid = 0xfdb97531;
+	static const void * const bogus_shmaddr =
+		(void *) (unsigned long) 0xdec0ded1dec0ded2ULL;
+	static const int bogus_shmflg = 0xffffface;
+
+	long rc;
+
 	id = shmget(IPC_PRIVATE, 1, 0600);
 	if (id < 0)
 		perror_msg_and_skip("shmget");
 	atexit(cleanup);
 
+	rc = (long) shmat(bogus_shmid, bogus_shmaddr, bogus_shmflg);
+	printf("%s(%d, %p, SHM_REMAP|SHM_RDONLY|SHM_RND|%#x) = %s\n",
+	       SHMAT, bogus_shmid, bogus_shmaddr, bogus_shmflg & ~0x7000,
+	       sprintrc(rc));
+
 	shmat(id, NULL, SHM_REMAP);
 	printf("%s(%d, NULL, SHM_REMAP) = -1 %s (%m)\n",
 	       SHMAT, id, errno2name());
@@ -35,6 +47,9 @@
 		perror_msg_and_skip("shmat SHM_RDONLY");
 	printf("%s(%d, NULL, SHM_RDONLY) = %p\n", SHMAT, id, shmaddr);
 
+	rc = shmdt(NULL);
+	printf("shmdt(NULL) = %s\n", sprintrc(rc));
+
 	if (shmdt(shmaddr))
 		perror_msg_and_skip("shmdt");
 	printf("shmdt(%p) = 0\n", shmaddr);
diff --git a/tests/siginfo.c b/tests/siginfo.c
index 48cfaf3..2ecb13f 100644
--- a/tests/siginfo.c
+++ b/tests/siginfo.c
@@ -86,7 +86,8 @@
 		", si_pid=%d, si_uid=%u, si_status=%d"
 		", si_utime=%llu, si_stime=%llu} ---\n",
 		sinfo.si_pid, sinfo.si_uid, sinfo.si_status,
-		widen_to_ull(sinfo.si_utime), widen_to_ull(sinfo.si_stime));
+		zero_extend_signed_to_ull(sinfo.si_utime),
+		zero_extend_signed_to_ull(sinfo.si_stime));
 
 	int s;
 	assert(wait(&s) == pid);
@@ -116,7 +117,8 @@
 		", si_pid=%d, si_uid=%u, si_status=SIGUSR1"
 		", si_utime=%llu, si_stime=%llu} ---\n",
 		sinfo.si_pid, sinfo.si_uid,
-		widen_to_ull(sinfo.si_utime), widen_to_ull(sinfo.si_stime));
+		zero_extend_signed_to_ull(sinfo.si_utime),
+		zero_extend_signed_to_ull(sinfo.si_stime));
 
 	assert(wait(&s) == pid);
 	assert(WIFSIGNALED(s) && WTERMSIG(s) == SIGUSR1);
@@ -142,7 +144,8 @@
 		", si_pid=%d, si_uid=%u, si_status=SIGSTOP"
 		", si_utime=%llu, si_stime=%llu} ---\n",
 		sinfo.si_pid, sinfo.si_uid,
-		widen_to_ull(sinfo.si_utime), widen_to_ull(sinfo.si_stime));
+		zero_extend_signed_to_ull(sinfo.si_utime),
+		zero_extend_signed_to_ull(sinfo.si_stime));
 
 	assert(kill(pid, SIGCONT) == 0);
 
@@ -151,7 +154,8 @@
 		", si_pid=%d, si_uid=%u, si_status=SIGCONT"
 		", si_utime=%llu, si_stime=%llu} ---\n",
 		sinfo.si_pid, sinfo.si_uid,
-		widen_to_ull(sinfo.si_utime), widen_to_ull(sinfo.si_stime));
+		zero_extend_signed_to_ull(sinfo.si_utime),
+		zero_extend_signed_to_ull(sinfo.si_stime));
 
 	assert(write(1, "", 1) == 1);
 	(void) close(1);
@@ -161,7 +165,8 @@
 		", si_pid=%d, si_uid=%u, si_status=0"
 		", si_utime=%llu, si_stime=%llu} ---\n",
 		sinfo.si_pid, sinfo.si_uid,
-		widen_to_ull(sinfo.si_utime), widen_to_ull(sinfo.si_stime));
+		zero_extend_signed_to_ull(sinfo.si_utime),
+		zero_extend_signed_to_ull(sinfo.si_stime));
 
 	assert(wait(&s) == pid && s == 0);
 
diff --git a/tests/signalfd.expected b/tests/signalfd.expected
deleted file mode 100644
index 21937bc..0000000
--- a/tests/signalfd.expected
+++ /dev/null
@@ -1 +0,0 @@
-signalfd4\(-1, \[(USR2 CHLD|CHLD USR2)\], (4|8|16), SFD_CLOEXEC\|SFD_NONBLOCK\) += 0
diff --git a/tests/signalfd.test b/tests/signalfd.test
deleted file mode 100755
index dcbfe68..0000000
--- a/tests/signalfd.test
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-# Check signalfd4 syscall decoding.
-
-. "${srcdir=.}/init.sh"
-
-run_prog
-run_strace -e signalfd4 $args
-match_grep
-
-exit 0
diff --git a/tests/signalfd.c b/tests/signalfd4.c
similarity index 64%
copy from tests/signalfd.c
copy to tests/signalfd4.c
index 7b1d6ce..47e49b5 100644
--- a/tests/signalfd.c
+++ b/tests/signalfd4.c
@@ -1,4 +1,6 @@
 /*
+ * Check decoding of signalfd4 syscall.
+ *
  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
  * All rights reserved.
  *
@@ -27,28 +29,58 @@
 
 #include "tests.h"
 #include <fcntl.h>
+#include <asm/unistd.h>
 
-#if defined HAVE_SYS_SIGNALFD_H && defined HAVE_SIGNALFD && defined O_CLOEXEC
+#if defined __NR_rt_sigprocmask \
+ && defined HAVE_SYS_SIGNALFD_H \
+ && defined HAVE_SIGNALFD \
+ && defined O_CLOEXEC
 
 # include <signal.h>
+# include <stdio.h>
 # include <unistd.h>
 # include <sys/signalfd.h>
 
+static unsigned int
+get_sigset_size(void)
+{
+	const unsigned int big_size = 1024 / 8;
+	unsigned int set_size;
+
+	for (set_size = big_size; set_size; set_size >>= 1) {
+		if (!syscall(__NR_rt_sigprocmask, SIG_SETMASK,
+			     NULL, NULL, set_size))
+			break;
+	}
+
+	if (!set_size)
+		perror_msg_and_fail("rt_sigprocmask");
+
+	return set_size;
+}
+
 int
 main(void)
 {
+	const char *const sigs = SIGUSR2 < SIGCHLD ? "USR2 CHLD" : "CHLD USR2";
+	const unsigned int size = get_sigset_size();
+
 	sigset_t mask;
 	sigemptyset(&mask);
 	sigaddset(&mask, SIGUSR2);
 	sigaddset(&mask, SIGCHLD);
-	(void) close(0);
-	if (signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK))
-		perror_msg_and_skip("signalfd");
+
+	int fd = signalfd(-1, &mask, O_CLOEXEC | O_NONBLOCK);
+	printf("signalfd4(-1, [%s], %u, SFD_CLOEXEC|SFD_NONBLOCK) = %s\n",
+	       sigs, size, sprintrc(fd));
+
+	puts("+++ exited with 0 +++");
 	return 0;
 }
 
 #else
 
-SKIP_MAIN_UNDEFINED("HAVE_SYS_SIGNALFD_H && HAVE_SIGNALFD && O_CLOEXEC")
+SKIP_MAIN_UNDEFINED("__NR_rt_sigprocmask && HAVE_SYS_SIGNALFD_H"
+		    " && HAVE_SIGNALFD && O_CLOEXEC")
 
 #endif
diff --git a/tests/signalfd4.test b/tests/signalfd4.test
new file mode 100755
index 0000000..a615a5b
--- /dev/null
+++ b/tests/signalfd4.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check decoding of signalfd4 syscall.
+
+. "${srcdir=.}/init.sh"
+run_strace_match_diff
diff --git a/tests/socketcall.c b/tests/socketcall.c
index 5ccddc4..d2ec959 100644
--- a/tests/socketcall.c
+++ b/tests/socketcall.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_socketcall
 
diff --git a/tests/sockname.c b/tests/sockname.c
index 56a8a36..c5072ca 100644
--- a/tests/sockname.c
+++ b/tests/sockname.c
@@ -101,26 +101,22 @@
 
 	PREPARE_TEST_SYSCALL_INVOCATION;
 	rc = TEST_SYSCALL_NAME(fd PREFIX_F_ARGS, (void *) addr, 0 SUFFIX_ARGS);
-	printf("%s(%d%s, %p, NULL%s) = %d %s (%m)\n",
-	       TEST_SYSCALL_STR, fd, PREFIX_F_STR, addr, SUFFIX_STR, rc,
-	       errno2name());
+	printf("%s(%d%s, %p, NULL%s) = %s\n",
+	       TEST_SYSCALL_STR, fd, PREFIX_F_STR, addr, SUFFIX_STR,
+	       sprintrc(rc));
 
 	PREPARE_TEST_SYSCALL_INVOCATION;
 	rc = TEST_SYSCALL_NAME(fd PREFIX_S_ARGS, 0, 0 SUFFIX_ARGS);
-	if (rc < 0)
-		printf("%s(%d%s, NULL, NULL%s) = %d %s (%m)\n",
-		       TEST_SYSCALL_STR, fd, PREFIX_F_STR, SUFFIX_STR, rc,
-		       errno2name());
-	else
-		printf("%s(%d%s, NULL, NULL%s) = %d\n",
-		       TEST_SYSCALL_STR, fd, PREFIX_S_STR, SUFFIX_STR, rc);
+	printf("%s(%d%s, NULL, NULL%s) = %s\n",
+	       TEST_SYSCALL_STR, fd, rc == -1 ? PREFIX_F_STR : PREFIX_S_STR,
+	       SUFFIX_STR, sprintrc(rc));
 
 	PREPARE_TEST_SYSCALL_INVOCATION;
 	rc = TEST_SYSCALL_NAME(fd PREFIX_F_ARGS, (void *) addr,
 			       plen + 1 SUFFIX_ARGS);
-	printf("%s(%d%s, %p, %p%s) = %d %s (%m)\n",
+	printf("%s(%d%s, %p, %p%s) = %s\n",
 	       TEST_SYSCALL_STR, fd, PREFIX_F_STR, addr,
-	       plen + 1, SUFFIX_STR, rc, errno2name());
+	       plen + 1, SUFFIX_STR, sprintrc(rc));
 
 	const size_t offsetof_sun_path = offsetof(struct sockaddr_un, sun_path);
 	*plen = offsetof_sun_path;
@@ -154,7 +150,7 @@
 	PREPARE_TEST_SYSCALL_INVOCATION;
 	rc = TEST_SYSCALL_NAME(fd PREFIX_F_ARGS, (void *) addr,
 			       plen SUFFIX_ARGS);
-	printf("%s(%d%s, %p, [%d]%s) = %d %s (%m)\n",
+	printf("%s(%d%s, %p, [%d]%s) = %s\n",
 	       TEST_SYSCALL_STR, fd, PREFIX_F_STR, addr,
-	       *plen, SUFFIX_STR, rc, errno2name());
+	       *plen, SUFFIX_STR, sprintrc(rc));
 }
diff --git a/tests/splice.c b/tests/splice.c
index 433cf7f..5a89910 100644
--- a/tests/splice.c
+++ b/tests/splice.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_splice
 
diff --git a/tests/sprintrc.c b/tests/sprintrc.c
new file mode 100644
index 0000000..a573a27
--- /dev/null
+++ b/tests/sprintrc.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016 Eugene Syromiatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <stdio.h>
+
+enum sprintrc_fmt {
+	SPRINTRC_FMT_RAW,
+	SPRINTRC_FMT_GREP,
+};
+
+/**
+ * Provides pointer to static string buffer with printed return code in format
+ * used by strace - with errno and error message.
+ *
+ * @param rc  Return code.
+ * @param fmt Output format. Currently, raw (used for diff matching) and grep
+ *            (for extended POSIX regex-based pattern matching) formats are
+ *            supported.
+ * @return    Pointer to (statically allocated) buffer containing decimal
+ *            representation of return code and errno/error message in case @rc
+ *            is equal to -1.
+ */
+static inline const char *
+sprintrc_ex(long rc, enum sprintrc_fmt fmt)
+{
+	static const char *formats[] = {
+		[SPRINTRC_FMT_RAW] = "-1 %s (%m)",
+		[SPRINTRC_FMT_GREP] = "-1 %s \\(%m\\)",
+	};
+	static char buf[4096];
+
+	if (fmt >= ARRAY_SIZE(formats))
+		perror_msg_and_fail("sprintrc_ex: incorrect format provided");
+
+	if (rc == 0)
+		return "0";
+
+	int ret = (rc == -1)
+		? snprintf(buf, sizeof(buf), formats[fmt], errno2name())
+		: snprintf(buf, sizeof(buf), "%ld", rc);
+
+	if (ret < 0)
+		perror_msg_and_fail("snprintf");
+	if ((size_t) ret >= sizeof(buf))
+		error_msg_and_fail("snprintf overflow: got %d, expected"
+				   " no more than %zu", ret, sizeof(buf));
+
+	return buf;
+}
+
+const char *
+sprintrc(long rc)
+{
+	return sprintrc_ex(rc, SPRINTRC_FMT_RAW);
+}
+
+const char *
+sprintrc_grep(long rc)
+{
+	return sprintrc_ex(rc, SPRINTRC_FMT_GREP);
+}
diff --git a/tests/stat.c b/tests/stat.c
index f64ff30..df6cab1 100644
--- a/tests/stat.c
+++ b/tests/stat.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_stat
 
diff --git a/tests/stat64.c b/tests/stat64.c
index c164189..4c2101b 100644
--- a/tests/stat64.c
+++ b/tests/stat64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_stat64
 
@@ -34,6 +34,7 @@
 # define TEST_SYSCALL_STR "stat64"
 # define STRUCT_STAT struct stat64
 # define STRUCT_STAT_STR "struct stat64"
+# define STRUCT_STAT_IS_STAT64 1
 # define SAMPLE_SIZE ((libc_off_t) 43147718418)
 # include "lstatx.c"
 
diff --git a/tests/statfs.c b/tests/statfs.c
index 5a87afc..6032a66 100644
--- a/tests/statfs.c
+++ b/tests/statfs.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_statfs
 
diff --git a/tests/statfs64.c b/tests/statfs64.c
index b85dce2..f46e767 100644
--- a/tests/statfs64.c
+++ b/tests/statfs64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_statfs64
 
diff --git a/tests/strace-S.test b/tests/strace-S.test
index 44c15cc..3ea315c 100755
--- a/tests/strace-S.test
+++ b/tests/strace-S.test
@@ -14,7 +14,7 @@
 	sedexpr="$1"; shift
 
 	run_strace -c -w -S "$sortby" ./readv > /dev/null
-	sed -ne "$sedexpr" < "$LOG" > "$OUT"
+	sed -r -n -e "$sedexpr" < "$LOG" > "$OUT"
 
 	[ -s "$OUT" ] ||
 		fail_ "$STRACE $args output mismatch"
@@ -25,8 +25,8 @@
 	}
 }
 
-c='[[:space:]]\+\([^[:space:]]\+\)'
-test_c calls '-n -r' '/^[[:space:]]\+[0-9]/ s/^'"$c$c$c$c"'[[:space:]].*/\4/p'
-test_c name '' '/^[[:space:]]\+[0-9]/ s/^'"$c$c$c$c"'\([[:space:]]\+[0-9]\+\)\?'"$c"'$/\6/p'
+c='[[:space:]]+([^[:space:]]+)'
+test_c calls '-n -r' '/^[[:space:]]+[0-9]/ s/^'"$c$c$c$c"'[[:space:]].*/\4/p'
+test_c name '' '/^[[:space:]]+[0-9]/ s/^'"$c$c$c$c"'([[:space:]]+[0-9]+)?'"$c"'$/\6/p'
 
 rm -f "$OUT"
diff --git a/tests/strace-V.test b/tests/strace-V.test
index 91093ac..d441371 100755
--- a/tests/strace-V.test
+++ b/tests/strace-V.test
@@ -8,7 +8,7 @@
 
 getval()
 {
-	sed -n 's/#define[[:space:]]*'"$1"'[[:space:]]*"\([^"]*\)".*/\1/p' ../config.h
+	sed -r -n 's/#define[[:space:]]*'"$1"'[[:space:]]*"([^"]*)".*/\1/p' ../config.h
 }
 
 printf "%s -- version %s\n" "$(getval PACKAGE_NAME)" "$(getval VERSION)" > "$EXP"
diff --git a/tests/strace-k.test b/tests/strace-k.test
index 5919bac..d5e8ed2 100755
--- a/tests/strace-k.test
+++ b/tests/strace-k.test
@@ -41,7 +41,7 @@
 run_strace -e getpid -k $args
 
 expected='getpid f3 f2 f1 f0 main '
-result=$(sed -n '1,/(main+0x[a-f0-9]\+) .*/ s/^.*(\([^+]\+\)+0x[a-f0-9]\+) .*/\1/p' "$LOG" |
+result=$(sed -r -n '1,/\(main\+0x[a-f0-9]+\) .*/ s/^.*\(([^+]+)\+0x[a-f0-9]+\) .*/\1/p' "$LOG" |
 	tr '\n' ' ')
 
 test "$result" = "$expected" || {
diff --git a/tests/swap.c b/tests/swap.c
index 065af4d..ed8cec8 100644
--- a/tests/swap.c
+++ b/tests/swap.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_swapon && defined __NR_swapoff
 
diff --git a/tests/symlink.c b/tests/symlink.c
index 44c5655..72cb490 100644
--- a/tests/symlink.c
+++ b/tests/symlink.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_symlink
 
diff --git a/tests/symlinkat.c b/tests/symlinkat.c
index 3dfdd80..d0116d0 100644
--- a/tests/symlinkat.c
+++ b/tests/symlinkat.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_symlinkat
 
diff --git a/tests/sync.c b/tests/sync.c
index 132a6f2..e6e7ce3 100644
--- a/tests/sync.c
+++ b/tests/sync.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_sync
 
diff --git a/tests/sync_file_range.c b/tests/sync_file_range.c
index 9426e3c..aadef68 100644
--- a/tests/sync_file_range.c
+++ b/tests/sync_file_range.c
@@ -29,7 +29,7 @@
 
 #include "tests.h"
 #include <fcntl.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined HAVE_SYNC_FILE_RANGE && defined __NR_sync_file_range
 
diff --git a/tests/sync_file_range2.c b/tests/sync_file_range2.c
index d19cf25..6ce7db2 100644
--- a/tests/sync_file_range2.c
+++ b/tests/sync_file_range2.c
@@ -29,7 +29,7 @@
 
 #include "tests.h"
 #include <fcntl.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined HAVE_SYNC_FILE_RANGE && defined  __NR_sync_file_range2
 
diff --git a/tests/syslog.c b/tests/syslog.c
index 8c68298..d4d4a7b 100644
--- a/tests/syslog.c
+++ b/tests/syslog.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_syslog
 
diff --git a/tests/tee.c b/tests/tee.c
index f36f92a..eb562c7 100644
--- a/tests/tee.c
+++ b/tests/tee.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_tee
 
diff --git a/tests/tests.h b/tests/tests.h
index e0bf228..f3ddc85 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -25,8 +25,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef TESTS_H_
-# define TESTS_H_
+#ifndef STRACE_TESTS_H
+#define STRACE_TESTS_H
 
 # ifdef HAVE_CONFIG_H
 #  include "config.h"
@@ -35,6 +35,11 @@
 # include <sys/types.h>
 # include "gcc_compat.h"
 
+/* Tests of "strace -v" are expected to define VERBOSE to 1. */
+#ifndef VERBOSE
+# define VERBOSE 0
+#endif
+
 /* Cached sysconf(_SC_PAGESIZE). */
 size_t get_page_size(void);
 
@@ -99,6 +104,11 @@
 /* Translate signal number to its name. */
 const char *signal2name(int);
 
+/* Print return code and, in case return code is -1, errno information. */
+const char *sprintrc(long rc);
+/* sprintrc variant suitable for usage as part of grep pattern. */
+const char *sprintrc_grep(long rc);
+
 struct xlat;
 
 /* Print flags in symbolic form according to xlat table. */
@@ -120,14 +130,22 @@
 # define ARRAY_SIZE(arg) ((unsigned int) (sizeof(arg) / sizeof((arg)[0])))
 # define LENGTH_OF(arg) ((unsigned int) sizeof(arg) - 1)
 
-/*
- * Widen without sign-extension a signed integer type to unsigned long long.
- */
-#define widen_to_ull(v) \
-	(sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
+/* Zero-extend a signed integer type to unsigned long long. */
+#define zero_extend_signed_to_ull(v) \
+	(sizeof(v) == sizeof(char) ? (unsigned long long) (unsigned char) (v) : \
+	 sizeof(v) == sizeof(short) ? (unsigned long long) (unsigned short) (v) : \
+	 sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
 	 sizeof(v) == sizeof(long) ? (unsigned long long) (unsigned long) (v) : \
 	 (unsigned long long) (v))
 
+/* Sign-extend an unsigned integer type to long long. */
+#define sign_extend_unsigned_to_ll(v) \
+	(sizeof(v) == sizeof(char) ? (long long) (char) (v) : \
+	 sizeof(v) == sizeof(short) ? (long long) (short) (v) : \
+	 sizeof(v) == sizeof(int) ? (long long) (int) (v) : \
+	 sizeof(v) == sizeof(long) ? (long long) (long) (v) : \
+	 (long long) (v))
+
 # define SKIP_MAIN_UNDEFINED(arg) \
 	int main(void) { error_msg_and_skip("undefined: %s", arg); }
 
@@ -151,4 +169,4 @@
 # define PRI__u64 PRI__64"u"
 # define PRI__x64 PRI__64"x"
 
-#endif
+#endif /* !STRACE_TESTS_H */
diff --git a/tests/time.c b/tests/time.c
index 041b011..4a5cde9 100644
--- a/tests/time.c
+++ b/tests/time.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_time
 
diff --git a/tests/timer_create.c b/tests/timer_create.c
index ff924d3..6f98f36 100644
--- a/tests/timer_create.c
+++ b/tests/timer_create.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_timer_create
 
diff --git a/tests/timer_xettime.c b/tests/timer_xettime.c
index 7c691c6..877f717 100644
--- a/tests/timer_xettime.c
+++ b/tests/timer_xettime.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_timer_create \
  && defined __NR_timer_gettime \
@@ -59,6 +59,10 @@
 		struct itimerspec its;
 		uint32_t pad[4];
 	} old = {
+		.its = {
+			.it_interval = { 0xdeface5, 0xdeface6 },
+			.it_value = { 0xdeface7, 0xdeface8 }
+		},
 		.pad = { 0xdeadbeef, 0xbadc0ded, 0xdeadbeef, 0xbadc0ded }
 	}, new = {
 		.its = {
diff --git a/tests/timerfd_xettime.c b/tests/timerfd_xettime.c
index f97c1db..2742ec2 100644
--- a/tests/timerfd_xettime.c
+++ b/tests/timerfd_xettime.c
@@ -27,7 +27,7 @@
 
 #include "tests.h"
 #include <fcntl.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_timerfd_create \
  && defined __NR_timerfd_gettime \
@@ -51,6 +51,10 @@
 		struct itimerspec its;
 		uint32_t pad[4];
 	} old = {
+		.its = {
+			.it_interval = { 0xdeface5, 0xdeface6 },
+			.it_value = { 0xdeface7, 0xdeface8 }
+		},
 		.pad = { 0xdeadbeef, 0xbadc0ded, 0xdeadbeef, 0xbadc0ded }
 	}, new = {
 		.its = {
diff --git a/tests/times-fail.c b/tests/times-fail.c
index 5f5277c..cb69bd4 100644
--- a/tests/times-fail.c
+++ b/tests/times-fail.c
@@ -2,7 +2,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 int
 main (void)
diff --git a/tests/times.c b/tests/times.c
index 6c76dbc..18b209b 100644
--- a/tests/times.c
+++ b/tests/times.c
@@ -38,7 +38,7 @@
 #include <time.h>
 #include <unistd.h>
 
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <sys/times.h>
 #include <sys/wait.h>
 
diff --git a/tests/truncate.c b/tests/truncate.c
index c3ad2ba..3f16aef 100644
--- a/tests/truncate.c
+++ b/tests/truncate.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_truncate
 
diff --git a/tests/truncate64.c b/tests/truncate64.c
index c973c45..c4a524d 100644
--- a/tests/truncate64.c
+++ b/tests/truncate64.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_truncate64
 
diff --git a/tests/ugetrlimit.c b/tests/ugetrlimit.c
index dc24bb8..a99e496 100644
--- a/tests/ugetrlimit.c
+++ b/tests/ugetrlimit.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_ugetrlimit
 
diff --git a/tests/umask.c b/tests/umask.c
index 2dcea28..86903a9 100644
--- a/tests/umask.c
+++ b/tests/umask.c
@@ -1,11 +1,23 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
+void
+test_umask(const mode_t mode)
+{
+	mode_t rc = umask(0xffff0000 | mode);
+	printf("umask(%#03ho) = %#03o\n", (unsigned short) mode, rc);
+}
+
 int
 main(void)
 {
-	mode_t rc = umask(044);
-	printf("umask(%#o) = %#o\n", 044, rc);
+	test_umask(0);
+	test_umask(06);
+	test_umask(026);
+	test_umask(0126);
+	test_umask(07777);
+	test_umask(0107777);
+	test_umask(-1);
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/umode_t.c b/tests/umode_t.c
new file mode 100644
index 0000000..7ab27dc
--- /dev/null
+++ b/tests/umode_t.c
@@ -0,0 +1,78 @@
+/*
+ * Check decoding of umode_t type syscall arguments.
+ *
+ * Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#ifndef TEST_SYSCALL_PREFIX_ARGS
+# define TEST_SYSCALL_PREFIX_ARGS
+#endif
+#ifndef TEST_SYSCALL_PREFIX_STR
+# define TEST_SYSCALL_PREFIX_STR ""
+#endif
+
+static const char sample[] = TEST_SYSCALL_STR;
+
+static void
+test_syscall(unsigned short mode)
+{
+	unsigned long lmode = (unsigned long) 0xffffffffffff0000 | mode;
+	long rc = syscall(TEST_SYSCALL_NR, TEST_SYSCALL_PREFIX_ARGS
+			  sample, lmode);
+
+	if (mode <= 07)
+		printf("%s(%s\"%s\", 00%d) = %ld %s (%m)\n",
+		       sample, TEST_SYSCALL_PREFIX_STR,
+		       sample, (int) mode, rc, errno2name());
+	else
+		printf("%s(%s\"%s\", %#03ho) = %ld %s (%m)\n",
+		       sample, TEST_SYSCALL_PREFIX_STR,
+		       sample, mode, rc, errno2name());
+}
+
+int
+main(void)
+{
+	test_syscall(0);
+	test_syscall(0xffff);
+	test_syscall(06);
+	test_syscall(060);
+	test_syscall(0600);
+	test_syscall(024);
+	test_syscall(S_IFREG);
+	test_syscall(S_IFDIR | 06);
+	test_syscall(S_IFLNK | 060);
+	test_syscall(S_IFIFO | 0600);
+	test_syscall(S_IFCHR | 024);
+	test_syscall((0xffff & ~S_IFMT) | S_IFBLK);
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/umount.c b/tests/umount.c
index cc382fe..eda7ae5 100644
--- a/tests/umount.c
+++ b/tests/umount.c
@@ -29,7 +29,7 @@
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 #include <unistd.h>
 
 #ifdef __NR_oldumount
diff --git a/tests/umount2.c b/tests/umount2.c
index 45ed1a4..1a6d845 100644
--- a/tests/umount2.c
+++ b/tests/umount2.c
@@ -30,7 +30,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_umount2
 # define TEST_SYSCALL_STR "umount2"
diff --git a/tests/uname.c b/tests/uname.c
index 571cf9b..cd6f51c 100644
--- a/tests/uname.c
+++ b/tests/uname.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_uname
 
diff --git a/tests/unix-pair-send-recv.c b/tests/unix-pair-send-recv.c
index 9540239..d4ac0d2 100644
--- a/tests/unix-pair-send-recv.c
+++ b/tests/unix-pair-send-recv.c
@@ -32,7 +32,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/socket.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifndef __NR_send
 # define __NR_send -1
diff --git a/tests/unlink.c b/tests/unlink.c
index f5a1a1a..bbb1de1 100644
--- a/tests/unlink.c
+++ b/tests/unlink.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_unlink
 
diff --git a/tests/unlinkat.c b/tests/unlinkat.c
index 29eeb19..0b69b03 100644
--- a/tests/unlinkat.c
+++ b/tests/unlinkat.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_unlinkat
 
diff --git a/tests/userfaultfd.c b/tests/userfaultfd.c
index 5747a2a..254b84e 100644
--- a/tests/userfaultfd.c
+++ b/tests/userfaultfd.c
@@ -27,7 +27,7 @@
 
 #include "tests.h"
 #include <fcntl.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_userfaultfd && defined O_CLOEXEC
 
diff --git a/tests/utime.c b/tests/utime.c
index 2286217..ef40d1b 100644
--- a/tests/utime.c
+++ b/tests/utime.c
@@ -28,7 +28,6 @@
  */
 
 #include "tests.h"
-#include <assert.h>
 #include <time.h>
 #include <utime.h>
 #include <errno.h>
@@ -45,23 +44,22 @@
 int
 main(void)
 {
-	utime("", NULL);
-	printf("utime(\"\", NULL) = -1 ENOENT (%m)\n");
+	int rc = utime("", NULL);
+	printf("utime(\"\", NULL) = %s\n", sprintrc(rc));
 
 	const time_t t = time(NULL);
 	const struct tm * const p = localtime(&t);
 	const struct utimbuf u = { .actime = t, .modtime = t };
 	const struct utimbuf const *tail_u = tail_memdup(&u, sizeof(u));
 
+	rc = utime("utime\nfilename", tail_u);
+	const char *errstr = sprintrc(rc);
 	printf("utime(\"utime\\nfilename\", [");
 	print_tm(p);
 	printf(", ");
 	print_tm(p);
-	printf("]) = -1 ENOENT ");
-	assert(utime("utime\nfilename", tail_u) == -1);
-	if (ENOENT != errno)
-		perror_msg_and_skip("utime");
-	printf("(%m)\n");
+	printf("]) = %s\n", errstr);
+
 	puts("+++ exited with 0 +++");
 	return 0;
 }
diff --git a/tests/utimes.c b/tests/utimes.c
index e9fe931..401d18a 100644
--- a/tests/utimes.c
+++ b/tests/utimes.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_utimes
 
diff --git a/tests/vhangup.c b/tests/vhangup.c
index 468f334..e7ddabb 100644
--- a/tests/vhangup.c
+++ b/tests/vhangup.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_vhangup
 
@@ -21,10 +21,7 @@
 	 * The system call, however, returns 0 iff the calling process
 	 * has CAP_SYS_TTY_CONFIG capability.
 	 */
-	if (rc)
-		printf("vhangup() = %ld %s (%m)\n", rc, errno2name());
-	else
-		puts("vhangup() = 0");
+	printf("vhangup() = %s\n", sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/vmsplice.c b/tests/vmsplice.c
index 06c0694..f29962e 100644
--- a/tests/vmsplice.c
+++ b/tests/vmsplice.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_vmsplice
 
diff --git a/tests/wait4-v.c b/tests/wait4-v.c
index 95a3c8b..8c0c9f5 100644
--- a/tests/wait4-v.c
+++ b/tests/wait4-v.c
@@ -1,3 +1,3 @@
 /* This file is part of wait4-v strace test. */
-#define VERBOSE_RUSAGE
+#define VERBOSE 1
 #include "wait4.c"
diff --git a/tests/wait4.c b/tests/wait4.c
index 981818c..2d316aa 100644
--- a/tests/wait4.c
+++ b/tests/wait4.c
@@ -42,7 +42,7 @@
 	snprintf(buf, sizeof(buf),
 		 "{ru_utime={%lu, %lu}"
 		 ", ru_stime={%lu, %lu}"
-#ifdef VERBOSE_RUSAGE
+#if VERBOSE
 		 ", ru_maxrss=%lu"
 		 ", ru_ixrss=%lu"
 		 ", ru_idrss=%lu"
@@ -64,7 +64,7 @@
 		 , (long) ru->ru_utime.tv_usec
 		 , (long) ru->ru_stime.tv_sec
 		 , (long) ru->ru_stime.tv_usec
-#ifdef VERBOSE_RUSAGE
+#if VERBOSE
 		 , (long) ru->ru_maxrss
 		 , (long) ru->ru_ixrss
 		 , (long) ru->ru_idrss
diff --git a/tests/waitid-v.c b/tests/waitid-v.c
index 06171ae..15a8010 100644
--- a/tests/waitid-v.c
+++ b/tests/waitid-v.c
@@ -1,3 +1,3 @@
 /* This file is part of waitid-v strace test. */
-#define VERBOSE_RUSAGE
+#define VERBOSE 1
 #include "waitid.c"
diff --git a/tests/waitid.c b/tests/waitid.c
index bd7e8ef..b379f1a 100644
--- a/tests/waitid.c
+++ b/tests/waitid.c
@@ -35,7 +35,7 @@
 #include <unistd.h>
 #include <sys/wait.h>
 #include <sys/resource.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 static const char *
 sprint_rusage(const struct rusage *const ru)
@@ -44,7 +44,7 @@
 	snprintf(buf, sizeof(buf),
 		 "{ru_utime={%llu, %llu}"
 		 ", ru_stime={%llu, %llu}"
-#ifdef VERBOSE_RUSAGE
+#if VERBOSE
 		 ", ru_maxrss=%llu"
 		 ", ru_ixrss=%llu"
 		 ", ru_idrss=%llu"
@@ -62,25 +62,25 @@
 #else
 		 ", ...}"
 #endif
-		 , widen_to_ull(ru->ru_utime.tv_sec)
-		 , widen_to_ull(ru->ru_utime.tv_usec)
-		 , widen_to_ull(ru->ru_stime.tv_sec)
-		 , widen_to_ull(ru->ru_stime.tv_usec)
-#ifdef VERBOSE_RUSAGE
-		 , widen_to_ull(ru->ru_maxrss)
-		 , widen_to_ull(ru->ru_ixrss)
-		 , widen_to_ull(ru->ru_idrss)
-		 , widen_to_ull(ru->ru_isrss)
-		 , widen_to_ull(ru->ru_minflt)
-		 , widen_to_ull(ru->ru_majflt)
-		 , widen_to_ull(ru->ru_nswap)
-		 , widen_to_ull(ru->ru_inblock)
-		 , widen_to_ull(ru->ru_oublock)
-		 , widen_to_ull(ru->ru_msgsnd)
-		 , widen_to_ull(ru->ru_msgrcv)
-		 , widen_to_ull(ru->ru_nsignals)
-		 , widen_to_ull(ru->ru_nvcsw)
-		 , widen_to_ull(ru->ru_nivcsw)
+		 , zero_extend_signed_to_ull(ru->ru_utime.tv_sec)
+		 , zero_extend_signed_to_ull(ru->ru_utime.tv_usec)
+		 , zero_extend_signed_to_ull(ru->ru_stime.tv_sec)
+		 , zero_extend_signed_to_ull(ru->ru_stime.tv_usec)
+#if VERBOSE
+		 , zero_extend_signed_to_ull(ru->ru_maxrss)
+		 , zero_extend_signed_to_ull(ru->ru_ixrss)
+		 , zero_extend_signed_to_ull(ru->ru_idrss)
+		 , zero_extend_signed_to_ull(ru->ru_isrss)
+		 , zero_extend_signed_to_ull(ru->ru_minflt)
+		 , zero_extend_signed_to_ull(ru->ru_majflt)
+		 , zero_extend_signed_to_ull(ru->ru_nswap)
+		 , zero_extend_signed_to_ull(ru->ru_inblock)
+		 , zero_extend_signed_to_ull(ru->ru_oublock)
+		 , zero_extend_signed_to_ull(ru->ru_msgsnd)
+		 , zero_extend_signed_to_ull(ru->ru_msgrcv)
+		 , zero_extend_signed_to_ull(ru->ru_nsignals)
+		 , zero_extend_signed_to_ull(ru->ru_nvcsw)
+		 , zero_extend_signed_to_ull(ru->ru_nivcsw)
 #endif
 		 );
 	return buf;
@@ -130,8 +130,8 @@
 		 si->si_pid,
 		 si->si_uid,
 		 status_text,
-		 widen_to_ull(si->si_utime),
-		 widen_to_ull(si->si_stime));
+		 zero_extend_signed_to_ull(si->si_utime),
+		 zero_extend_signed_to_ull(si->si_stime));
 	return buf;
 }
 
diff --git a/tests/waitpid.c b/tests/waitpid.c
index c6f0ad4..dbcdf87 100644
--- a/tests/waitpid.c
+++ b/tests/waitpid.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #ifdef __NR_waitpid
 
diff --git a/tests/xattr.c b/tests/xattr.c
index e72436c..877552f 100644
--- a/tests/xattr.c
+++ b/tests/xattr.c
@@ -29,7 +29,6 @@
 
 #ifdef HAVE_SYS_XATTR_H
 
-# include <assert.h>
 # include <stdio.h>
 # include <sys/xattr.h>
 
@@ -48,94 +47,83 @@
 	char *const efault = tail_alloc(1) + 1;
 	const char *const value = tail_memdup(c_value, sizeof(c_value) - 1);
 	char *const big = tail_alloc(XATTR_SIZE_MAX + 1);
+	long rc;
+	const char *errstr;
 
-	assert(fsetxattr(-1, 0, 0, 0, XATTR_CREATE) == -1);
-	printf("fsetxattr(-1, NULL, NULL, 0, XATTR_CREATE) = -1 %s (%m)\n",
-	       errno2name());
+	rc = fsetxattr(-1, 0, 0, 0, XATTR_CREATE);
+	printf("fsetxattr(-1, NULL, NULL, 0, XATTR_CREATE) = %s\n",
+	       sprintrc(rc));
 
-	assert(fsetxattr(-1, 0, z_value, 0, XATTR_CREATE) == -1);
-	printf("fsetxattr(-1, NULL, \"\", 0, XATTR_CREATE) = -1 %s (%m)\n",
-	       errno2name());
+	rc = fsetxattr(-1, 0, z_value, 0, XATTR_CREATE);
+	printf("fsetxattr(-1, NULL, \"\", 0, XATTR_CREATE) = %s\n",
+	       sprintrc(rc));
 
-	assert(fsetxattr(-1, name, big, XATTR_SIZE_MAX + 1, XATTR_CREATE) == -1);
-	printf("fsetxattr(-1, \"%s\", %p, %u, XATTR_CREATE)"
-	       " = -1 %s (%m)\n",
-	       name, big, XATTR_SIZE_MAX + 1, errno2name());
+	rc = fsetxattr(-1, name, big, XATTR_SIZE_MAX + 1, XATTR_CREATE);
+	printf("fsetxattr(-1, \"%s\", %p, %u, XATTR_CREATE) = %s\n",
+	       name, big, XATTR_SIZE_MAX + 1, sprintrc(rc));
 
-	assert(fsetxattr(-1, name, value, sizeof(c_value), XATTR_CREATE) == -1);
-	printf("fsetxattr(-1, \"%s\", %p, %u, XATTR_CREATE)"
-	       " = -1 %s (%m)\n",
-	       name, value, (unsigned) sizeof(c_value), errno2name());
+	rc = fsetxattr(-1, name, value, sizeof(c_value), XATTR_CREATE);
+	printf("fsetxattr(-1, \"%s\", %p, %u, XATTR_CREATE) = %s\n",
+	       name, value, (unsigned) sizeof(c_value), sprintrc(rc));
 
-	assert(fsetxattr(-1, name, z_value, sizeof(c_value), XATTR_REPLACE) == -1);
-	printf("fsetxattr(-1, \"%s\", \"%s\", %u, XATTR_REPLACE)"
-	       " = -1 %s (%m)\n",
-	       name, q_value, (unsigned) sizeof(c_value), errno2name());
+	rc = fsetxattr(-1, name, z_value, sizeof(c_value), XATTR_REPLACE);
+	printf("fsetxattr(-1, \"%s\", \"%s\", %u, XATTR_REPLACE) = %s\n",
+	       name, q_value, (unsigned) sizeof(c_value), sprintrc(rc));
 
-	assert(fsetxattr(-1, name, value, sizeof(c_value) - 1, XATTR_CREATE|XATTR_REPLACE) == -1);
+	rc = fsetxattr(-1, name, value, sizeof(c_value) - 1, XATTR_CREATE|XATTR_REPLACE);
 	printf("fsetxattr(-1, \"%s\", \"%s\", %u, XATTR_CREATE|XATTR_REPLACE)"
-	       " = -1 %s (%m)\n",
-	       name, q_value, (unsigned) sizeof(c_value) - 1, errno2name());
+	       " = %s\n",
+	       name, q_value, (unsigned) sizeof(c_value) - 1, sprintrc(rc));
 
-	assert(setxattr(".", name, z_value, sizeof(c_value), XATTR_CREATE) == -1);
-	printf("setxattr(\".\", \"%s\", \"%s\", %u, XATTR_CREATE)"
-	       " = -1 %s (%m)\n",
-	       name, q_value, (unsigned) sizeof(c_value), errno2name());
+	rc = setxattr(".", name, z_value, sizeof(c_value), XATTR_CREATE);
+	printf("setxattr(\".\", \"%s\", \"%s\", %u, XATTR_CREATE) = %s\n",
+	       name, q_value, (unsigned) sizeof(c_value), sprintrc(rc));
 
-	assert(lsetxattr(".", name, value, sizeof(c_value) - 1, XATTR_CREATE) == -1);
-	printf("lsetxattr(\".\", \"%s\", \"%s\", %u, XATTR_CREATE)"
-	       " = -1 %s (%m)\n",
-	       name, q_value, (unsigned) sizeof(c_value) - 1, errno2name());
+	rc = lsetxattr(".", name, value, sizeof(c_value) - 1, XATTR_CREATE);
+	printf("lsetxattr(\".\", \"%s\", \"%s\", %u, XATTR_CREATE) = %s\n",
+	       name, q_value, (unsigned) sizeof(c_value) - 1, sprintrc(rc));
 
-	assert(fgetxattr(-1, name, efault, 4) == -1);
-	printf("fgetxattr(-1, \"%s\", %p, 4) = -1 %s (%m)\n",
-	       name, efault, errno2name());
+	rc = fgetxattr(-1, name, efault, 4);
+	printf("fgetxattr(-1, \"%s\", %p, 4) = %s\n",
+	       name, efault, sprintrc(rc));
 
-	assert(getxattr(".", name, big, XATTR_SIZE_MAX + 1) == -1);
-	printf("getxattr(\".\", \"%s\", %p, %u) = -1 %s (%m)\n",
-	       name, big, XATTR_SIZE_MAX + 1, errno2name());
+	rc = getxattr(".", name, big, XATTR_SIZE_MAX + 1);
+	printf("getxattr(\".\", \"%s\", %p, %u) = %s\n",
+	       name, big, XATTR_SIZE_MAX + 1, sprintrc(rc));
 
-	assert(lgetxattr(".", name, big + 1, XATTR_SIZE_MAX) == -1);
-	printf("lgetxattr(\".\", \"%s\", %p, %u) = -1 %s (%m)\n",
-	       name, big + 1, XATTR_SIZE_MAX, errno2name());
+	rc = lgetxattr(".", name, big + 1, XATTR_SIZE_MAX);
+	printf("lgetxattr(\".\", \"%s\", %p, %u) = %s\n",
+	       name, big + 1, XATTR_SIZE_MAX, sprintrc(rc));
 
-	assert(flistxattr(-1, efault, 4) == -1);
-	printf("flistxattr(-1, %p, 4) = -1 %s (%m)\n",
-	       efault, errno2name());
+	rc = flistxattr(-1, efault, 4);
+	printf("flistxattr(-1, %p, 4) = %s\n", efault, sprintrc(rc));
 
-	assert(llistxattr("", efault + 1, 4) == -1);
-	printf("llistxattr(\"\", %p, 4) = -1 %s (%m)\n",
-	       efault + 1, errno2name());
+	rc = llistxattr("", efault + 1, 4);
+	printf("llistxattr(\"\", %p, 4) = %s\n", efault + 1, sprintrc(rc));
 
-	ssize_t rc = listxattr(".", big, 0);
-	if (rc < 0)
-		printf("listxattr(\".\", %p, 0) = -1 %s (%m)\n",
-		       big, errno2name());
-	else
-		printf("listxattr(\".\", %p, 0) = %ld\n",
-		       big, (long) rc);
+	rc = listxattr(".", big, 0);
+	printf("listxattr(\".\", %p, 0) = %s\n", big, sprintrc(rc));
 
 	rc = listxattr(".", big, XATTR_SIZE_MAX + 1);
+	errstr = sprintrc(rc);
+	printf("listxattr(\".\", ");
 	if (rc < 0)
-		printf("listxattr(\".\", %p, %u) = -1 %s (%m)\n",
-		       big, XATTR_SIZE_MAX + 1, errno2name());
+		printf("%p", big);
 	else {
-		printf("listxattr(\".\", \"");
+		putchar('"');
 		print_quoted_memory(big, rc);
-		printf("\", %u) = %ld\n", XATTR_SIZE_MAX + 1, (long) rc);
+		putchar('"');
 	}
+	printf(", %u) = %s\n", XATTR_SIZE_MAX + 1, errstr);
 
-	assert(fremovexattr(-1, name) == -1);
-	printf("fremovexattr(-1, \"%s\") = -1 %s (%m)\n",
-	       name, errno2name());
+	rc = fremovexattr(-1, name);
+	printf("fremovexattr(-1, \"%s\") = %s\n", name, sprintrc(rc));
 
-	assert(removexattr(".", name) == -1);
-	printf("removexattr(\".\", \"%s\") = -1 %s (%m)\n",
-	       name, errno2name());
+	rc = removexattr(".", name);
+	printf("removexattr(\".\", \"%s\") = %s\n", name, sprintrc(rc));
 
-	assert(lremovexattr(".", name) == -1);
-	printf("lremovexattr(\".\", \"%s\") = -1 %s (%m)\n",
-	       name, errno2name());
+	rc = lremovexattr(".", name);
+	printf("lremovexattr(\".\", \"%s\") = %s\n", name, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/xchownx.c b/tests/xchownx.c
index b065675..fe58283 100644
--- a/tests/xchownx.c
+++ b/tests/xchownx.c
@@ -27,7 +27,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -141,29 +140,11 @@
 
 		const long rc = syscall(SYSCALL_NR, SYSCALL_ARG1,
 					tests[i].uid, tests[i].gid);
-		int saved_errno = errno;
-		if (rc != expected) {
-			if (!i && ENOSYS == errno) {
-				printf("%s(" FMT_ARG1 ", %u, %u)"
-				       " = -1 ENOSYS (%m)\n",
-				       SYSCALL_NAME, SYSCALL_ARG1, uid, gid);
-				break;
-			}
-			perror_msg_and_fail("%s(" FMT_ARG1
-					    ", %#lx, %#lx) != %ld",
-					    SYSCALL_NAME, SYSCALL_ARG1,
-					    tests[i].uid, tests[i].gid,
-					    expected);
-		}
-
+		const char *errstr = sprintrc(rc);
 		printf("%s(" FMT_ARG1, SYSCALL_NAME, SYSCALL_ARG1);
 		print_int(unum);
 		print_int(gnum);
-		errno = saved_errno;
-		if (expected)
-			printf(") = %ld %s (%m)\n", expected, errno2name());
-		else
-			printf(") = 0\n");
+		printf(") = %s\n", errstr);
 	}
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/xet_robust_list.c b/tests/xet_robust_list.c
index eef31dc..f834930 100644
--- a/tests/xet_robust_list.c
+++ b/tests/xet_robust_list.c
@@ -26,7 +26,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_get_robust_list && defined __NR_set_robust_list
 
diff --git a/tests/xetpgid.c b/tests/xetpgid.c
index 6ce79c1..d4d5545 100644
--- a/tests/xetpgid.c
+++ b/tests/xetpgid.c
@@ -28,7 +28,7 @@
  */
 
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_getpgid && defined __NR_setpgid
 
diff --git a/tests/xetpriority.c b/tests/xetpriority.c
index a32b031..dfd3264 100644
--- a/tests/xetpriority.c
+++ b/tests/xetpriority.c
@@ -1,5 +1,5 @@
 #include "tests.h"
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 #if defined __NR_getpriority && defined __NR_setpriority
 
@@ -18,11 +18,7 @@
 	rc = syscall(__NR_setpriority, PRIO_PROCESS,
 		     (unsigned long) 0xffffffff00000000 | pid,
 		     (unsigned long) 0xffffffff00000000);
-	if (rc)
-		printf("setpriority(PRIO_PROCESS, %d, 0) = %ld %s (%m)\n",
-		       pid, rc, errno2name());
-	else
-		printf("setpriority(PRIO_PROCESS, %d, 0) = 0\n", pid);
+	printf("setpriority(PRIO_PROCESS, %d, 0) = %s\n", pid, sprintrc(rc));
 
 	puts("+++ exited with 0 +++");
 	return 0;
diff --git a/tests/xettimeofday.c b/tests/xettimeofday.c
index ae28e02..dd05091 100644
--- a/tests/xettimeofday.c
+++ b/tests/xettimeofday.c
@@ -31,7 +31,7 @@
 #include <stdint.h>
 #include <unistd.h>
 #include <sys/time.h>
-#include <sys/syscall.h>
+#include <asm/unistd.h>
 
 int
 main(void)
diff --git a/tests/xstatfsx.c b/tests/xstatfsx.c
index 3561866..c5c04be 100644
--- a/tests/xstatfsx.c
+++ b/tests/xstatfsx.c
@@ -105,14 +105,16 @@
 	print_statfs(".", NULL);
 
 	long rc = SYSCALL_INVOKE("", -1, 0, sizeof(STRUCT_STATFS));
+	const char *errstr = sprintrc(rc);
 	PRINT_SYSCALL_HEADER("", -1, sizeof(STRUCT_STATFS));
-	printf("NULL) = %ld %s (%m)\n", rc, errno2name());
+	printf("NULL) = %s\n", errstr);
 
 #ifdef CHECK_ODD_SIZE
 	const unsigned long addr = (unsigned long) 0xfacefeeddeadbeef;
 	rc = SYSCALL_INVOKE("", -1, addr, sizeof(STRUCT_STATFS) + 1);
+	errstr = sprintrc(rc);
 	PRINT_SYSCALL_HEADER("", -1, sizeof(STRUCT_STATFS) + 1);
-	printf("%#lx) = %ld %s (%m)\n", addr, rc, errno2name());
+	printf("%#lx) = %s\n", addr, errstr);
 #endif
 
 	puts("+++ exited with 0 +++");
diff --git a/tests/xstatx.c b/tests/xstatx.c
index 2883f16..2d0dac3 100644
--- a/tests/xstatx.c
+++ b/tests/xstatx.c
@@ -44,14 +44,7 @@
 # include <stddef.h>
 # include <time.h>
 # include <unistd.h>
-
-# if defined MAJOR_IN_SYSMACROS
-#  include <sys/sysmacros.h>
-# elif defined MAJOR_IN_MKDEV
-#  include <sys/mkdev.h>
-# else
-#  include <sys/types.h>
-# endif
+# include <sys/sysmacros.h>
 
 static void
 print_time(const time_t t)
@@ -68,9 +61,18 @@
 		       p->tm_year + 1900, p->tm_mon + 1, p->tm_mday,
 		       p->tm_hour, p->tm_min, p->tm_sec);
 	else
-		printf("%llu", (unsigned long long) t);
+		printf("%llu", zero_extend_signed_to_ull(t));
 }
 
+# ifndef STRUCT_STAT
+#  define STRUCT_STAT struct stat
+#  define STRUCT_STAT_STR "struct stat"
+#  define STRUCT_STAT_IS_STAT64 0
+# endif
+# ifndef SAMPLE_SIZE
+#  define SAMPLE_SIZE 43147718418
+# endif
+
 typedef off_t libc_off_t;
 
 # ifdef USE_ASM_STAT
@@ -88,54 +90,46 @@
 #  undef st_atime
 #  undef st_mtime
 #  undef st_ctime
-#  undef dev_t
-#  undef gid_t
-#  undef ino_t
-#  undef loff_t
-#  undef mode_t
-#  undef nlink_t
-#  undef off64_t
-#  undef off_t
-#  undef time_t
-#  undef uid_t
-#  define dev_t __kernel_dev_t
-#  define gid_t __kernel_gid_t
-#  define ino_t __kernel_ino_t
-#  define loff_t __kernel_loff_t
-#  define mode_t __kernel_mode_t
-#  define nlink_t __kernel_nlink_t
-#  define off64_t __kernel_off64_t
-#  define off_t __kernel_off_t
-#  define time_t __kernel_time_t
-#  define uid_t __kernel_uid_t
 #  include "asm_stat.h"
-# else
-#  undef HAVE_STRUCT_STAT_ST_ATIME_NSEC
-#  ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
-#   define HAVE_STRUCT_STAT_ST_ATIME_NSEC 1
-#   undef st_atime_nsec
-#   define st_atime_nsec st_atim.tv_nsec
-#  endif
+
+#  if STRUCT_STAT_IS_STAT64
+#   undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+#   if defined MPERS_IS_m32
+#    ifdef HAVE_M32_STRUCT_STAT64_ST_MTIME_NSEC
+#     define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#    endif
+#   elif defined MPERS_IS_mx32
+#    ifdef HAVE_MX32_STRUCT_STAT64_ST_MTIME_NSEC
+#     define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#    endif
+#   elif defined HAVE_STRUCT_STAT64_ST_MTIME_NSEC
+#    define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#   endif /* MPERS_IS_m32 || MPERS_IS_mx32 || HAVE_STRUCT_STAT64_ST_MTIME_NSEC */
+#  else /* !STRUCT_STAT_IS_STAT64 */
+#   if defined MPERS_IS_m32
+#    undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+#    ifdef HAVE_M32_STRUCT_STAT_ST_MTIME_NSEC
+#     define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#    endif
+#   elif defined MPERS_IS_mx32
+#    undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
+#    ifdef HAVE_MX32_STRUCT_STAT_ST_MTIME_NSEC
+#     define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
+#    endif
+#   endif /*  MPERS_IS_m32 || MPERS_IS_mx32 */
+#  endif /* STRUCT_STAT_IS_STAT64 */
+
+# else /* !USE_ASM_STAT */
 #  undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
 #  ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
 #   define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
-#   undef st_mtime_nsec
-#   define st_mtime_nsec st_mtim.tv_nsec
-#  endif
-#  undef HAVE_STRUCT_STAT_ST_CTIME_NSEC
-#  ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
-#   define HAVE_STRUCT_STAT_ST_CTIME_NSEC 1
+#   undef st_atime_nsec
+#   define st_atime_nsec st_atim.tv_nsec
 #   undef st_ctime_nsec
 #   define st_ctime_nsec st_ctim.tv_nsec
-#  endif
-# endif
-
-# ifndef STRUCT_STAT
-#  define STRUCT_STAT struct stat
-#  define STRUCT_STAT_STR "struct stat"
-# endif
-# ifndef SAMPLE_SIZE
-#  define SAMPLE_SIZE 43147718418
+#   undef st_mtime_nsec
+#   define st_mtime_nsec st_mtim.tv_nsec
+#  endif /* HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC */
 # endif
 
 static void
@@ -163,46 +157,46 @@
 print_stat(const STRUCT_STAT *st)
 {
 	printf("{st_dev=makedev(%u, %u)",
-	       (unsigned int) major(st->st_dev),
-	       (unsigned int) minor(st->st_dev));
-	printf(", st_ino=%llu", (unsigned long long) st->st_ino);
+	       (unsigned int) major(zero_extend_signed_to_ull(st->st_dev)),
+	       (unsigned int) minor(zero_extend_signed_to_ull(st->st_dev)));
+	printf(", st_ino=%llu", zero_extend_signed_to_ull(st->st_ino));
 	printf(", st_mode=");
 	print_ftype(st->st_mode);
 	printf("|");
 	print_perms(st->st_mode);
-	printf(", st_nlink=%u", (unsigned int) st->st_nlink);
-	printf(", st_uid=%u", (unsigned int) st->st_uid);
-	printf(", st_gid=%u", (unsigned int) st->st_gid);
-	printf(", st_blksize=%u", (unsigned int) st->st_blksize);
-	printf(", st_blocks=%u", (unsigned int) st->st_blocks);
+	printf(", st_nlink=%llu", zero_extend_signed_to_ull(st->st_nlink));
+	printf(", st_uid=%llu", zero_extend_signed_to_ull(st->st_uid));
+	printf(", st_gid=%llu", zero_extend_signed_to_ull(st->st_gid));
+	printf(", st_blksize=%llu", zero_extend_signed_to_ull(st->st_blksize));
+	printf(", st_blocks=%llu", zero_extend_signed_to_ull(st->st_blocks));
 
 	switch (st->st_mode & S_IFMT) {
 	case S_IFCHR: case S_IFBLK:
 		printf(", st_rdev=makedev(%u, %u)",
-		       (unsigned int) major(st->st_rdev),
-		       (unsigned int) minor(st->st_rdev));
+		       (unsigned int) major(zero_extend_signed_to_ull(st->st_rdev)),
+		       (unsigned int) minor(zero_extend_signed_to_ull(st->st_rdev)));
 		break;
 	default:
-		printf(", st_size=%llu", (unsigned long long) st->st_size);
+		printf(", st_size=%llu", zero_extend_signed_to_ull(st->st_size));
 	}
 
 	printf(", st_atime=");
-	print_time(st->st_atime);
-# ifdef HAVE_STRUCT_STAT_ST_ATIME_NSEC
+	print_time(sign_extend_unsigned_to_ll(st->st_atime));
+# ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
 	if (st->st_atime_nsec)
-		printf(".%09lu", (unsigned long) st->st_atime_nsec);
+		printf(".%09llu", zero_extend_signed_to_ull(st->st_atime_nsec));
 # endif
 	printf(", st_mtime=");
-	print_time(st->st_mtime);
+	print_time(sign_extend_unsigned_to_ll(st->st_mtime));
 # ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
 	if (st->st_mtime_nsec)
-		printf(".%09lu", (unsigned long) st->st_mtime_nsec);
+		printf(".%09llu", zero_extend_signed_to_ull(st->st_mtime_nsec));
 # endif
 	printf(", st_ctime=");
-	print_time(st->st_ctime);
-# ifdef HAVE_STRUCT_STAT_ST_CTIME_NSEC
+	print_time(sign_extend_unsigned_to_ll(st->st_ctime));
+# ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
 	if (st->st_ctime_nsec)
-		printf(".%09lu", (unsigned long) st->st_ctime_nsec);
+		printf(".%09llu", zero_extend_signed_to_ull(st->st_ctime_nsec));
 # endif
 	printf("}");
 }
@@ -248,12 +242,12 @@
 		return 77;
 	}
 	(void) unlink(sample);
-	if ((unsigned long long) SAMPLE_SIZE !=
-	    (unsigned long long) st[0].st_size) {
+	if (zero_extend_signed_to_ull(SAMPLE_SIZE) !=
+	    zero_extend_signed_to_ull(st[0].st_size)) {
 		fprintf(stderr, "Size mismatch: "
 				"requested size(%llu) != st_size(%llu)\n",
-			(unsigned long long) SAMPLE_SIZE,
-			(unsigned long long) st[0].st_size);
+			zero_extend_signed_to_ull(SAMPLE_SIZE),
+			zero_extend_signed_to_ull(st[0].st_size));
 		fprintf(stderr, "The most likely reason for this is incorrect"
 				" definition of %s.\n"
 				"Here is some diagnostics that might help:\n",
diff --git a/time.c b/time.c
index 963d0ea..b32eddf 100644
--- a/time.c
+++ b/time.c
@@ -314,15 +314,17 @@
 
 SYS_FUNC(timerfd_settime)
 {
-	printfd(tcp, tcp->u_arg[0]);
-	tprints(", ");
-	printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
-	tprints(", ");
-	print_itimerspec(tcp, tcp->u_arg[2]);
-	tprints(", ");
-	print_itimerspec(tcp, tcp->u_arg[3]);
-
-	return RVAL_DECODED;
+	if (entering(tcp)) {
+		printfd(tcp, tcp->u_arg[0]);
+		tprints(", ");
+		printflags(timerfdflags, tcp->u_arg[1], "TFD_???");
+		tprints(", ");
+		print_itimerspec(tcp, tcp->u_arg[2]);
+		tprints(", ");
+	} else {
+		print_itimerspec(tcp, tcp->u_arg[3]);
+	}
+	return 0;
 }
 
 SYS_FUNC(timerfd_gettime)
diff --git a/times.c b/times.c
index 04df462..6af4f95 100644
--- a/times.c
+++ b/times.c
@@ -46,11 +46,11 @@
 
 	if (!umove_or_printaddr(tcp, tcp->u_arg[0], &tbuf)) {
 		tprintf("{tms_utime=%llu, tms_stime=%llu, ",
-			widen_to_ull(tbuf.tms_utime),
-			widen_to_ull(tbuf.tms_stime));
+			zero_extend_signed_to_ull(tbuf.tms_utime),
+			zero_extend_signed_to_ull(tbuf.tms_stime));
 		tprintf("tms_cutime=%llu, tms_cstime=%llu}",
-			widen_to_ull(tbuf.tms_cutime),
-			widen_to_ull(tbuf.tms_cstime));
+			zero_extend_signed_to_ull(tbuf.tms_cutime),
+			zero_extend_signed_to_ull(tbuf.tms_cstime));
 	}
 
 	return syserror(tcp) ? RVAL_DECIMAL :
diff --git a/travis-build.sh b/travis-build.sh
index e6da4bb..32ccd50 100755
--- a/travis-build.sh
+++ b/travis-build.sh
@@ -17,7 +17,7 @@
 		;;
 	x86)
 		CC="$CC -m32"
-		export DISTCHECK_CONFIGURE_FLAGS='--build=i686-pc-linux-gnu'
+		export DISTCHECK_CONFIGURE_FLAGS='--build=i686-pc-linux-gnu --target=i686-pc-linux-gnu'
 		;;
 esac
 
diff --git a/travis-install.sh b/travis-install.sh
index 567a49b..ba5ff2d 100755
--- a/travis-install.sh
+++ b/travis-install.sh
@@ -19,8 +19,31 @@
 		apt_get_install gcc-multilib "$CC"
 		;;
 	musl-gcc)
-		sudo add-apt-repository ppa:bortis/musl -y
-		apt_get_install gcc-multilib musl-tools linux-musl-dev
+		apt_get_install gcc-multilib
+		git clone --depth=1 https://github.com/strace/musl
+		cd musl
+			CC=gcc
+			build=
+			case "${TARGET-}" in
+				x32)
+					CC="$CC -mx32"
+					;;
+				x86)
+					CC="$CC -m32"
+					build='--build=i686-pc-linux-gnu --target=i686-pc-linux-gnu'
+					;;
+			esac
+			./configure --prefix=/opt/musl --exec-prefix=/usr ${build}
+			make
+			sudo make install
+		cd -
+		rm -rf musl
+		sudo ln -s \
+			/usr/include/linux \
+			/usr/include/asm \
+			/usr/include/asm-generic \
+			/usr/include/mtd \
+			/opt/musl/include/
 		;;
 esac
 
diff --git a/umask.c b/umask.c
index dda40d4..d42258a 100644
--- a/umask.c
+++ b/umask.c
@@ -2,7 +2,7 @@
 
 SYS_FUNC(umask)
 {
-	tprintf("%#lo", tcp->u_arg[0]);
+	print_numeric_umode_t(tcp->u_arg[0]);
 
 	return RVAL_DECODED | RVAL_OCTAL;
 }
diff --git a/userfaultfd.c b/userfaultfd.c
index 2721105..07094a1 100644
--- a/userfaultfd.c
+++ b/userfaultfd.c
@@ -77,7 +77,7 @@
 				printflags64(uffd_api_flags, ua.ioctls,
 					     "_UFFDIO_???");
 			}
-			tprintf("}");
+			tprints("}");
 		}
 		return 1;
 	}
@@ -107,14 +107,14 @@
 			tprints(", ");
 			if (umove_or_printaddr(tcp, arg, &ur))
 				return RVAL_DECODED | 1;
-			tprintf("{range=");
+			tprints("{range=");
 			tprintf_uffdio_range(&ur.range);
-			tprintf(", mode=");
+			tprints(", mode=");
 			printflags64(uffd_register_mode_flags, ur.mode,
 				     "UFFDIO_REGISTER_MODE_???");
 		} else {
 			if (!syserror(tcp) && !umove(tcp, arg, &ur)) {
-				tprintf(", ioctls=");
+				tprints(", ioctls=");
 				printflags64(uffd_register_ioctl_flags,
 					     ur.ioctls, "UFFDIO_???");
 			}
@@ -138,9 +138,9 @@
 			tprints(", ");
 			if (umove_or_printaddr(tcp, arg, &uz))
 				return RVAL_DECODED | 1;
-			tprintf("{range=");
+			tprints("{range=");
 			tprintf_uffdio_range(&uz.range);
-			tprintf(", mode=");
+			tprints(", mode=");
 			printflags64(uffd_zeropage_flags, uz.mode,
 				     "UFFDIO_ZEROPAGE_???");
 		} else {
diff --git a/util.c b/util.c
index afa3290..23a5fdb 100644
--- a/util.c
+++ b/util.c
@@ -275,7 +275,17 @@
      defined XTENSA
 	/* Align arg_no to the next even number. */
 	arg_no = (arg_no + 1) & 0xe;
-# endif
+# elif defined SH
+	/*
+	 * The SH4 ABI does allow long longs in odd-numbered registers, but
+	 * does not allow them to be split between registers and memory - and
+	 * there are only four argument registers for normal functions.  As a
+	 * result, pread, for example, takes an extra padding argument before
+	 * the offset.  This was changed late in the 2.4 series (around 2.4.20).
+	 */
+	if (arg_no == 3)
+		arg_no++;
+# endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
 	*val = LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]);
 	arg_no += 2;
 #endif
@@ -609,6 +619,9 @@
 			/* Check for NUL-terminated string. */
 			if (c == eol)
 				goto asciz_ended;
+			if ((i == (size - 1)) &&
+			    (style & QUOTE_OMIT_TRAILING_0) && (c == '\0'))
+				goto asciz_ended;
 			switch (c) {
 				case '\"': case '\\':
 					*s++ = '\\';
@@ -785,7 +798,7 @@
  * If string length exceeds `max_strlen', append `...' to the output.
  */
 void
-printstr(struct tcb *tcp, long addr, long len)
+printstr_ex(struct tcb *tcp, long addr, long len, unsigned int user_style)
 {
 	static char *str = NULL;
 	static char *outstr;
@@ -829,6 +842,8 @@
 		style = 0;
 	}
 
+	style |= user_style;
+
 	/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
 	 * or we were requested to print more than -s NUM chars)...
 	 */
@@ -1403,24 +1418,44 @@
 	return cur >= end_addr;
 }
 
+long long
+getarg_ll(struct tcb *tcp, int argn)
+{
+#if HAVE_STRUCT_TCB_EXT_ARG
+# if SUPPORTED_PERSONALITIES > 1
+	if (current_personality == 1)
+		return (long) tcp->u_arg[argn];
+	else
+# endif
+	return (long long) tcp->ext_arg[argn];
+#else
+	return (long) tcp->u_arg[argn];
+#endif
+}
+
+unsigned long long
+getarg_ull(struct tcb *tcp, int argn)
+{
+#if HAVE_STRUCT_TCB_EXT_ARG
+# if SUPPORTED_PERSONALITIES > 1
+	if (current_personality == 1)
+		return (unsigned long) tcp->u_arg[argn];
+	else
+# endif
+	return (unsigned long long) tcp->ext_arg[argn];
+#else
+	return (unsigned long) tcp->u_arg[argn];
+#endif
+}
+
 int
 printargs(struct tcb *tcp)
 {
 	if (entering(tcp)) {
 		int i;
 		int n = tcp->s_ent->nargs;
-		for (i = 0; i < n; i++) {
-#if HAVE_STRUCT_TCB_EXT_ARG
-# if SUPPORTED_PERSONALITIES > 1
-			if (current_personality == 1)
-				tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
-			else
-# endif
-			tprintf("%s%#llx", i ? ", " : "", tcp->ext_arg[i]);
-#else
-			tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
-#endif
-		}
+		for (i = 0; i < n; i++)
+			tprintf("%s%#llx", i ? ", " : "", getarg_ull(tcp, i));
 	}
 	return 0;
 }
diff --git a/xlat.h b/xlat.h
index 2f7643c..aaa7aab 100644
--- a/xlat.h
+++ b/xlat.h
@@ -1,4 +1,5 @@
 #ifndef STRACE_XLAT_H
+#define STRACE_XLAT_H
 
 # include <stdint.h>
 
@@ -13,4 +14,4 @@
 # define XLAT_TYPE_PAIR(type, val, str)	{     (type)(val), str  }
 # define XLAT_END			{		0, 0    }
 
-#endif
+#endif /* !STRACE_XLAT_H */
diff --git a/xlat/Makemodule.am b/xlat/Makemodule.am
index 06db6bd..2e7abca 100644
--- a/xlat/Makemodule.am
+++ b/xlat/Makemodule.am
@@ -1,5 +1,5 @@
-XLAT_INPUT_FILES = xlat/access_flags.in xlat/aclipc.in xlat/addrfams.in xlat/adjtimex_modes.in xlat/adjtimex_state.in xlat/adjtimex_status.in xlat/advise.in xlat/af_packet_types.in xlat/archvals.in xlat/arp_hardware_types.in xlat/at_flags.in xlat/atomic_ops.in xlat/audit_arch.in xlat/baud_options.in xlat/blkpg_ops.in xlat/bootflags1.in xlat/bootflags2.in xlat/bootflags3.in xlat/bpf_class.in xlat/bpf_commands.in xlat/bpf_map_types.in xlat/bpf_map_update_elem_flags.in xlat/bpf_miscop.in xlat/bpf_mode.in xlat/bpf_op_alu.in xlat/bpf_op_jmp.in xlat/bpf_prog_types.in xlat/bpf_rval.in xlat/bpf_size.in xlat/bpf_src.in xlat/bsg_protocol.in xlat/bsg_subprotocol.in xlat/bt_protocols.in xlat/btrfs_balance_args.in xlat/btrfs_balance_ctl_cmds.in xlat/btrfs_balance_flags.in xlat/btrfs_balance_state.in xlat/btrfs_compress_types.in xlat/btrfs_defrag_flags.in xlat/btrfs_dev_replace_cmds.in xlat/btrfs_dev_replace_results.in xlat/btrfs_dev_replace_state.in xlat/btrfs_dev_stats_flags.in xlat/btrfs_dev_stats_values.in xlat/btrfs_features_compat.in xlat/btrfs_features_compat_ro.in xlat/btrfs_features_incompat.in xlat/btrfs_key_types.in xlat/btrfs_qgroup_ctl_cmds.in xlat/btrfs_qgroup_inherit_flags.in xlat/btrfs_qgroup_limit_flags.in xlat/btrfs_qgroup_status_flags.in xlat/btrfs_scrub_flags.in xlat/btrfs_send_flags.in xlat/btrfs_snap_flags_v2.in xlat/btrfs_space_info_flags.in xlat/btrfs_tree_objectids.in xlat/cacheflush_scope.in xlat/cap.in xlat/cap_mask0.in xlat/cap_mask1.in xlat/cap_version.in xlat/clockflags.in xlat/clocknames.in xlat/clone_flags.in xlat/cpuclocknames.in xlat/delete_module_flags.in xlat/dirent_types.in xlat/efd_flags.in xlat/epollctls.in xlat/epollevents.in xlat/epollflags.in xlat/ethernet_protocols.in xlat/evdev_abs.in xlat/evdev_autorepeat.in xlat/evdev_ev.in xlat/evdev_ff_status.in xlat/evdev_ff_types.in xlat/evdev_keycode.in xlat/evdev_leds.in xlat/evdev_misc.in xlat/evdev_mtslots.in xlat/evdev_prop.in xlat/evdev_relative_axes.in xlat/evdev_snd.in xlat/evdev_switch.in xlat/evdev_sync.in xlat/falloc_flags.in xlat/fan_classes.in xlat/fan_event_flags.in xlat/fan_init_flags.in xlat/fan_mark_flags.in xlat/fcntl64cmds.in xlat/fcntlcmds.in xlat/fdflags.in xlat/fiemap_extent_flags.in xlat/fiemap_flags.in xlat/flockcmds.in xlat/f_owner_types.in xlat/f_seals.in xlat/fsmagic.in xlat/futexops.in xlat/futexwakecmps.in xlat/futexwakeops.in xlat/getrandom_flags.in xlat/getsockipoptions.in xlat/getsockipv6options.in xlat/hci_channels.in xlat/icmpfilterflags.in xlat/if_dqblk_valid.in xlat/if_dqinfo_flags.in xlat/if_dqinfo_valid.in xlat/iffflags.in xlat/inet_protocols.in xlat/inotify_flags.in xlat/inotify_init_flags.in xlat/ioctl_dirs.in xlat/ioprio_class.in xlat/ioprio_who.in xlat/ipccalls.in xlat/ipc_msg_flags.in xlat/ip_cmsg_types.in xlat/itimer_which.in xlat/kcmp_types.in xlat/kexec_arch_values.in xlat/kexec_file_load_flags.in xlat/kexec_load_flags.in xlat/keyctl_commands.in xlat/key_perms.in xlat/key_reqkeys.in xlat/key_spec.in xlat/lockfcmds.in xlat/loop_crypt_type_options.in xlat/loop_flags_options.in xlat/madvise_cmds.in xlat/mbindflags.in xlat/mctl_sync.in xlat/membarrier_cmds.in xlat/memfd_create_flags.in xlat/mempolicyflags.in xlat/mlockall_flags.in xlat/mlock_flags.in xlat/mmap_flags.in xlat/mmap_prot.in xlat/modem_flags.in xlat/modetypes.in xlat/module_init_flags.in xlat/mount_flags.in xlat/move_pages_flags.in xlat/mremap_flags.in xlat/msgctl_flags.in xlat/msg_flags.in xlat/mtd_file_mode_options.in xlat/mtd_flags_options.in xlat/mtd_mode_options.in xlat/mtd_nandecc_options.in xlat/mtd_otp_options.in xlat/mtd_type_options.in xlat/netlink_flags.in xlat/netlink_protocols.in xlat/netlink_types.in xlat/notifyflags.in xlat/nt_descriptor_types.in xlat/open_access_modes.in xlat/open_mode_flags.in xlat/openmodessol.in xlat/packet_mreq_type.in xlat/perf_event_open_flags.in xlat/personality_flags.in xlat/personality_types.in xlat/policies.in xlat/pollflags.in xlat/pr_cap_ambient.in xlat/prctl_options.in xlat/priorities.in xlat/pr_mce_kill.in xlat/pr_mce_kill_policy.in xlat/pr_set_mm.in xlat/pr_tsc.in xlat/pr_unalign_flags.in xlat/ptp_flags_options.in xlat/ptrace_cmds.in xlat/ptrace_events.in xlat/ptrace_peeksiginfo_flags.in xlat/ptrace_setoptions_flags.in xlat/quotacmds.in xlat/quota_formats.in xlat/quotatypes.in xlat/rename_flags.in xlat/resource_flags.in xlat/resources.in xlat/rwf_flags.in xlat/sched_flags.in xlat/schedulers.in xlat/scmvals.in xlat/secbits.in xlat/seccomp_filter_flags.in xlat/seccomp_mode.in xlat/seccomp_ops.in xlat/seccomp_ret_action.in xlat/semctl_flags.in xlat/semop_flags.in xlat/setsockipoptions.in xlat/setsockipv6options.in xlat/sfd_flags.in xlat/sg_io_dxfer_direction.in xlat/shmctl_flags.in xlat/shm_flags.in xlat/shm_resource_flags.in xlat/shutdown_modes.in xlat/sigact_flags.in xlat/sigaltstack_flags.in xlat/sigbus_codes.in xlat/sigchld_codes.in xlat/sigemt_codes.in xlat/sigev_value.in xlat/sigfpe_codes.in xlat/sigill_codes.in xlat/siginfo_codes.in xlat/sigpoll_codes.in xlat/sigprocmaskcmds.in xlat/sigprof_codes.in xlat/sigsegv_codes.in xlat/sigsys_codes.in xlat/sigtrap_codes.in xlat/socketcalls.in xlat/socketlayers.in xlat/sockipoptions.in xlat/sockipv6options.in xlat/sockipxoptions.in xlat/sockoptions.in xlat/sockpacketoptions.in xlat/sockrawoptions.in xlat/socksctpoptions.in xlat/socktcpoptions.in xlat/sock_type_flags.in xlat/socktypes.in xlat/splice_flags.in xlat/sram_alloc_flags.in xlat/statfs_flags.in xlat/swap_flags.in xlat/sync_file_range_flags.in xlat/sysctl_kern.in xlat/sysctl_net_core.in xlat/sysctl_net.in xlat/sysctl_net_ipv4_conf.in xlat/sysctl_net_ipv4.in xlat/sysctl_net_ipv4_route.in xlat/sysctl_net_ipv6.in xlat/sysctl_net_ipv6_route.in xlat/sysctl_net_unix.in xlat/sysctl_root.in xlat/sysctl_vm.in xlat/syslog_action_type.in xlat/sysmips_operations.in xlat/tcflsh_options.in xlat/tcxonc_options.in xlat/timerfdflags.in xlat/ubi_volume_props.in xlat/ubi_volume_types.in xlat/uffd_api_flags.in xlat/uffd_copy_flags.in xlat/uffd_flags.in xlat/uffd_register_ioctl_flags.in xlat/uffd_register_mode_flags.in xlat/uffd_zeropage_flags.in xlat/umount_flags.in xlat/usagewho.in xlat/v4l2_buf_flags.in xlat/v4l2_buf_types.in xlat/v4l2_capture_modes.in xlat/v4l2_colorspaces.in xlat/v4l2_control_classes.in xlat/v4l2_control_flags.in xlat/v4l2_control_ids.in xlat/v4l2_control_types.in xlat/v4l2_device_capabilities_flags.in xlat/v4l2_fields.in xlat/v4l2_format_description_flags.in xlat/v4l2_frameinterval_types.in xlat/v4l2_framesize_types.in xlat/v4l2_input_types.in xlat/v4l2_memories.in xlat/v4l2_streaming_capabilities.in xlat/wait4_options.in xlat/waitid_types.in xlat/whence_codes.in xlat/xattrflags.in xlat/xfs_dqblk_flags.in xlat/xfs_quota_flags.in 
-XLAT_HEADER_FILES = xlat/access_flags.h xlat/aclipc.h xlat/addrfams.h xlat/adjtimex_modes.h xlat/adjtimex_state.h xlat/adjtimex_status.h xlat/advise.h xlat/af_packet_types.h xlat/archvals.h xlat/arp_hardware_types.h xlat/at_flags.h xlat/atomic_ops.h xlat/audit_arch.h xlat/baud_options.h xlat/blkpg_ops.h xlat/bootflags1.h xlat/bootflags2.h xlat/bootflags3.h xlat/bpf_class.h xlat/bpf_commands.h xlat/bpf_map_types.h xlat/bpf_map_update_elem_flags.h xlat/bpf_miscop.h xlat/bpf_mode.h xlat/bpf_op_alu.h xlat/bpf_op_jmp.h xlat/bpf_prog_types.h xlat/bpf_rval.h xlat/bpf_size.h xlat/bpf_src.h xlat/bsg_protocol.h xlat/bsg_subprotocol.h xlat/bt_protocols.h xlat/btrfs_balance_args.h xlat/btrfs_balance_ctl_cmds.h xlat/btrfs_balance_flags.h xlat/btrfs_balance_state.h xlat/btrfs_compress_types.h xlat/btrfs_defrag_flags.h xlat/btrfs_dev_replace_cmds.h xlat/btrfs_dev_replace_results.h xlat/btrfs_dev_replace_state.h xlat/btrfs_dev_stats_flags.h xlat/btrfs_dev_stats_values.h xlat/btrfs_features_compat.h xlat/btrfs_features_compat_ro.h xlat/btrfs_features_incompat.h xlat/btrfs_key_types.h xlat/btrfs_qgroup_ctl_cmds.h xlat/btrfs_qgroup_inherit_flags.h xlat/btrfs_qgroup_limit_flags.h xlat/btrfs_qgroup_status_flags.h xlat/btrfs_scrub_flags.h xlat/btrfs_send_flags.h xlat/btrfs_snap_flags_v2.h xlat/btrfs_space_info_flags.h xlat/btrfs_tree_objectids.h xlat/cacheflush_scope.h xlat/cap.h xlat/cap_mask0.h xlat/cap_mask1.h xlat/cap_version.h xlat/clockflags.h xlat/clocknames.h xlat/clone_flags.h xlat/cpuclocknames.h xlat/delete_module_flags.h xlat/dirent_types.h xlat/efd_flags.h xlat/epollctls.h xlat/epollevents.h xlat/epollflags.h xlat/ethernet_protocols.h xlat/evdev_abs.h xlat/evdev_autorepeat.h xlat/evdev_ev.h xlat/evdev_ff_status.h xlat/evdev_ff_types.h xlat/evdev_keycode.h xlat/evdev_leds.h xlat/evdev_misc.h xlat/evdev_mtslots.h xlat/evdev_prop.h xlat/evdev_relative_axes.h xlat/evdev_snd.h xlat/evdev_switch.h xlat/evdev_sync.h xlat/falloc_flags.h xlat/fan_classes.h xlat/fan_event_flags.h xlat/fan_init_flags.h xlat/fan_mark_flags.h xlat/fcntl64cmds.h xlat/fcntlcmds.h xlat/fdflags.h xlat/fiemap_extent_flags.h xlat/fiemap_flags.h xlat/flockcmds.h xlat/f_owner_types.h xlat/f_seals.h xlat/fsmagic.h xlat/futexops.h xlat/futexwakecmps.h xlat/futexwakeops.h xlat/getrandom_flags.h xlat/getsockipoptions.h xlat/getsockipv6options.h xlat/hci_channels.h xlat/icmpfilterflags.h xlat/if_dqblk_valid.h xlat/if_dqinfo_flags.h xlat/if_dqinfo_valid.h xlat/iffflags.h xlat/inet_protocols.h xlat/inotify_flags.h xlat/inotify_init_flags.h xlat/ioctl_dirs.h xlat/ioprio_class.h xlat/ioprio_who.h xlat/ipccalls.h xlat/ipc_msg_flags.h xlat/ip_cmsg_types.h xlat/itimer_which.h xlat/kcmp_types.h xlat/kexec_arch_values.h xlat/kexec_file_load_flags.h xlat/kexec_load_flags.h xlat/keyctl_commands.h xlat/key_perms.h xlat/key_reqkeys.h xlat/key_spec.h xlat/lockfcmds.h xlat/loop_crypt_type_options.h xlat/loop_flags_options.h xlat/madvise_cmds.h xlat/mbindflags.h xlat/mctl_sync.h xlat/membarrier_cmds.h xlat/memfd_create_flags.h xlat/mempolicyflags.h xlat/mlockall_flags.h xlat/mlock_flags.h xlat/mmap_flags.h xlat/mmap_prot.h xlat/modem_flags.h xlat/modetypes.h xlat/module_init_flags.h xlat/mount_flags.h xlat/move_pages_flags.h xlat/mremap_flags.h xlat/msgctl_flags.h xlat/msg_flags.h xlat/mtd_file_mode_options.h xlat/mtd_flags_options.h xlat/mtd_mode_options.h xlat/mtd_nandecc_options.h xlat/mtd_otp_options.h xlat/mtd_type_options.h xlat/netlink_flags.h xlat/netlink_protocols.h xlat/netlink_types.h xlat/notifyflags.h xlat/nt_descriptor_types.h xlat/open_access_modes.h xlat/open_mode_flags.h xlat/openmodessol.h xlat/packet_mreq_type.h xlat/perf_event_open_flags.h xlat/personality_flags.h xlat/personality_types.h xlat/policies.h xlat/pollflags.h xlat/pr_cap_ambient.h xlat/prctl_options.h xlat/priorities.h xlat/pr_mce_kill.h xlat/pr_mce_kill_policy.h xlat/pr_set_mm.h xlat/pr_tsc.h xlat/pr_unalign_flags.h xlat/ptp_flags_options.h xlat/ptrace_cmds.h xlat/ptrace_events.h xlat/ptrace_peeksiginfo_flags.h xlat/ptrace_setoptions_flags.h xlat/quotacmds.h xlat/quota_formats.h xlat/quotatypes.h xlat/rename_flags.h xlat/resource_flags.h xlat/resources.h xlat/rwf_flags.h xlat/sched_flags.h xlat/schedulers.h xlat/scmvals.h xlat/secbits.h xlat/seccomp_filter_flags.h xlat/seccomp_mode.h xlat/seccomp_ops.h xlat/seccomp_ret_action.h xlat/semctl_flags.h xlat/semop_flags.h xlat/setsockipoptions.h xlat/setsockipv6options.h xlat/sfd_flags.h xlat/sg_io_dxfer_direction.h xlat/shmctl_flags.h xlat/shm_flags.h xlat/shm_resource_flags.h xlat/shutdown_modes.h xlat/sigact_flags.h xlat/sigaltstack_flags.h xlat/sigbus_codes.h xlat/sigchld_codes.h xlat/sigemt_codes.h xlat/sigev_value.h xlat/sigfpe_codes.h xlat/sigill_codes.h xlat/siginfo_codes.h xlat/sigpoll_codes.h xlat/sigprocmaskcmds.h xlat/sigprof_codes.h xlat/sigsegv_codes.h xlat/sigsys_codes.h xlat/sigtrap_codes.h xlat/socketcalls.h xlat/socketlayers.h xlat/sockipoptions.h xlat/sockipv6options.h xlat/sockipxoptions.h xlat/sockoptions.h xlat/sockpacketoptions.h xlat/sockrawoptions.h xlat/socksctpoptions.h xlat/socktcpoptions.h xlat/sock_type_flags.h xlat/socktypes.h xlat/splice_flags.h xlat/sram_alloc_flags.h xlat/statfs_flags.h xlat/swap_flags.h xlat/sync_file_range_flags.h xlat/sysctl_kern.h xlat/sysctl_net_core.h xlat/sysctl_net.h xlat/sysctl_net_ipv4_conf.h xlat/sysctl_net_ipv4.h xlat/sysctl_net_ipv4_route.h xlat/sysctl_net_ipv6.h xlat/sysctl_net_ipv6_route.h xlat/sysctl_net_unix.h xlat/sysctl_root.h xlat/sysctl_vm.h xlat/syslog_action_type.h xlat/sysmips_operations.h xlat/tcflsh_options.h xlat/tcxonc_options.h xlat/timerfdflags.h xlat/ubi_volume_props.h xlat/ubi_volume_types.h xlat/uffd_api_flags.h xlat/uffd_copy_flags.h xlat/uffd_flags.h xlat/uffd_register_ioctl_flags.h xlat/uffd_register_mode_flags.h xlat/uffd_zeropage_flags.h xlat/umount_flags.h xlat/usagewho.h xlat/v4l2_buf_flags.h xlat/v4l2_buf_types.h xlat/v4l2_capture_modes.h xlat/v4l2_colorspaces.h xlat/v4l2_control_classes.h xlat/v4l2_control_flags.h xlat/v4l2_control_ids.h xlat/v4l2_control_types.h xlat/v4l2_device_capabilities_flags.h xlat/v4l2_fields.h xlat/v4l2_format_description_flags.h xlat/v4l2_frameinterval_types.h xlat/v4l2_framesize_types.h xlat/v4l2_input_types.h xlat/v4l2_memories.h xlat/v4l2_streaming_capabilities.h xlat/wait4_options.h xlat/waitid_types.h xlat/whence_codes.h xlat/xattrflags.h xlat/xfs_dqblk_flags.h xlat/xfs_quota_flags.h 
+XLAT_INPUT_FILES = xlat/access_flags.in xlat/aclipc.in xlat/addrfams.in xlat/adjtimex_modes.in xlat/adjtimex_state.in xlat/adjtimex_status.in xlat/advise.in xlat/af_packet_types.in xlat/archvals.in xlat/arp_hardware_types.in xlat/at_flags.in xlat/atomic_ops.in xlat/audit_arch.in xlat/baud_options.in xlat/blkpg_ops.in xlat/bootflags1.in xlat/bootflags2.in xlat/bootflags3.in xlat/bpf_class.in xlat/bpf_commands.in xlat/bpf_map_types.in xlat/bpf_map_update_elem_flags.in xlat/bpf_miscop.in xlat/bpf_mode.in xlat/bpf_op_alu.in xlat/bpf_op_jmp.in xlat/bpf_prog_types.in xlat/bpf_rval.in xlat/bpf_size.in xlat/bpf_src.in xlat/bsg_protocol.in xlat/bsg_subprotocol.in xlat/bt_protocols.in xlat/btrfs_balance_args.in xlat/btrfs_balance_ctl_cmds.in xlat/btrfs_balance_flags.in xlat/btrfs_balance_state.in xlat/btrfs_compress_types.in xlat/btrfs_defrag_flags.in xlat/btrfs_dev_replace_cmds.in xlat/btrfs_dev_replace_results.in xlat/btrfs_dev_replace_state.in xlat/btrfs_dev_stats_flags.in xlat/btrfs_dev_stats_values.in xlat/btrfs_features_compat.in xlat/btrfs_features_compat_ro.in xlat/btrfs_features_incompat.in xlat/btrfs_key_types.in xlat/btrfs_qgroup_ctl_cmds.in xlat/btrfs_qgroup_inherit_flags.in xlat/btrfs_qgroup_limit_flags.in xlat/btrfs_qgroup_status_flags.in xlat/btrfs_scrub_flags.in xlat/btrfs_send_flags.in xlat/btrfs_snap_flags_v2.in xlat/btrfs_space_info_flags.in xlat/btrfs_tree_objectids.in xlat/cacheflush_scope.in xlat/cap.in xlat/cap_mask0.in xlat/cap_mask1.in xlat/cap_version.in xlat/clockflags.in xlat/clocknames.in xlat/clone_flags.in xlat/cpuclocknames.in xlat/delete_module_flags.in xlat/dirent_types.in xlat/efd_flags.in xlat/epollctls.in xlat/epollevents.in xlat/epollflags.in xlat/ethernet_protocols.in xlat/evdev_abs.in xlat/evdev_autorepeat.in xlat/evdev_ev.in xlat/evdev_ff_status.in xlat/evdev_ff_types.in xlat/evdev_keycode.in xlat/evdev_leds.in xlat/evdev_misc.in xlat/evdev_mtslots.in xlat/evdev_prop.in xlat/evdev_relative_axes.in xlat/evdev_snd.in xlat/evdev_switch.in xlat/evdev_sync.in xlat/falloc_flags.in xlat/fan_classes.in xlat/fan_event_flags.in xlat/fan_init_flags.in xlat/fan_mark_flags.in xlat/fcntl64cmds.in xlat/fcntlcmds.in xlat/fdflags.in xlat/fiemap_extent_flags.in xlat/fiemap_flags.in xlat/flockcmds.in xlat/f_owner_types.in xlat/f_seals.in xlat/fsmagic.in xlat/futexops.in xlat/futexwakecmps.in xlat/futexwakeops.in xlat/getrandom_flags.in xlat/getsockipoptions.in xlat/getsockipv6options.in xlat/hci_channels.in xlat/icmpfilterflags.in xlat/if_dqblk_valid.in xlat/if_dqinfo_flags.in xlat/if_dqinfo_valid.in xlat/iffflags.in xlat/inet_protocols.in xlat/inotify_flags.in xlat/inotify_init_flags.in xlat/ioctl_dirs.in xlat/ioprio_class.in xlat/ioprio_who.in xlat/ipccalls.in xlat/ipc_msg_flags.in xlat/ip_cmsg_types.in xlat/itimer_which.in xlat/kcmp_types.in xlat/kexec_arch_values.in xlat/kexec_file_load_flags.in xlat/kexec_load_flags.in xlat/keyctl_commands.in xlat/key_perms.in xlat/key_reqkeys.in xlat/key_spec.in xlat/lockfcmds.in xlat/loop_crypt_type_options.in xlat/loop_flags_options.in xlat/madvise_cmds.in xlat/mbindflags.in xlat/mctl_sync.in xlat/membarrier_cmds.in xlat/memfd_create_flags.in xlat/mempolicyflags.in xlat/mlockall_flags.in xlat/mlock_flags.in xlat/mmap_flags.in xlat/mmap_prot.in xlat/modem_flags.in xlat/modetypes.in xlat/module_init_flags.in xlat/mount_flags.in xlat/move_pages_flags.in xlat/mremap_flags.in xlat/msgctl_flags.in xlat/msg_flags.in xlat/mtd_file_mode_options.in xlat/mtd_flags_options.in xlat/mtd_mode_options.in xlat/mtd_nandecc_options.in xlat/mtd_otp_options.in xlat/mtd_type_options.in xlat/netlink_flags.in xlat/netlink_protocols.in xlat/netlink_types.in xlat/notifyflags.in xlat/nt_descriptor_types.in xlat/open_access_modes.in xlat/open_mode_flags.in xlat/openmodessol.in xlat/packet_mreq_type.in xlat/perf_event_open_flags.in xlat/personality_flags.in xlat/personality_types.in xlat/policies.in xlat/pollflags.in xlat/pr_cap_ambient.in xlat/prctl_options.in xlat/priorities.in xlat/pr_mce_kill.in xlat/pr_mce_kill_policy.in xlat/pr_set_mm.in xlat/pr_tsc.in xlat/pr_unalign_flags.in xlat/ptp_flags_options.in xlat/ptrace_cmds.in xlat/ptrace_events.in xlat/ptrace_peeksiginfo_flags.in xlat/ptrace_setoptions_flags.in xlat/quotacmds.in xlat/quota_formats.in xlat/quotatypes.in xlat/rename_flags.in xlat/resource_flags.in xlat/resources.in xlat/rwf_flags.in xlat/sa_handler_values.in xlat/sched_flags.in xlat/schedulers.in xlat/scmvals.in xlat/secbits.in xlat/seccomp_filter_flags.in xlat/seccomp_mode.in xlat/seccomp_ops.in xlat/seccomp_ret_action.in xlat/semctl_flags.in xlat/semop_flags.in xlat/setsockipoptions.in xlat/setsockipv6options.in xlat/sfd_flags.in xlat/sg_io_dxfer_direction.in xlat/shmctl_flags.in xlat/shm_flags.in xlat/shm_resource_flags.in xlat/shutdown_modes.in xlat/sigact_flags.in xlat/sigaltstack_flags.in xlat/sigbus_codes.in xlat/sigchld_codes.in xlat/sigemt_codes.in xlat/sigev_value.in xlat/sigfpe_codes.in xlat/sigill_codes.in xlat/siginfo_codes.in xlat/sigpoll_codes.in xlat/sigprocmaskcmds.in xlat/sigprof_codes.in xlat/sigsegv_codes.in xlat/sigsys_codes.in xlat/sigtrap_codes.in xlat/socketcalls.in xlat/socketlayers.in xlat/sockipoptions.in xlat/sockipv6options.in xlat/sockipxoptions.in xlat/sockoptions.in xlat/sockpacketoptions.in xlat/sockrawoptions.in xlat/socksctpoptions.in xlat/socktcpoptions.in xlat/sock_type_flags.in xlat/socktypes.in xlat/splice_flags.in xlat/sram_alloc_flags.in xlat/statfs_flags.in xlat/swap_flags.in xlat/sync_file_range_flags.in xlat/sysctl_kern.in xlat/sysctl_net_core.in xlat/sysctl_net.in xlat/sysctl_net_ipv4_conf.in xlat/sysctl_net_ipv4.in xlat/sysctl_net_ipv4_route.in xlat/sysctl_net_ipv6.in xlat/sysctl_net_ipv6_route.in xlat/sysctl_net_unix.in xlat/sysctl_root.in xlat/sysctl_vm.in xlat/syslog_action_type.in xlat/sysmips_operations.in xlat/tcflsh_options.in xlat/tcxonc_options.in xlat/timerfdflags.in xlat/ubi_volume_props.in xlat/ubi_volume_types.in xlat/uffd_api_flags.in xlat/uffd_copy_flags.in xlat/uffd_flags.in xlat/uffd_register_ioctl_flags.in xlat/uffd_register_mode_flags.in xlat/uffd_zeropage_flags.in xlat/umount_flags.in xlat/usagewho.in xlat/v4l2_buf_flags.in xlat/v4l2_buf_types.in xlat/v4l2_capture_modes.in xlat/v4l2_colorspaces.in xlat/v4l2_control_classes.in xlat/v4l2_control_flags.in xlat/v4l2_control_ids.in xlat/v4l2_control_types.in xlat/v4l2_device_capabilities_flags.in xlat/v4l2_fields.in xlat/v4l2_format_description_flags.in xlat/v4l2_frameinterval_types.in xlat/v4l2_framesize_types.in xlat/v4l2_input_types.in xlat/v4l2_memories.in xlat/v4l2_streaming_capabilities.in xlat/wait4_options.in xlat/waitid_types.in xlat/whence_codes.in xlat/xattrflags.in xlat/xfs_dqblk_flags.in xlat/xfs_quota_flags.in 
+XLAT_HEADER_FILES = xlat/access_flags.h xlat/aclipc.h xlat/addrfams.h xlat/adjtimex_modes.h xlat/adjtimex_state.h xlat/adjtimex_status.h xlat/advise.h xlat/af_packet_types.h xlat/archvals.h xlat/arp_hardware_types.h xlat/at_flags.h xlat/atomic_ops.h xlat/audit_arch.h xlat/baud_options.h xlat/blkpg_ops.h xlat/bootflags1.h xlat/bootflags2.h xlat/bootflags3.h xlat/bpf_class.h xlat/bpf_commands.h xlat/bpf_map_types.h xlat/bpf_map_update_elem_flags.h xlat/bpf_miscop.h xlat/bpf_mode.h xlat/bpf_op_alu.h xlat/bpf_op_jmp.h xlat/bpf_prog_types.h xlat/bpf_rval.h xlat/bpf_size.h xlat/bpf_src.h xlat/bsg_protocol.h xlat/bsg_subprotocol.h xlat/bt_protocols.h xlat/btrfs_balance_args.h xlat/btrfs_balance_ctl_cmds.h xlat/btrfs_balance_flags.h xlat/btrfs_balance_state.h xlat/btrfs_compress_types.h xlat/btrfs_defrag_flags.h xlat/btrfs_dev_replace_cmds.h xlat/btrfs_dev_replace_results.h xlat/btrfs_dev_replace_state.h xlat/btrfs_dev_stats_flags.h xlat/btrfs_dev_stats_values.h xlat/btrfs_features_compat.h xlat/btrfs_features_compat_ro.h xlat/btrfs_features_incompat.h xlat/btrfs_key_types.h xlat/btrfs_qgroup_ctl_cmds.h xlat/btrfs_qgroup_inherit_flags.h xlat/btrfs_qgroup_limit_flags.h xlat/btrfs_qgroup_status_flags.h xlat/btrfs_scrub_flags.h xlat/btrfs_send_flags.h xlat/btrfs_snap_flags_v2.h xlat/btrfs_space_info_flags.h xlat/btrfs_tree_objectids.h xlat/cacheflush_scope.h xlat/cap.h xlat/cap_mask0.h xlat/cap_mask1.h xlat/cap_version.h xlat/clockflags.h xlat/clocknames.h xlat/clone_flags.h xlat/cpuclocknames.h xlat/delete_module_flags.h xlat/dirent_types.h xlat/efd_flags.h xlat/epollctls.h xlat/epollevents.h xlat/epollflags.h xlat/ethernet_protocols.h xlat/evdev_abs.h xlat/evdev_autorepeat.h xlat/evdev_ev.h xlat/evdev_ff_status.h xlat/evdev_ff_types.h xlat/evdev_keycode.h xlat/evdev_leds.h xlat/evdev_misc.h xlat/evdev_mtslots.h xlat/evdev_prop.h xlat/evdev_relative_axes.h xlat/evdev_snd.h xlat/evdev_switch.h xlat/evdev_sync.h xlat/falloc_flags.h xlat/fan_classes.h xlat/fan_event_flags.h xlat/fan_init_flags.h xlat/fan_mark_flags.h xlat/fcntl64cmds.h xlat/fcntlcmds.h xlat/fdflags.h xlat/fiemap_extent_flags.h xlat/fiemap_flags.h xlat/flockcmds.h xlat/f_owner_types.h xlat/f_seals.h xlat/fsmagic.h xlat/futexops.h xlat/futexwakecmps.h xlat/futexwakeops.h xlat/getrandom_flags.h xlat/getsockipoptions.h xlat/getsockipv6options.h xlat/hci_channels.h xlat/icmpfilterflags.h xlat/if_dqblk_valid.h xlat/if_dqinfo_flags.h xlat/if_dqinfo_valid.h xlat/iffflags.h xlat/inet_protocols.h xlat/inotify_flags.h xlat/inotify_init_flags.h xlat/ioctl_dirs.h xlat/ioprio_class.h xlat/ioprio_who.h xlat/ipccalls.h xlat/ipc_msg_flags.h xlat/ip_cmsg_types.h xlat/itimer_which.h xlat/kcmp_types.h xlat/kexec_arch_values.h xlat/kexec_file_load_flags.h xlat/kexec_load_flags.h xlat/keyctl_commands.h xlat/key_perms.h xlat/key_reqkeys.h xlat/key_spec.h xlat/lockfcmds.h xlat/loop_crypt_type_options.h xlat/loop_flags_options.h xlat/madvise_cmds.h xlat/mbindflags.h xlat/mctl_sync.h xlat/membarrier_cmds.h xlat/memfd_create_flags.h xlat/mempolicyflags.h xlat/mlockall_flags.h xlat/mlock_flags.h xlat/mmap_flags.h xlat/mmap_prot.h xlat/modem_flags.h xlat/modetypes.h xlat/module_init_flags.h xlat/mount_flags.h xlat/move_pages_flags.h xlat/mremap_flags.h xlat/msgctl_flags.h xlat/msg_flags.h xlat/mtd_file_mode_options.h xlat/mtd_flags_options.h xlat/mtd_mode_options.h xlat/mtd_nandecc_options.h xlat/mtd_otp_options.h xlat/mtd_type_options.h xlat/netlink_flags.h xlat/netlink_protocols.h xlat/netlink_types.h xlat/notifyflags.h xlat/nt_descriptor_types.h xlat/open_access_modes.h xlat/open_mode_flags.h xlat/openmodessol.h xlat/packet_mreq_type.h xlat/perf_event_open_flags.h xlat/personality_flags.h xlat/personality_types.h xlat/policies.h xlat/pollflags.h xlat/pr_cap_ambient.h xlat/prctl_options.h xlat/priorities.h xlat/pr_mce_kill.h xlat/pr_mce_kill_policy.h xlat/pr_set_mm.h xlat/pr_tsc.h xlat/pr_unalign_flags.h xlat/ptp_flags_options.h xlat/ptrace_cmds.h xlat/ptrace_events.h xlat/ptrace_peeksiginfo_flags.h xlat/ptrace_setoptions_flags.h xlat/quotacmds.h xlat/quota_formats.h xlat/quotatypes.h xlat/rename_flags.h xlat/resource_flags.h xlat/resources.h xlat/rwf_flags.h xlat/sa_handler_values.h xlat/sched_flags.h xlat/schedulers.h xlat/scmvals.h xlat/secbits.h xlat/seccomp_filter_flags.h xlat/seccomp_mode.h xlat/seccomp_ops.h xlat/seccomp_ret_action.h xlat/semctl_flags.h xlat/semop_flags.h xlat/setsockipoptions.h xlat/setsockipv6options.h xlat/sfd_flags.h xlat/sg_io_dxfer_direction.h xlat/shmctl_flags.h xlat/shm_flags.h xlat/shm_resource_flags.h xlat/shutdown_modes.h xlat/sigact_flags.h xlat/sigaltstack_flags.h xlat/sigbus_codes.h xlat/sigchld_codes.h xlat/sigemt_codes.h xlat/sigev_value.h xlat/sigfpe_codes.h xlat/sigill_codes.h xlat/siginfo_codes.h xlat/sigpoll_codes.h xlat/sigprocmaskcmds.h xlat/sigprof_codes.h xlat/sigsegv_codes.h xlat/sigsys_codes.h xlat/sigtrap_codes.h xlat/socketcalls.h xlat/socketlayers.h xlat/sockipoptions.h xlat/sockipv6options.h xlat/sockipxoptions.h xlat/sockoptions.h xlat/sockpacketoptions.h xlat/sockrawoptions.h xlat/socksctpoptions.h xlat/socktcpoptions.h xlat/sock_type_flags.h xlat/socktypes.h xlat/splice_flags.h xlat/sram_alloc_flags.h xlat/statfs_flags.h xlat/swap_flags.h xlat/sync_file_range_flags.h xlat/sysctl_kern.h xlat/sysctl_net_core.h xlat/sysctl_net.h xlat/sysctl_net_ipv4_conf.h xlat/sysctl_net_ipv4.h xlat/sysctl_net_ipv4_route.h xlat/sysctl_net_ipv6.h xlat/sysctl_net_ipv6_route.h xlat/sysctl_net_unix.h xlat/sysctl_root.h xlat/sysctl_vm.h xlat/syslog_action_type.h xlat/sysmips_operations.h xlat/tcflsh_options.h xlat/tcxonc_options.h xlat/timerfdflags.h xlat/ubi_volume_props.h xlat/ubi_volume_types.h xlat/uffd_api_flags.h xlat/uffd_copy_flags.h xlat/uffd_flags.h xlat/uffd_register_ioctl_flags.h xlat/uffd_register_mode_flags.h xlat/uffd_zeropage_flags.h xlat/umount_flags.h xlat/usagewho.h xlat/v4l2_buf_flags.h xlat/v4l2_buf_types.h xlat/v4l2_capture_modes.h xlat/v4l2_colorspaces.h xlat/v4l2_control_classes.h xlat/v4l2_control_flags.h xlat/v4l2_control_ids.h xlat/v4l2_control_types.h xlat/v4l2_device_capabilities_flags.h xlat/v4l2_fields.h xlat/v4l2_format_description_flags.h xlat/v4l2_frameinterval_types.h xlat/v4l2_framesize_types.h xlat/v4l2_input_types.h xlat/v4l2_memories.h xlat/v4l2_streaming_capabilities.h xlat/wait4_options.h xlat/waitid_types.h xlat/whence_codes.h xlat/xattrflags.h xlat/xfs_dqblk_flags.h xlat/xfs_quota_flags.h 
 $(top_srcdir)/xlat/access_flags.h: $(top_srcdir)/xlat/access_flags.in $(top_srcdir)/xlat/gen.sh
 	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@
 $(top_srcdir)/xlat/aclipc.h: $(top_srcdir)/xlat/aclipc.in $(top_srcdir)/xlat/gen.sh
@@ -384,6 +384,8 @@
 	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@
 $(top_srcdir)/xlat/rwf_flags.h: $(top_srcdir)/xlat/rwf_flags.in $(top_srcdir)/xlat/gen.sh
 	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@
+$(top_srcdir)/xlat/sa_handler_values.h: $(top_srcdir)/xlat/sa_handler_values.in $(top_srcdir)/xlat/gen.sh
+	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@
 $(top_srcdir)/xlat/sched_flags.h: $(top_srcdir)/xlat/sched_flags.in $(top_srcdir)/xlat/gen.sh
 	$(AM_V_GEN)$(top_srcdir)/xlat/gen.sh $< $@
 $(top_srcdir)/xlat/schedulers.h: $(top_srcdir)/xlat/schedulers.in $(top_srcdir)/xlat/gen.sh
diff --git a/xlat/bpf_map_types.h b/xlat/bpf_map_types.h
index 2ce223a..c77f47b 100644
--- a/xlat/bpf_map_types.h
+++ b/xlat/bpf_map_types.h
@@ -23,6 +23,9 @@
 #if !(defined(BPF_MAP_TYPE_STACK_TRACE) || (defined(HAVE_DECL_BPF_MAP_TYPE_STACK_TRACE) && HAVE_DECL_BPF_MAP_TYPE_STACK_TRACE))
 # define BPF_MAP_TYPE_STACK_TRACE 7
 #endif
+#if !(defined(BPF_MAP_TYPE_CGROUP_ARRAY) || (defined(HAVE_DECL_BPF_MAP_TYPE_CGROUP_ARRAY) && HAVE_DECL_BPF_MAP_TYPE_CGROUP_ARRAY))
+# define BPF_MAP_TYPE_CGROUP_ARRAY 8
+#endif
 
 #ifdef IN_MPERS
 
@@ -40,6 +43,7 @@
  XLAT(BPF_MAP_TYPE_PERCPU_HASH),
  XLAT(BPF_MAP_TYPE_PERCPU_ARRAY),
  XLAT(BPF_MAP_TYPE_STACK_TRACE),
+ XLAT(BPF_MAP_TYPE_CGROUP_ARRAY),
  XLAT_END
 };
 
diff --git a/xlat/bpf_map_types.in b/xlat/bpf_map_types.in
index b048af1..ccb24f3 100644
--- a/xlat/bpf_map_types.in
+++ b/xlat/bpf_map_types.in
@@ -6,3 +6,4 @@
 BPF_MAP_TYPE_PERCPU_HASH 5
 BPF_MAP_TYPE_PERCPU_ARRAY 6
 BPF_MAP_TYPE_STACK_TRACE 7
+BPF_MAP_TYPE_CGROUP_ARRAY 8
diff --git a/xlat/bpf_prog_types.h b/xlat/bpf_prog_types.h
index 43f3e8e..4f3b445 100644
--- a/xlat/bpf_prog_types.h
+++ b/xlat/bpf_prog_types.h
@@ -17,6 +17,9 @@
 #if !(defined(BPF_PROG_TYPE_TRACEPOINT) || (defined(HAVE_DECL_BPF_PROG_TYPE_TRACEPOINT) && HAVE_DECL_BPF_PROG_TYPE_TRACEPOINT))
 # define BPF_PROG_TYPE_TRACEPOINT 5
 #endif
+#if !(defined(BPF_PROG_TYPE_XDP) || (defined(HAVE_DECL_BPF_PROG_TYPE_XDP) && HAVE_DECL_BPF_PROG_TYPE_XDP))
+# define BPF_PROG_TYPE_XDP 6
+#endif
 
 #ifdef IN_MPERS
 
@@ -32,6 +35,7 @@
  XLAT(BPF_PROG_TYPE_SCHED_CLS),
  XLAT(BPF_PROG_TYPE_SCHED_ACT),
  XLAT(BPF_PROG_TYPE_TRACEPOINT),
+ XLAT(BPF_PROG_TYPE_XDP),
  XLAT_END
 };
 
diff --git a/xlat/bpf_prog_types.in b/xlat/bpf_prog_types.in
index e6e8446..16f51d6 100644
--- a/xlat/bpf_prog_types.in
+++ b/xlat/bpf_prog_types.in
@@ -4,3 +4,4 @@
 BPF_PROG_TYPE_SCHED_CLS 3
 BPF_PROG_TYPE_SCHED_ACT 4
 BPF_PROG_TYPE_TRACEPOINT 5
+BPF_PROG_TYPE_XDP 6
diff --git a/xlat/ethernet_protocols.h b/xlat/ethernet_protocols.h
index 142fee9..035ca8c 100644
--- a/xlat/ethernet_protocols.h
+++ b/xlat/ethernet_protocols.h
@@ -143,6 +143,9 @@
 #if defined(ETH_P_1588) || (defined(HAVE_DECL_ETH_P_1588) && HAVE_DECL_ETH_P_1588)
   XLAT(ETH_P_1588),
 #endif
+#if defined(ETH_P_NCSI) || (defined(HAVE_DECL_ETH_P_NCSI) && HAVE_DECL_ETH_P_NCSI)
+  XLAT(ETH_P_NCSI),
+#endif
 #if defined(ETH_P_PRP) || (defined(HAVE_DECL_ETH_P_PRP) && HAVE_DECL_ETH_P_PRP)
   XLAT(ETH_P_PRP),
 #endif
diff --git a/xlat/ethernet_protocols.in b/xlat/ethernet_protocols.in
index df078ba..522d1be 100644
--- a/xlat/ethernet_protocols.in
+++ b/xlat/ethernet_protocols.in
@@ -43,6 +43,7 @@
 ETH_P_8021AH
 ETH_P_MVRP
 ETH_P_1588
+ETH_P_NCSI
 ETH_P_PRP
 ETH_P_FCOE
 ETH_P_TDLS
diff --git a/xlat/falloc_flags.h b/xlat/falloc_flags.h
index 0e34b47..12d1069 100644
--- a/xlat/falloc_flags.h
+++ b/xlat/falloc_flags.h
@@ -1,4 +1,22 @@
 /* Generated by ./xlat/gen.sh from ./xlat/falloc_flags.in; do not edit. */
+#if !(defined(FALLOC_FL_KEEP_SIZE) || (defined(HAVE_DECL_FALLOC_FL_KEEP_SIZE) && HAVE_DECL_FALLOC_FL_KEEP_SIZE))
+# define FALLOC_FL_KEEP_SIZE 0x01
+#endif
+#if !(defined(FALLOC_FL_PUNCH_HOLE) || (defined(HAVE_DECL_FALLOC_FL_PUNCH_HOLE) && HAVE_DECL_FALLOC_FL_PUNCH_HOLE))
+# define FALLOC_FL_PUNCH_HOLE 0x02
+#endif
+#if !(defined(FALLOC_FL_NO_HIDE_STALE) || (defined(HAVE_DECL_FALLOC_FL_NO_HIDE_STALE) && HAVE_DECL_FALLOC_FL_NO_HIDE_STALE))
+# define FALLOC_FL_NO_HIDE_STALE 0x04
+#endif
+#if !(defined(FALLOC_FL_COLLAPSE_RANGE) || (defined(HAVE_DECL_FALLOC_FL_COLLAPSE_RANGE) && HAVE_DECL_FALLOC_FL_COLLAPSE_RANGE))
+# define FALLOC_FL_COLLAPSE_RANGE 0x08
+#endif
+#if !(defined(FALLOC_FL_ZERO_RANGE) || (defined(HAVE_DECL_FALLOC_FL_ZERO_RANGE) && HAVE_DECL_FALLOC_FL_ZERO_RANGE))
+# define FALLOC_FL_ZERO_RANGE 0x10
+#endif
+#if !(defined(FALLOC_FL_INSERT_RANGE) || (defined(HAVE_DECL_FALLOC_FL_INSERT_RANGE) && HAVE_DECL_FALLOC_FL_INSERT_RANGE))
+# define FALLOC_FL_INSERT_RANGE 0x20
+#endif
 
 #ifdef IN_MPERS
 
@@ -8,24 +26,12 @@
 
 static
 const struct xlat falloc_flags[] = {
-#if defined(FALLOC_FL_KEEP_SIZE) || (defined(HAVE_DECL_FALLOC_FL_KEEP_SIZE) && HAVE_DECL_FALLOC_FL_KEEP_SIZE)
-  XLAT(FALLOC_FL_KEEP_SIZE),
-#endif
-#if defined(FALLOC_FL_PUNCH_HOLE) || (defined(HAVE_DECL_FALLOC_FL_PUNCH_HOLE) && HAVE_DECL_FALLOC_FL_PUNCH_HOLE)
-  XLAT(FALLOC_FL_PUNCH_HOLE),
-#endif
-#if defined(FALLOC_FL_NO_HIDE_STALE) || (defined(HAVE_DECL_FALLOC_FL_NO_HIDE_STALE) && HAVE_DECL_FALLOC_FL_NO_HIDE_STALE)
-  XLAT(FALLOC_FL_NO_HIDE_STALE),
-#endif
-#if defined(FALLOC_FL_COLLAPSE_RANGE) || (defined(HAVE_DECL_FALLOC_FL_COLLAPSE_RANGE) && HAVE_DECL_FALLOC_FL_COLLAPSE_RANGE)
-  XLAT(FALLOC_FL_COLLAPSE_RANGE),
-#endif
-#if defined(FALLOC_FL_ZERO_RANGE) || (defined(HAVE_DECL_FALLOC_FL_ZERO_RANGE) && HAVE_DECL_FALLOC_FL_ZERO_RANGE)
-  XLAT(FALLOC_FL_ZERO_RANGE),
-#endif
-#if defined(FALLOC_FL_INSERT_RANGE) || (defined(HAVE_DECL_FALLOC_FL_INSERT_RANGE) && HAVE_DECL_FALLOC_FL_INSERT_RANGE)
-  XLAT(FALLOC_FL_INSERT_RANGE),
-#endif
+ XLAT(FALLOC_FL_KEEP_SIZE),
+ XLAT(FALLOC_FL_PUNCH_HOLE),
+ XLAT(FALLOC_FL_NO_HIDE_STALE),
+ XLAT(FALLOC_FL_COLLAPSE_RANGE),
+ XLAT(FALLOC_FL_ZERO_RANGE),
+ XLAT(FALLOC_FL_INSERT_RANGE),
  XLAT_END
 };
 
diff --git a/xlat/falloc_flags.in b/xlat/falloc_flags.in
index 936e960..9d8ecf2 100644
--- a/xlat/falloc_flags.in
+++ b/xlat/falloc_flags.in
@@ -1,6 +1,6 @@
-FALLOC_FL_KEEP_SIZE
-FALLOC_FL_PUNCH_HOLE
-FALLOC_FL_NO_HIDE_STALE
-FALLOC_FL_COLLAPSE_RANGE
-FALLOC_FL_ZERO_RANGE
-FALLOC_FL_INSERT_RANGE
+FALLOC_FL_KEEP_SIZE      0x01
+FALLOC_FL_PUNCH_HOLE     0x02
+FALLOC_FL_NO_HIDE_STALE  0x04
+FALLOC_FL_COLLAPSE_RANGE 0x08
+FALLOC_FL_ZERO_RANGE     0x10
+FALLOC_FL_INSERT_RANGE   0x20
diff --git a/xlat/fsmagic.h b/xlat/fsmagic.h
index ec1777c..49d4595 100644
--- a/xlat/fsmagic.h
+++ b/xlat/fsmagic.h
@@ -19,11 +19,15 @@
 { 0x00002468,	"MINIX2_SUPER_MAGIC"	},
 { 0x00002478,	"MINIX2_SUPER_MAGIC2"	},
 { 0x00003434,	"NILFS_SUPER_MAGIC"	},
+{ 0x00004244,	"HFS_SUPER_MAGIC"	},
+{ 0x0000482b,	"HFSPLUS_SUPER_MAGIC"	},
 { 0x00004d44,	"MSDOS_SUPER_MAGIC"	},
 { 0x00004d5a,	"MINIX3_SUPER_MAGIC"	},
 { 0x0000517b,	"SMB_SUPER_MAGIC"	},
 { 0x0000564c,	"NCP_SUPER_MAGIC"	},
+{ 0x00005df5,	"EXOFS_SUPER_MAGIC"	},
 { 0x00006969,	"NFS_SUPER_MAGIC"	},
+{ 0x00007275,	"ROMFS_MAGIC"		},
 { 0x000072b6,	"JFFS2_SUPER_MAGIC"	},
 { 0x00009660,	"ISOFS_SUPER_MAGIC"	},
 { 0x00009fa0,	"PROC_SUPER_MAGIC"	},
@@ -38,8 +42,10 @@
 { 0x0027e0eb,	"CGROUP_SUPER_MAGIC"	},
 { 0x00414a53,	"EFS_SUPER_MAGIC"	},
 { 0x00c0ffee,	"HOSTFS_SUPER_MAGIC"	},
+{ 0x00c36400,	"CEPH_SUPER_MAGIC"	},
 { 0x01021994,	"TMPFS_MAGIC"		},
 { 0x01021997,	"V9FS_MAGIC"		},
+{ 0x01161970,	"GFS2_MAGIC"		},
 { 0x012fd16d,	"XIAFS_SUPER_MAGIC"	},
 { 0x012ff7b4,	"XENIX_SUPER_MAGIC"	},
 { 0x012ff7b5,	"SYSV4_SUPER_MAGIC"	},
@@ -49,39 +55,60 @@
 { 0x09041934,	"ANON_INODE_FS_MAGIC"	},
 { 0x0bad1dea,	"FUTEXFS_SUPER_MAGIC"	},
 { 0x11307854,	"MTD_INODE_FS_MAGIC"	},
+{ 0x13661366,	"BALLOON_KVM_MAGIC"	},
 { 0x15013346,	"UDF_SUPER_MAGIC"	},
+{ 0x1badface,	"BFS_MAGIC"		},
+{ 0x24051905,	"UBIFS_SUPER_MAGIC"	},
 { 0x28cd3d45,	"CRAMFS_MAGIC"		},
+{ 0x2fc12fc1,	"ZFS_SUPER_MAGIC"	},
+{ 0x3153464a,	"JFS_SUPER_MAGIC"	},
+{ 0x42465331,	"BEFS_SUPER_MAGIC"	},
 { 0x42494e4d,	"BINFMTFS_MAGIC"	},
 { 0x43415d53,	"SMACK_MAGIC"		},
 { 0x453dcd28,	"CRAMFS_MAGIC_WEND"	},
+{ 0x47504653,	"GPFS_SUPER_MAGIC"	},
 { 0x50495045,	"PIPEFS_MAGIC"		},
 { 0x52654973,	"REISERFS_SUPER_MAGIC"	},
 { 0x5346414f,	"AFS_SUPER_MAGIC"	},
+{ 0x5346544e,	"NTFS_SB_MAGIC"		},
 { 0x534f434b,	"SOCKFS_MAGIC"		},
 { 0x54190100,	"UFS_CIGAM"		},
+{ 0x565a4653,	"VZFS_SUPER_MAGIC"	},
 { 0x57ac6e9d,	"STACK_END_MAGIC"	},
+{ 0x58295829,	"ZSMALLOC_MAGIC"	},
+{ 0x58465342,	"XFS_SB_MAGIC"		},
 { 0x6165676c,	"PSTOREFS_MAGIC"	},
+{ 0x61756673,	"AUFS_SUPER_MAGIC"	},
 { 0x62646576,	"BDEVFS_MAGIC"		},
+{ 0x62656570,	"CONFIGFS_MAGIC"	},
 { 0x62656572,	"SYSFS_MAGIC"		},
 { 0x63677270,	"CGROUP2_SUPER_MAGIC"	},
 { 0x64626720,	"DEBUGFS_MAGIC"		},
+{ 0x65735543,	"FUSE_CTL_SUPER_MAGIC"	},
+{ 0x65735546,	"FUSE_SUPER_MAGIC"	},
 { 0x68191122,	"QNX6_SUPER_MAGIC"	},
+{ 0x6b414653,	"AFS_FS_MAGIC"		},
 { 0x6e736673,	"NSFS_MAGIC"		},
 { 0x73636673,	"SECURITYFS_MAGIC"	},
 { 0x73717368,	"SQUASHFS_MAGIC"	},
 { 0x73727279,	"BTRFS_TEST_MAGIC"	},
 { 0x73757245,	"CODA_SUPER_MAGIC"	},
+{ 0x7461636f,	"OCFS2_SUPER_MAGIC"	},
 { 0x74726163,	"TRACEFS_MAGIC"		},
 { 0x794c7630,	"OVERLAYFS_SUPER_MAGIC"	},
 { 0x858458f6,	"RAMFS_MAGIC"		},
 { 0x9123683e,	"BTRFS_SUPER_MAGIC"	},
 { 0x958458f6,	"HUGETLBFS_MAGIC"	},
+{ 0xa501fcf5,	"VXFS_SUPER_MAGIC"	},
 { 0xabba1974,	"XENFS_SUPER_MAGIC"	},
+{ 0xc97e8168,	"LOGFS_MAGIC"		},
 { 0xcafe4a11,	"BPF_FS_MAGIC"		},
 { 0xde5e81e4,	"EFIVARFS_MAGIC"	},
 { 0xf2f52010,	"F2FS_SUPER_MAGIC"	},
 { 0xf97cff8c,	"SELINUX_MAGIC"		},
 { 0xf995e849,	"HPFS_SUPER_MAGIC"	},
+{ 0xfe534d42,	"SMB2_MAGIC_NUMBER"	},
+{ 0xff534d42,	"CIFS_MAGIC_NUMBER"	},
  /* this array should remain not NULL-terminated */
 };
 
diff --git a/xlat/fsmagic.in b/xlat/fsmagic.in
index f9005b6..538c175 100644
--- a/xlat/fsmagic.in
+++ b/xlat/fsmagic.in
@@ -9,11 +9,15 @@
 { 0x00002468,	"MINIX2_SUPER_MAGIC"	},
 { 0x00002478,	"MINIX2_SUPER_MAGIC2"	},
 { 0x00003434,	"NILFS_SUPER_MAGIC"	},
+{ 0x00004244,	"HFS_SUPER_MAGIC"	},
+{ 0x0000482b,	"HFSPLUS_SUPER_MAGIC"	},
 { 0x00004d44,	"MSDOS_SUPER_MAGIC"	},
 { 0x00004d5a,	"MINIX3_SUPER_MAGIC"	},
 { 0x0000517b,	"SMB_SUPER_MAGIC"	},
 { 0x0000564c,	"NCP_SUPER_MAGIC"	},
+{ 0x00005df5,	"EXOFS_SUPER_MAGIC"	},
 { 0x00006969,	"NFS_SUPER_MAGIC"	},
+{ 0x00007275,	"ROMFS_MAGIC"		},
 { 0x000072b6,	"JFFS2_SUPER_MAGIC"	},
 { 0x00009660,	"ISOFS_SUPER_MAGIC"	},
 { 0x00009fa0,	"PROC_SUPER_MAGIC"	},
@@ -28,8 +32,10 @@
 { 0x0027e0eb,	"CGROUP_SUPER_MAGIC"	},
 { 0x00414a53,	"EFS_SUPER_MAGIC"	},
 { 0x00c0ffee,	"HOSTFS_SUPER_MAGIC"	},
+{ 0x00c36400,	"CEPH_SUPER_MAGIC"	},
 { 0x01021994,	"TMPFS_MAGIC"		},
 { 0x01021997,	"V9FS_MAGIC"		},
+{ 0x01161970,	"GFS2_MAGIC"		},
 { 0x012fd16d,	"XIAFS_SUPER_MAGIC"	},
 { 0x012ff7b4,	"XENIX_SUPER_MAGIC"	},
 { 0x012ff7b5,	"SYSV4_SUPER_MAGIC"	},
@@ -39,37 +45,58 @@
 { 0x09041934,	"ANON_INODE_FS_MAGIC"	},
 { 0x0bad1dea,	"FUTEXFS_SUPER_MAGIC"	},
 { 0x11307854,	"MTD_INODE_FS_MAGIC"	},
+{ 0x13661366,	"BALLOON_KVM_MAGIC"	},
 { 0x15013346,	"UDF_SUPER_MAGIC"	},
+{ 0x1badface,	"BFS_MAGIC"		},
+{ 0x24051905,	"UBIFS_SUPER_MAGIC"	},
 { 0x28cd3d45,	"CRAMFS_MAGIC"		},
+{ 0x2fc12fc1,	"ZFS_SUPER_MAGIC"	},
+{ 0x3153464a,	"JFS_SUPER_MAGIC"	},
+{ 0x42465331,	"BEFS_SUPER_MAGIC"	},
 { 0x42494e4d,	"BINFMTFS_MAGIC"	},
 { 0x43415d53,	"SMACK_MAGIC"		},
 { 0x453dcd28,	"CRAMFS_MAGIC_WEND"	},
+{ 0x47504653,	"GPFS_SUPER_MAGIC"	},
 { 0x50495045,	"PIPEFS_MAGIC"		},
 { 0x52654973,	"REISERFS_SUPER_MAGIC"	},
 { 0x5346414f,	"AFS_SUPER_MAGIC"	},
+{ 0x5346544e,	"NTFS_SB_MAGIC"		},
 { 0x534f434b,	"SOCKFS_MAGIC"		},
 { 0x54190100,	"UFS_CIGAM"		},
+{ 0x565a4653,	"VZFS_SUPER_MAGIC"	},
 { 0x57ac6e9d,	"STACK_END_MAGIC"	},
+{ 0x58295829,	"ZSMALLOC_MAGIC"	},
+{ 0x58465342,	"XFS_SB_MAGIC"		},
 { 0x6165676c,	"PSTOREFS_MAGIC"	},
+{ 0x61756673,	"AUFS_SUPER_MAGIC"	},
 { 0x62646576,	"BDEVFS_MAGIC"		},
+{ 0x62656570,	"CONFIGFS_MAGIC"	},
 { 0x62656572,	"SYSFS_MAGIC"		},
 { 0x63677270,	"CGROUP2_SUPER_MAGIC"	},
 { 0x64626720,	"DEBUGFS_MAGIC"		},
+{ 0x65735543,	"FUSE_CTL_SUPER_MAGIC"	},
+{ 0x65735546,	"FUSE_SUPER_MAGIC"	},
 { 0x68191122,	"QNX6_SUPER_MAGIC"	},
+{ 0x6b414653,	"AFS_FS_MAGIC"		},
 { 0x6e736673,	"NSFS_MAGIC"		},
 { 0x73636673,	"SECURITYFS_MAGIC"	},
 { 0x73717368,	"SQUASHFS_MAGIC"	},
 { 0x73727279,	"BTRFS_TEST_MAGIC"	},
 { 0x73757245,	"CODA_SUPER_MAGIC"	},
+{ 0x7461636f,	"OCFS2_SUPER_MAGIC"	},
 { 0x74726163,	"TRACEFS_MAGIC"		},
 { 0x794c7630,	"OVERLAYFS_SUPER_MAGIC"	},
 { 0x858458f6,	"RAMFS_MAGIC"		},
 { 0x9123683e,	"BTRFS_SUPER_MAGIC"	},
 { 0x958458f6,	"HUGETLBFS_MAGIC"	},
+{ 0xa501fcf5,	"VXFS_SUPER_MAGIC"	},
 { 0xabba1974,	"XENFS_SUPER_MAGIC"	},
+{ 0xc97e8168,	"LOGFS_MAGIC"		},
 { 0xcafe4a11,	"BPF_FS_MAGIC"		},
 { 0xde5e81e4,	"EFIVARFS_MAGIC"	},
 { 0xf2f52010,	"F2FS_SUPER_MAGIC"	},
 { 0xf97cff8c,	"SELINUX_MAGIC"		},
 { 0xf995e849,	"HPFS_SUPER_MAGIC"	},
+{ 0xfe534d42,	"SMB2_MAGIC_NUMBER"	},
+{ 0xff534d42,	"CIFS_MAGIC_NUMBER"	},
 #unterminated
diff --git a/xlat/futexops.h b/xlat/futexops.h
index 536b162..4efc761 100644
--- a/xlat/futexops.h
+++ b/xlat/futexops.h
@@ -111,6 +111,12 @@
  XLAT(FUTEX_WAKE_BITSET_PRIVATE),
  XLAT(FUTEX_WAIT_REQUEUE_PI_PRIVATE),
  XLAT(FUTEX_CMP_REQUEUE_PI_PRIVATE),
+#if defined(FUTEX_WAIT) || (defined(HAVE_DECL_FUTEX_WAIT) && HAVE_DECL_FUTEX_WAIT)
+  XLAT(FUTEX_WAIT|FUTEX_CLOCK_REALTIME),
+#endif
+#if defined(FUTEX_WAIT_PRIVATE) || (defined(HAVE_DECL_FUTEX_WAIT_PRIVATE) && HAVE_DECL_FUTEX_WAIT_PRIVATE)
+  XLAT(FUTEX_WAIT_PRIVATE|FUTEX_CLOCK_REALTIME),
+#endif
 #if defined(FUTEX_WAIT_BITSET) || (defined(HAVE_DECL_FUTEX_WAIT_BITSET) && HAVE_DECL_FUTEX_WAIT_BITSET)
   XLAT(FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME),
 #endif
diff --git a/xlat/futexops.in b/xlat/futexops.in
index 3372673..3e589ab 100644
--- a/xlat/futexops.in
+++ b/xlat/futexops.in
@@ -24,6 +24,8 @@
 FUTEX_WAKE_BITSET_PRIVATE	(FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
 FUTEX_WAIT_REQUEUE_PI_PRIVATE	(FUTEX_WAIT_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
 FUTEX_CMP_REQUEUE_PI_PRIVATE	(FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
+FUTEX_WAIT|FUTEX_CLOCK_REALTIME
+FUTEX_WAIT_PRIVATE|FUTEX_CLOCK_REALTIME
 FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME
 FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME
 FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME
diff --git a/xlat/gen.sh b/xlat/gen.sh
index cf78c47..ec63280 100755
--- a/xlat/gen.sh
+++ b/xlat/gen.sh
@@ -44,11 +44,11 @@
 
 	local val
 	val="$(printf %s "$line" |
-		sed -n 's/^\([^[:space:]]\+\).*$/\1/p')"
+		sed -r -n 's/^([^[:space:]]+).*$/\1/p')"
 
 	local def
 	def="$(printf %s "${line}" |
-		sed -n 's/^[^[:space:]]\+[[:space:]]\+\([^[:space:]].*\)$/\1/p')"
+		sed -r -n 's/^[^[:space:]]+[[:space:]]+([^[:space:]].*)$/\1/p')"
 
 	if [ -n "$def" ]; then
 		cat <<-EOF
@@ -89,10 +89,10 @@
 	local line val m def xlat
 	line="$1"; shift
 
-	val="$(printf %s "${line}" | sed -n 's/^\([^[:space:]]\+\).*$/\1/p')"
+	val="$(printf %s "${line}" | sed -r -n 's/^([^[:space:]]+).*$/\1/p')"
 	m="${val%%|*}"
 	def="$(printf %s "${line}" |
-	       sed -n 's/^[^[:space:]]\+[[:space:]]\+\([^[:space:]].*\)$/\1/p')"
+	       sed -r -n 's/^[^[:space:]]+[[:space:]]+([^[:space:]].*)$/\1/p')"
 
 	if [ "${m}" = "${m#1<<}" ]; then
 		xlat="$(print_xlat "${val}")"
diff --git a/xlat/kexec_arch_values.h b/xlat/kexec_arch_values.h
index 1850d94..537ba4b 100644
--- a/xlat/kexec_arch_values.h
+++ b/xlat/kexec_arch_values.h
@@ -35,6 +35,9 @@
 #if !(defined(KEXEC_ARCH_MIPS) || (defined(HAVE_DECL_KEXEC_ARCH_MIPS) && HAVE_DECL_KEXEC_ARCH_MIPS))
 # define KEXEC_ARCH_MIPS ( 8 << 16)
 #endif
+#if !(defined(KEXEC_ARCH_AARCH64) || (defined(HAVE_DECL_KEXEC_ARCH_AARCH64) && HAVE_DECL_KEXEC_ARCH_AARCH64))
+# define KEXEC_ARCH_AARCH64 (183 << 16)
+#endif
 
 #ifdef IN_MPERS
 
@@ -56,6 +59,7 @@
  XLAT(KEXEC_ARCH_SH),
  XLAT(KEXEC_ARCH_MIPS_LE),
  XLAT(KEXEC_ARCH_MIPS),
+ XLAT(KEXEC_ARCH_AARCH64),
  XLAT_END
 };
 
diff --git a/xlat/kexec_arch_values.in b/xlat/kexec_arch_values.in
index 66d25bf..c56e8eb 100644
--- a/xlat/kexec_arch_values.in
+++ b/xlat/kexec_arch_values.in
@@ -10,3 +10,4 @@
 KEXEC_ARCH_SH      (42 << 16)
 KEXEC_ARCH_MIPS_LE (10 << 16)
 KEXEC_ARCH_MIPS    ( 8 << 16)
+KEXEC_ARCH_AARCH64 (183 << 16)
diff --git a/xlat/ptrace_cmds.h b/xlat/ptrace_cmds.h
index 0a8e0f0..ee9ebe2 100644
--- a/xlat/ptrace_cmds.h
+++ b/xlat/ptrace_cmds.h
@@ -277,6 +277,18 @@
 #if defined(PTRACE_SETFPAREGS) || (defined(HAVE_DECL_PTRACE_SETFPAREGS) && HAVE_DECL_PTRACE_SETFPAREGS)
   XLAT(PTRACE_SETFPAREGS),
 #endif
+#if defined(PTRACE_GETREGS64) || (defined(HAVE_DECL_PTRACE_GETREGS64) && HAVE_DECL_PTRACE_GETREGS64)
+  XLAT(PTRACE_GETREGS64),
+#endif
+#if defined(PTRACE_SETREGS64) || (defined(HAVE_DECL_PTRACE_SETREGS64) && HAVE_DECL_PTRACE_SETREGS64)
+  XLAT(PTRACE_SETREGS64),
+#endif
+#if defined(PTRACE_GETFPREGS64) || (defined(HAVE_DECL_PTRACE_GETFPREGS64) && HAVE_DECL_PTRACE_GETFPREGS64)
+  XLAT(PTRACE_GETFPREGS64),
+#endif
+#if defined(PTRACE_SETFPREGS64) || (defined(HAVE_DECL_PTRACE_SETFPREGS64) && HAVE_DECL_PTRACE_SETFPREGS64)
+  XLAT(PTRACE_SETFPREGS64),
+#endif
 /* x86 */
 #if defined(PTRACE_ARCH_PRCTL) || (defined(HAVE_DECL_PTRACE_ARCH_PRCTL) && HAVE_DECL_PTRACE_ARCH_PRCTL)
   XLAT(PTRACE_ARCH_PRCTL),
diff --git a/xlat/ptrace_cmds.in b/xlat/ptrace_cmds.in
index 5e4da83..525494d 100644
--- a/xlat/ptrace_cmds.in
+++ b/xlat/ptrace_cmds.in
@@ -93,6 +93,10 @@
 PTRACE_WRITETEXT
 PTRACE_GETFPAREGS
 PTRACE_SETFPAREGS
+PTRACE_GETREGS64
+PTRACE_SETREGS64
+PTRACE_GETFPREGS64
+PTRACE_SETFPREGS64
 /* x86 */
 PTRACE_ARCH_PRCTL
 PTRACE_SYSEMU
diff --git a/xlat/sa_handler_values.h b/xlat/sa_handler_values.h
new file mode 100644
index 0000000..3d7da04
--- /dev/null
+++ b/xlat/sa_handler_values.h
@@ -0,0 +1,23 @@
+/* Generated by ./xlat/gen.sh from ./xlat/sa_handler_values.in; do not edit. */
+
+#ifdef IN_MPERS
+
+# error static const struct xlat sa_handler_values in mpers mode
+
+#else
+
+static
+const struct xlat sa_handler_values[] = {
+#if defined(SIG_ERR) || (defined(HAVE_DECL_SIG_ERR) && HAVE_DECL_SIG_ERR)
+  XLAT_TYPE(unsigned long, SIG_ERR),
+#endif
+#if defined(SIG_DFL) || (defined(HAVE_DECL_SIG_DFL) && HAVE_DECL_SIG_DFL)
+  XLAT_TYPE(unsigned long, SIG_DFL),
+#endif
+#if defined(SIG_IGN) || (defined(HAVE_DECL_SIG_IGN) && HAVE_DECL_SIG_IGN)
+  XLAT_TYPE(unsigned long, SIG_IGN),
+#endif
+ XLAT_END
+};
+
+#endif /* !IN_MPERS */
diff --git a/xlat/sa_handler_values.in b/xlat/sa_handler_values.in
new file mode 100644
index 0000000..e907611
--- /dev/null
+++ b/xlat/sa_handler_values.in
@@ -0,0 +1,4 @@
+#val_type unsigned long
+SIG_ERR
+SIG_DFL
+SIG_IGN
diff --git a/xlat/socksctpoptions.h b/xlat/socksctpoptions.h
index 7aa20db..cb34b9b 100644
--- a/xlat/socksctpoptions.h
+++ b/xlat/socksctpoptions.h
@@ -153,6 +153,15 @@
 #if defined(SCTP_GET_ASSOC_STATS) || (defined(HAVE_DECL_SCTP_GET_ASSOC_STATS) && HAVE_DECL_SCTP_GET_ASSOC_STATS)
   XLAT(SCTP_GET_ASSOC_STATS),
 #endif
+#if defined(SCTP_PR_SUPPORTED) || (defined(HAVE_DECL_SCTP_PR_SUPPORTED) && HAVE_DECL_SCTP_PR_SUPPORTED)
+  XLAT(SCTP_PR_SUPPORTED),
+#endif
+#if defined(SCTP_DEFAULT_PRINFO) || (defined(HAVE_DECL_SCTP_DEFAULT_PRINFO) && HAVE_DECL_SCTP_DEFAULT_PRINFO)
+  XLAT(SCTP_DEFAULT_PRINFO),
+#endif
+#if defined(SCTP_PR_ASSOC_STATUS) || (defined(HAVE_DECL_SCTP_PR_ASSOC_STATUS) && HAVE_DECL_SCTP_PR_ASSOC_STATUS)
+  XLAT(SCTP_PR_ASSOC_STATUS),
+#endif
  XLAT_END
 };
 
diff --git a/xlat/socksctpoptions.in b/xlat/socksctpoptions.in
index 8af43b7..fa967a2 100644
--- a/xlat/socksctpoptions.in
+++ b/xlat/socksctpoptions.in
@@ -47,3 +47,6 @@
 SCTP_SOCKOPT_CONNECTX
 SCTP_SOCKOPT_CONNECTX3
 SCTP_GET_ASSOC_STATS
+SCTP_PR_SUPPORTED
+SCTP_DEFAULT_PRINFO
+SCTP_PR_ASSOC_STATUS
diff --git a/xlat/socktcpoptions.h b/xlat/socktcpoptions.h
index 23f0770..7dd5923 100644
--- a/xlat/socktcpoptions.h
+++ b/xlat/socktcpoptions.h
@@ -92,6 +92,9 @@
 #if defined(TCP_SAVED_SYN) || (defined(HAVE_DECL_TCP_SAVED_SYN) && HAVE_DECL_TCP_SAVED_SYN)
   XLAT(TCP_SAVED_SYN),
 #endif
+#if defined(TCP_REPAIR_WINDOW) || (defined(HAVE_DECL_TCP_REPAIR_WINDOW) && HAVE_DECL_TCP_REPAIR_WINDOW)
+  XLAT(TCP_REPAIR_WINDOW),
+#endif
  XLAT_END
 };
 
diff --git a/xlat/socktcpoptions.in b/xlat/socktcpoptions.in
index b454e10..89bbd7e 100644
--- a/xlat/socktcpoptions.in
+++ b/xlat/socktcpoptions.in
@@ -26,3 +26,4 @@
 TCP_CC_INFO
 TCP_SAVE_SYN
 TCP_SAVED_SYN
+TCP_REPAIR_WINDOW