Fix decoding of 16-bit *chown and [gs]et*[gu]id syscalls

Define two sets of parsers on architectures that support (either
directly or via multiarch) 16-bit and 32-bit uid/gid syscalls
simultaneously.  Since the code in these two sets is essentially
the same and the key difference between them is the size of uid_t,
implement it by parametrizing uid_t and names of parser functions.

* defs.h (NEED_UID16_PARSERS): New macro.
* linux/syscall.h [NEED_UID16_PARSERS] (sys_chown16, sys_fchown16,
sys_getresuid16, sys_getuid16, sys_setfsuid16, sys_setresuid16,
sys_setreuid16, sys_setuid16): New prototypes.
* linux/dummy.h (sys_geteuid16): Alias to sys_getuid16.
(sys_getegid16, sys_getgid16, sys_getresgid16, sys_setfsgid16,
sys_setgid16, sys_setregid16, sys_setresgid16): Alias to corresponding
sys_*uid16 functions.
* uid.c: Stop including <asm/posix_types.h>.
Parametrize uid_t and names of all exported functions.
(get_print_uid): New function.
(sys_getresuid): Use it.
(printuid): Check for (uid_t) -1.
* uid16.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* linux/arm/syscallent.h: Use sys_chown16, sys_fchown16, sys_getegid16,
sys_geteuid16, sys_getgid16, sys_getresgid16, sys_getresuid16,
sys_getuid16, sys_setfsgid16, sys_setfsuid16, sys_setgid16,
sys_setregid16, sys_setresgid16, sys_setresuid16, sys_setreuid16,
and sys_setuid16 parsers for *chown and [gs]et*[gu]id syscall entries.
* linux/bfin/syscallent.h: Likewise.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/microblaze/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* tests/uid16.c: New file.
* tests/uid16.test: New test.
* tests/Makefile.am (CHECK_PROGRAMS): Add uid16.
(TESTS): Add uid16.test.
* tests/.gitignore: Add uid16.
diff --git a/uid.c b/uid.c
index bab6c5e..376d059 100644
--- a/uid.c
+++ b/uid.c
@@ -1,6 +1,39 @@
+#ifdef STRACE_UID_SIZE
+# if STRACE_UID_SIZE != 16
+#  error invalid STRACE_UID_SIZE
+# endif
+
+# define SIZEIFY(x)		SIZEIFY_(x,STRACE_UID_SIZE)
+# define SIZEIFY_(x,size)	SIZEIFY__(x,size)
+# define SIZEIFY__(x,size)	x ## size
+
+# define sys_getuid	SIZEIFY(sys_getuid)
+# define sys_setfsuid	SIZEIFY(sys_setfsuid)
+# define sys_setuid	SIZEIFY(sys_setuid)
+# define sys_getresuid	SIZEIFY(sys_getresuid)
+# define sys_setreuid	SIZEIFY(sys_setreuid)
+# define sys_setresuid	SIZEIFY(sys_setresuid)
+# define sys_chown	SIZEIFY(sys_chown)
+# define sys_fchown	SIZEIFY(sys_fchown)
+# define printuid	SIZEIFY(printuid)
+#endif /* STRACE_UID_SIZE */
+
 #include "defs.h"
 
-#include <asm/posix_types.h>
+#ifdef STRACE_UID_SIZE
+# if !NEED_UID16_PARSERS
+#  undef STRACE_UID_SIZE
+# endif
+#else
+# define STRACE_UID_SIZE 32
+#endif
+
+#ifdef STRACE_UID_SIZE
+
+# undef uid_t
+# define uid_t		uid_t_(STRACE_UID_SIZE)
+# define uid_t_(size)	uid_t__(size)
+# define uid_t__(size)	uint ## size ## _t
 
 int
 sys_getuid(struct tcb *tcp)
@@ -29,27 +62,28 @@
 	return 0;
 }
 
+static void
+get_print_uid(struct tcb *tcp, const char *prefix, const long addr)
+{
+	uid_t uid;
+
+	if (umove(tcp, addr, &uid) < 0)
+		tprintf("%s%#lx", prefix, addr);
+	else
+		tprintf("%s[%u]", prefix, uid);
+}
+
 int
 sys_getresuid(struct tcb *tcp)
 {
 	if (exiting(tcp)) {
-		__kernel_uid_t uid;
-		if (syserror(tcp))
+		if (syserror(tcp)) {
 			tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
 				tcp->u_arg[1], tcp->u_arg[2]);
-		else {
-			if (umove(tcp, tcp->u_arg[0], &uid) < 0)
-				tprintf("%#lx, ", tcp->u_arg[0]);
-			else
-				tprintf("[%lu], ", (unsigned long) uid);
-			if (umove(tcp, tcp->u_arg[1], &uid) < 0)
-				tprintf("%#lx, ", tcp->u_arg[1]);
-			else
-				tprintf("[%lu], ", (unsigned long) uid);
-			if (umove(tcp, tcp->u_arg[2], &uid) < 0)
-				tprintf("%#lx", tcp->u_arg[2]);
-			else
-				tprintf("[%lu]", (unsigned long) uid);
+		} else {
+			get_print_uid(tcp, "", tcp->u_arg[0]);
+			get_print_uid(tcp, ", ", tcp->u_arg[1]);
+			get_print_uid(tcp, ", ", tcp->u_arg[2]);
 		}
 	}
 	return 0;
@@ -101,8 +135,10 @@
 void
 printuid(const char *text, const unsigned int uid)
 {
-	if ((unsigned int) -1 == uid)
+	if ((unsigned int) -1 == uid || (uid_t) -1 == uid)
 		tprintf("%s-1", text);
 	else
 		tprintf("%s%u", text, uid);
 }
+
+#endif /* STRACE_UID_SIZE */