prctl.c: make use of RVAL_DECODED

* prctl.c (prctl_enter, prctl_exit): Merge into sys_prctl.
(sys_prctl, sys_arch_prctl): Update for RVAL_DECODED.
diff --git a/prctl.c b/prctl.c
index e74809d..ae36d5b 100644
--- a/prctl.c
+++ b/prctl.c
@@ -31,34 +31,93 @@
 
 #include "xlat/cap.h"
 
-static int
-prctl_enter(struct tcb *tcp)
+SYS_FUNC(prctl)
 {
 	unsigned int i;
 
-	printxval(prctl_options, tcp->u_arg[0], "PR_???");
+	if (entering(tcp))
+		printxval(prctl_options, tcp->u_arg[0], "PR_???");
 
 	switch (tcp->u_arg[0]) {
-	/* PR_GET_* are decoded on exit. */
-	case PR_GET_CHILD_SUBREAPER:
 	case PR_GET_DUMPABLE:
+	case PR_GET_KEEPCAPS:
+	case PR_GET_SECCOMP:
+	case PR_GET_TIMERSLACK:
+	case PR_GET_TIMING:
+		if (entering(tcp))
+			break;
+		return syserror(tcp) ? 0 : RVAL_UDECIMAL;
+
+	case PR_GET_CHILD_SUBREAPER:
 	case PR_GET_ENDIAN:
 	case PR_GET_FPEMU:
 	case PR_GET_FPEXC:
-	case PR_GET_KEEPCAPS:
+		if (entering(tcp))
+			tprints(", ");
+		else
+			printnum_int(tcp, tcp->u_arg[1], "%u");
+		break;
+
 	case PR_GET_NAME:
+		if (entering(tcp))
+			tprints(", ");
+		else {
+			if (syserror(tcp))
+				printaddr(tcp->u_arg[1]);
+			else
+				printstr(tcp, tcp->u_arg[1], -1);
+		}
+		break;
+
 	case PR_GET_PDEATHSIG:
-	case PR_GET_SECCOMP:
+		if (entering(tcp))
+			tprints(", ");
+		else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
+			tprints("[");
+			tprints(signame(i));
+			tprints("]");
+		}
+		break;
+
 	case PR_GET_SECUREBITS:
+		if (entering(tcp))
+			break;
+		if (syserror(tcp) || tcp->u_rval == 0)
+			return 0;
+		tcp->auxstr = sprintflags("", secbits, tcp->u_rval);
+		return RVAL_STR;
+
 	case PR_GET_TID_ADDRESS:
-	case PR_GET_TIMERSLACK:
-	case PR_GET_TIMING:
+		if (entering(tcp))
+			tprints(", ");
+		else
+			printnum_long(tcp, tcp->u_arg[1], "%#lx");
+		break;
+
 	case PR_GET_TSC:
+		if (entering(tcp))
+			tprints(", ");
+		else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
+			tprints("[");
+			printxval(pr_tsc, i, "PR_TSC_???");
+			tprints("]");
+		}
+		break;
+
 	case PR_GET_UNALIGN:
-	/* PR_TASK_PERF_EVENTS_* have nothing to decode on enter. */
+		if (entering(tcp))
+			tprints(", ");
+		else if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
+			tprints("[");
+			printflags(pr_unalign_flags, i, "PR_UNALIGN_???");
+			tprints("]");
+		}
+		break;
+
+	/* PR_TASK_PERF_EVENTS_* take no arguments. */
 	case PR_TASK_PERF_EVENTS_DISABLE:
 	case PR_TASK_PERF_EVENTS_ENABLE:
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_CHILD_SUBREAPER:
 	case PR_SET_DUMPABLE:
