Implement prlimit64 decoding, rewrite [gs]etrlimit decoding

* configure.ac: Remove AC_RLIM_T_IS_LONG_LONG call.
Define SIZEOF_RLIM_T.
* m4/long_long.m4 (AC_RLIM_T_IS_LONG_LONG): Remove.
* linux/dummy.h (sys_prlimit64): Remove.
* linux/syscall.h (sys_prlimit64): New prototype.
* resource.c (resources): Reindent, add RLIMIT_RTTIME.
(sprintrlim, print_rlimit32, sys_getrlimit, sys_setrlimit): Remove.
[HAVE_LONG_LONG_RLIM_T]: Remove dead code.
[_LFS64_LARGEFILE || HAVE_LONG_LONG_RLIM_T]: Likewise.
(sprint_rlim64, print_rlimit64, decode_rlimit64, sprint_rlim32,
print_rlimit32, decode_rlimit, sys_getrlimit, sys_setrlimit,
sys_prlimit64): New functions.
diff --git a/resource.c b/resource.c
index 631aa4a..77a94a2 100644
--- a/resource.c
+++ b/resource.c
@@ -33,37 +33,24 @@
 #include <sys/times.h>
 #include <linux/kernel.h>
 
-#if HAVE_LONG_LONG_RLIM_T
-/*
- * Hacks for systems that have a long long rlim_t
- */
-# define rlimit64 rlimit			/* Ugly hack */
-# define rlim64_t rlim_t			/* Ugly hack */
-# ifndef RLIM64_INFINITY
-#  define RLIM64_INFINITY RLIM_INFINITY	/* You guessed it */
-# endif
-# define sys_getrlimit64	sys_getrlimit
-# define sys_setrlimit64	sys_setrlimit
-#endif
-
 static const struct xlat resources[] = {
 #ifdef RLIMIT_AS
-	{ RLIMIT_AS,	"RLIMIT_AS"	},
+	{ RLIMIT_AS,		"RLIMIT_AS"		},
 #endif
 #ifdef RLIMIT_CORE
-	{ RLIMIT_CORE,	"RLIMIT_CORE"	},
+	{ RLIMIT_CORE,		"RLIMIT_CORE"		},
 #endif
 #ifdef RLIMIT_CPU
-	{ RLIMIT_CPU,	"RLIMIT_CPU"	},
+	{ RLIMIT_CPU,		"RLIMIT_CPU"		},
 #endif
 #ifdef RLIMIT_DATA
-	{ RLIMIT_DATA,	"RLIMIT_DATA"	},
+	{ RLIMIT_DATA,		"RLIMIT_DATA"		},
 #endif
 #ifdef RLIMIT_FSIZE
-	{ RLIMIT_FSIZE,	"RLIMIT_FSIZE"	},
+	{ RLIMIT_FSIZE,		"RLIMIT_FSIZE"		},
 #endif
 #ifdef RLIMIT_LOCKS
-	{ RLIMIT_LOCKS,	"RLIMIT_LOCKS"	},
+	{ RLIMIT_LOCKS,		"RLIMIT_LOCKS"		},
 #endif
 #ifdef RLIMIT_MEMLOCK
 	{ RLIMIT_MEMLOCK,	"RLIMIT_MEMLOCK"	},
@@ -72,92 +59,150 @@
 	{ RLIMIT_MSGQUEUE,	"RLIMIT_MSGQUEUE"	},
 #endif
 #ifdef RLIMIT_NICE
-	{ RLIMIT_NICE,	"RLIMIT_NICE"	},
+	{ RLIMIT_NICE,		"RLIMIT_NICE"		},
 #endif
 #ifdef RLIMIT_NOFILE
-	{ RLIMIT_NOFILE,	"RLIMIT_NOFILE"	},
+	{ RLIMIT_NOFILE,	"RLIMIT_NOFILE"		},
 #endif
 #ifdef RLIMIT_NPROC
-	{ RLIMIT_NPROC,	"RLIMIT_NPROC"	},
+	{ RLIMIT_NPROC,		"RLIMIT_NPROC"		},
 #endif
 #ifdef RLIMIT_RSS
-	{ RLIMIT_RSS,	"RLIMIT_RSS"	},
+	{ RLIMIT_RSS,		"RLIMIT_RSS"		},
 #endif
 #ifdef RLIMIT_RTPRIO
-	{ RLIMIT_RTPRIO,	"RLIMIT_RTPRIO"	},
+	{ RLIMIT_RTPRIO,	"RLIMIT_RTPRIO"		},
+#endif
+#ifdef RLIMIT_RTTIME
+	{ RLIMIT_RTTIME,	"RLIMIT_RTTIME"		},
 #endif
 #ifdef RLIMIT_SIGPENDING
 	{ RLIMIT_SIGPENDING,	"RLIMIT_SIGPENDING"	},
 #endif
 #ifdef RLIMIT_STACK
-	{ RLIMIT_STACK,	"RLIMIT_STACK"	},
+	{ RLIMIT_STACK,		"RLIMIT_STACK"		},
 #endif
 #ifdef RLIMIT_VMEM
-	{ RLIMIT_VMEM,	"RLIMIT_VMEM"	},
+	{ RLIMIT_VMEM,		"RLIMIT_VMEM"		},
 #endif
-	{ 0,		NULL		},
+	{ 0,			NULL			}
 };
 
