is_negated_errno: merge x86_64 and x32 definitions

* syscall.c (kernel_long_t, kernel_ulong_t): New types.
(is_negated_errno): Merge [X32] and [!X32] definitions.
(get_error): Merge [X86_64] and [X32] code.
diff --git a/syscall.c b/syscall.c
index 33791f0..c5681e2 100644
--- a/syscall.c
+++ b/syscall.c
@@ -2216,29 +2216,37 @@
 }
 
 /*
+ * Cannot rely on __kernel_[u]long_t being defined,
+ * it is quite a recent feature of <asm/posix_types.h>.
+ */
+#ifdef __kernel_long_t
+typedef __kernel_long_t kernel_long_t;
+typedef __kernel_ulong_t kernel_ulong_t;
+#else
+# ifdef X32
+typedef long long kernel_long_t;
+typedef unsigned long long kernel_ulong_t;
+# else
+typedef long kernel_long_t;
+typedef unsigned long kernel_ulong_t;
+# endif
+#endif
+
+/*
  * Check the syscall return value register value for whether it is
  * a negated errno code indicating an error, or a success return value.
  */
-#ifndef X32
-static inline int
-is_negated_errno(unsigned long int val)
+static inline bool
+is_negated_errno(kernel_ulong_t val)
 {
-	unsigned long int max = -(long int) nerrnos;
+	kernel_ulong_t max = -(kernel_long_t) nerrnos;
+
 #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
 	if (current_wordsize < sizeof(val)) {
-		val = (unsigned int) val;
-		max = (unsigned int) max;
+		val = (uint32_t) val;
+		max = (uint32_t) max;
 	}
-#endif
-	return val > max;
-}
-
-#else /* X32 */
-
-static inline int
-is_negated_errno(unsigned long long val)
-{
-	unsigned long long max = -(long long) nerrnos;
+#elif defined X32
 	/*
 	 * current_wordsize is 4 even in personality 0 (native X32)
 	 * but truncation _must not_ be done in it.
@@ -2248,9 +2256,10 @@
 		val = (uint32_t) val;
 		max = (uint32_t) max;
 	}
+#endif
+
 	return val > max;
 }
-#endif /* X32 */
 
 /* Returns:
  * 1: ok, continue in trace_syscall_exiting().
@@ -2281,11 +2290,16 @@
 	else {
 		tcp->u_rval = i386_regs.eax;
 	}
-#elif defined(X86_64)
-	long rax;
+#elif defined(X86_64) || defined(X32)
+	/*
+	 * In X32, return value is 64-bit (llseek uses one).
+	 * Using merely "long rax" would not work.
+	 */
+	kernel_long_t rax;
+
 	if (x86_io.iov_len == sizeof(i386_regs)) {
 		/* Sign extend from 32 bits */
-		rax = (int32_t)i386_regs.eax;
+		rax = (int32_t) i386_regs.eax;
 	} else {
 		rax = x86_64_regs.rax;
 	}
@@ -2295,25 +2309,10 @@
 	}
 	else {
 		tcp->u_rval = rax;
-	}
-#elif defined(X32)
-	/* In X32, return value is 64-bit (llseek uses one).
-	 * Using merely "long rax" would not work.
-	 */
-	long long rax;
-	if (x86_io.iov_len == sizeof(i386_regs)) {
-		/* Sign extend from 32 bits */
-		rax = (int32_t)i386_regs.eax;
-	} else {
-		rax = x86_64_regs.rax;
-	}
-	if (check_errno && is_negated_errno(rax)) {
-		tcp->u_rval = -1;
-		u_error = -rax;
-	}
-	else {
-		tcp->u_rval = rax; /* truncating */
+# ifdef X32
+		/* tcp->u_rval contains a truncated value */
 		tcp->u_lrval = rax;
+# endif
 	}
 #elif defined(IA64)
 	if (ia64_ia32mode) {