@@ -68,13 +127,20 @@
 	case PR_SET_KEEPCAPS:
 	case PR_SET_TIMING:
 		tprintf(", %lu", tcp->u_arg[1]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_CAPBSET_DROP:
-	case PR_CAPBSET_READ:
 		tprints(", ");
 		printxval(cap, tcp->u_arg[1], "CAP_???");
-		break;
+		return RVAL_DECODED;
+
+	case PR_CAPBSET_READ:
+		if (entering(tcp)) {
+			tprints(", ");
+			printxval(cap, tcp->u_arg[1], "CAP_???");
+			break;
+		}
+		return syserror(tcp) ? 0 : RVAL_UDECIMAL;
 
 	case PR_MCE_KILL:
 		tprints(", ");
@@ -87,19 +153,19 @@
 			tprintf("%#lx", tcp->u_arg[2]);
 		for (i = 3; i < tcp->s_ent->nargs; i++)
 			tprintf(", %#lx", tcp->u_arg[i]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_NAME:
 		tprints(", ");
 		printstr(tcp, tcp->u_arg[1], TASK_COMM_LEN);
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_MM:
 		tprints(", ");
 		printxval(pr_set_mm, tcp->u_arg[1], "PR_SET_MM_???");
 		for (i = 2; i < tcp->s_ent->nargs; i++)
 			tprintf(", %#lx", tcp->u_arg[i]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_PDEATHSIG:
 		tprints(", ");
@@ -107,7 +173,7 @@
 			tprintf("%lu", tcp->u_arg[1]);
 		else
 			tprints(signame(tcp->u_arg[1]));
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_PTRACER:
 		tprints(", ");
@@ -115,150 +181,72 @@
 			tprints("PR_SET_PTRACER_ANY");
 		else
 			tprintf("%lu", tcp->u_arg[1]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_SECCOMP:
 		tprints(", ");
 		printxval(seccomp_mode, tcp->u_arg[1],
 			  "SECCOMP_MODE_???");
 		if (SECCOMP_MODE_STRICT == tcp->u_arg[1])
-			break;
+			return RVAL_DECODED;
 		if (SECCOMP_MODE_FILTER == tcp->u_arg[1]) {
 			tprints(", ");
 			print_seccomp_filter(tcp, tcp->u_arg[2]);
-			break;
+			return RVAL_DECODED;
 		}
 		for (i = 2; i < tcp->s_ent->nargs; i++)
 			tprintf(", %#lx", tcp->u_arg[i]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_SECUREBITS:
 		tprints(", ");
 		printflags(secbits, tcp->u_arg[1], "SECBIT_???");
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_TIMERSLACK:
 		tprintf(", %ld", tcp->u_arg[1]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_TSC:
 		tprints(", ");
 		printxval(pr_tsc, tcp->u_arg[1], "PR_TSC_???");
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_UNALIGN:
 		tprints(", ");
 		printflags(pr_unalign_flags, tcp->u_arg[1], "PR_UNALIGN_???");
-		break;
+		return RVAL_DECODED;
 
 	case PR_SET_NO_NEW_PRIVS:
 	case PR_SET_THP_DISABLE:
 		tprintf(", %lu", tcp->u_arg[1]);
 		for (i = 2; i < tcp->s_ent->nargs; i++)
 			tprintf(", %#lx", tcp->u_arg[i]);
-		break;
+		return RVAL_DECODED;
 
 	case PR_GET_NO_NEW_PRIVS:
 	case PR_GET_THP_DISABLE:
-	case PR_MCE_KILL_GET:
-	/* Return code of "GET" commands will be decoded on exit */
-	case PR_MPX_DISABLE_MANAGEMENT:
-	case PR_MPX_ENABLE_MANAGEMENT:
-	default:
-		for (i = 1; i < tcp->s_ent->nargs; i++)
-			tprintf(", %#lx", tcp->u_arg[i]);
-		break;
-	}
-	return 0;
-}
-
-static int
-prctl_exit(struct tcb *tcp)
-{
-	unsigned int i;
-
-	switch (tcp->u_arg[0]) {
-	case PR_CAPBSET_READ:
-	case PR_GET_DUMPABLE:
-	case PR_GET_KEEPCAPS:
-	case PR_GET_NO_NEW_PRIVS:
-	case PR_GET_SECCOMP:
-	case PR_GET_THP_DISABLE:
-	case PR_GET_TIMERSLACK:
-	case PR_GET_TIMING:
+		if (entering(tcp))
+			return printargs(tcp);
 		return syserror(tcp) ? 0 : RVAL_UDECIMAL;
 
-	case PR_GET_CHILD_SUBREAPER:
-	case PR_GET_ENDIAN:
-	case PR_GET_FPEMU:
-	case PR_GET_FPEXC:
-		tprints(", ");
-		printnum_int(tcp, tcp->u_arg[1], "%u");
-		break;
-
-	case PR_GET_NAME:
-		tprints(", ");
-		if (syserror(tcp))
-			printaddr(tcp->u_arg[1]);
-		else
-			printstr(tcp, tcp->u_arg[1], -1);
-		break;
-
-	case PR_GET_PDEATHSIG:
-		tprints(", ");
-		if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
-			tprints("[");
-			tprints(signame(i));
-			tprints("]");
-		}
-		break;
-
-	case PR_GET_SECUREBITS:
-		if (syserror(tcp) || tcp->u_rval == 0)
-			return 0;
-		tcp->auxstr = sprintflags("", secbits, tcp->u_rval);
-		return RVAL_STR;
-
-	case PR_GET_TID_ADDRESS:
-		tprints(", ");
-		printnum_long(tcp, tcp->u_arg[1], "%#lx");
-		break;
-
-	case PR_GET_TSC:
-		tprints(", ");
-		if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
-			tprints("[");
-			printxval(pr_tsc, i, "PR_TSC_???");
-			tprints("]");
-		}
-		break;
-
-	case PR_GET_UNALIGN:
-		tprints(", ");
-		if (!umove_or_printaddr(tcp, tcp->u_arg[1], &i)) {
-			tprints("[");
-			printflags(pr_unalign_flags, i, "PR_UNALIGN_???");
-			tprints("]");
-		}
-		break;
-
 	case PR_MCE_KILL_GET:
+		if (entering(tcp))
+			return printargs(tcp);
 		if (syserror(tcp))
 			return 0;
 		tcp->auxstr = xlookup(pr_mce_kill_policy, tcp->u_rval);
 		return tcp->auxstr ? RVAL_STR : RVAL_UDECIMAL;
 
+	case PR_MPX_DISABLE_MANAGEMENT:
+	case PR_MPX_ENABLE_MANAGEMENT:
 	default:
-		break;
+		printargs(tcp);
+		return RVAL_DECODED;
 	}
 	return 0;
 }
 
-SYS_FUNC(prctl)
-{
-	return entering(tcp) ? prctl_enter(tcp) : prctl_exit(tcp);
-}
-
 #if defined X86_64 || defined X32
 # include <asm/prctl.h>
 # include "xlat/archvals.h"
@@ -271,17 +259,14 @@
 	switch (tcp->u_arg[0]) {
 	case ARCH_GET_GS:
 	case ARCH_GET_FS:
-		if (exiting(tcp)) {
+		if (entering(tcp))
 			tprints(", ");
+		else
 			printnum_long(tcp, tcp->u_arg[1], "%#lx");
-		}
 		return 0;
-	default:
-		if (exiting(tcp))
-			return 0;
 	}
 
 	tprintf(", %#lx", tcp->u_arg[1]);
-	return 0;
+	return RVAL_DECODED;
 }
 #endif /* X86_64 || X32 */