-#if !HAVE_LONG_LONG_RLIM_T
+#if !(SIZEOF_RLIM_T == 4 || SIZEOF_RLIM_T == 8)
+# error "Unsupported SIZEOF_RLIM_T value"
+#endif
+
 static const char *
-sprintrlim(long lim)
+sprint_rlim64(uint64_t lim)
 {
-	static char buf[sizeof(long)*3 + sizeof("%ld*1024")];
+	static char buf[sizeof(uint64_t)*3 + sizeof("*1024")];
 
-	if (lim == RLIM_INFINITY)
-		return "RLIM_INFINITY";
+	if (lim == UINT64_MAX)
+		return "RLIM64_INFINITY";
 
-	if (lim > 1024 && lim%1024 == 0)
-		sprintf(buf, "%ld*1024", lim/1024);
+	if (lim > 1024 && lim % 1024 == 0)
+		sprintf(buf, "%" PRIu64 "*1024", lim / 1024);
 	else
-		sprintf(buf, "%ld", lim);
+		sprintf(buf, "%" PRIu64, lim);
 	return buf;
 }
 
-# if defined(POWERPC64) || defined(X86_64)
 static void
-print_rlimit32(struct tcb *tcp)
+print_rlimit64(struct tcb *tcp, unsigned long addr)
 {
-	struct rlimit32 {
-		unsigned int rlim_cur;
-		unsigned int rlim_max;
+	struct rlimit_64 {
+		uint64_t rlim_cur;
+		uint64_t rlim_max;
 	} rlim;
 
-	if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
-		tprints("{...}");
+	if (umove(tcp, addr, &rlim) < 0)
+		tprintf("%#lx", addr);
 	else {
-		tprintf("{rlim_cur=%s,",
-			sprintrlim(rlim.rlim_cur == -1 ? RLIM_INFINITY
-				   : rlim.rlim_cur));
-		tprintf(" rlim_max=%s}",
-			sprintrlim(rlim.rlim_max == -1 ? RLIM_INFINITY
-				   : rlim.rlim_max));
+		tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur));
+		tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max));
 	}
 }
+
+static void
+decode_rlimit64(struct tcb *tcp, unsigned long addr)
+{
+	if (!addr)
+		tprints("NULL");
+	else if (!verbose(tcp) ||
+		 (exiting(tcp) && syserror(tcp)))
+		tprintf("%#lx", addr);
+	else
+		print_rlimit64(tcp, addr);
+}
+
+#if SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1
+
+static const char *
+sprint_rlim32(uint32_t lim)
+{
+	static char buf[sizeof(uint32_t)*3 + sizeof("*1024")];
+
+	if (lim == UINT32_MAX)
+		return "RLIM_INFINITY";
+
+	if (lim > 1024 && lim % 1024 == 0)
+		sprintf(buf, "%" PRIu32 "*1024", lim / 1024);
+	else
+		sprintf(buf, "%" PRIu32, lim);
+	return buf;
+}
+
+static void
+print_rlimit32(struct tcb *tcp, unsigned long addr)
+{
+	struct rlimit_32 {
+		uint32_t rlim_cur;
+		uint32_t rlim_max;
+	} rlim;
+
+	if (umove(tcp, addr, &rlim) < 0)
+		tprintf("%#lx", addr);
+	else {
+		tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur));
+		tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max));
+	}
+}
+
+static void
+decode_rlimit(struct tcb *tcp, unsigned long addr)
+{
+	if (!addr)
+		tprints("NULL");
+	else if (!verbose(tcp) ||
+		 (exiting(tcp) && syserror(tcp)))
+		tprintf("%#lx", addr);
+	else {
+# if SIZEOF_RLIM_T == 4
+		print_rlimit32(tcp, addr);
+# else
+		if (personality_wordsize[current_personality] == 4)
+			print_rlimit32(tcp, addr);
+		else
+			print_rlimit64(tcp, addr);
 # endif
+	}
+}
+
+#else /* SIZEOF_RLIM_T == 8 && SUPPORTED_PERSONALITIES == 1 */
+
+# define decode_rlimit decode_rlimit64
+
+#endif /* SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1 */
 
 int
 sys_getrlimit(struct tcb *tcp)
 {
-	struct rlimit rlim;
-
 	if (entering(tcp)) {
 		printxval(resources, tcp->u_arg[0], "RLIMIT_???");
 		tprints(", ");
 	}
 	else {
-		if (syserror(tcp) || !verbose(tcp))
-			tprintf("%#lx", tcp->u_arg[1]);
-# if defined(POWERPC64) || defined(X86_64)
-		else if (current_personality == 1)
-			print_rlimit32(tcp);
-# endif
-		else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
-			tprints("{...}");
-		else {
-			tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
-			tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
-		}
+		decode_rlimit(tcp, tcp->u_arg[1]);
 	}
 	return 0;
 }
@@ -165,86 +210,28 @@
 int
 sys_setrlimit(struct tcb *tcp)
 {
-	struct rlimit rlim;
-
 	if (entering(tcp)) {
 		printxval(resources, tcp->u_arg[0], "RLIMIT_???");
 		tprints(", ");
-		if (!verbose(tcp))
-			tprintf("%#lx", tcp->u_arg[1]);
-# if defined(POWERPC64) || defined(X86_64)
-		else if (current_personality == 1)
-			print_rlimit32(tcp);
-# endif
-		else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
-			tprints("{...}");
-		else {
-			tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur));
-			tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max));
-		}
-	}
-	return 0;
-}
-#endif /* !HAVE_LONG_LONG_RLIM_T */
-
-#if _LFS64_LARGEFILE || HAVE_LONG_LONG_RLIM_T
-static const char *
-sprintrlim64(rlim64_t lim)
-{
-	static char buf[sizeof(long long)*3 + sizeof("%lld*1024")];
-
-	if (lim == RLIM64_INFINITY)
-		return "RLIM64_INFINITY";
-
-	if (lim > 1024 && lim%1024 == 0)
-		sprintf(buf, "%lld*1024", (long long) lim/1024);
-	else
-		sprintf(buf, "%lld", (long long) lim);
-	return buf;
-}
-
-int
-sys_getrlimit64(struct tcb *tcp)
-{
-	struct rlimit64 rlim;
-
-	if (entering(tcp)) {
-		printxval(resources, tcp->u_arg[0], "RLIMIT_???");
-		tprints(", ");
-	}
-	else {
-		if (syserror(tcp) || !verbose(tcp))
-			tprintf("%#lx", tcp->u_arg[1]);
-		else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
-			tprints("{...}");
-		else {
-			tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
-			tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
-		}
+		decode_rlimit(tcp, tcp->u_arg[1]);
 	}
 	return 0;
 }
 
 int
-sys_setrlimit64(struct tcb *tcp)
+sys_prlimit64(struct tcb *tcp)
 {
-	struct rlimit64 rlim;
-
 	if (entering(tcp)) {
-		printxval(resources, tcp->u_arg[0], "RLIMIT_???");
+		tprintf("%ld, ", tcp->u_arg[0]);
+		printxval(resources, tcp->u_arg[1], "RLIMIT_???");
 		tprints(", ");
-		if (!verbose(tcp))
-			tprintf("%#lx", tcp->u_arg[1]);
-		else if (umove(tcp, tcp->u_arg[1], &rlim) < 0)
-			tprints("{...}");
-		else {
-			tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur));
-			tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max));
-		}
+		decode_rlimit64(tcp, tcp->u_arg[2]);
+		tprints(", ");
+	} else {
+		decode_rlimit64(tcp, tcp->u_arg[3]);
 	}
 	return 0;
 }
-#endif /* _LFS64_LARGEFILES || HAVE_LONG_LONG_RLIM_T */
 
 static const struct xlat usagewho[] = {
 	{ RUSAGE_SELF,		"RUSAGE_SELF"		},