Allocate all arc4random data on the same page.

Saves one dirty page per process.

Test: bionic unit tests, reboot, manual check of /proc/*/maps
Change-Id: Ibbcafa955d60e43f4cb735fa484c6868aa357cd5
diff --git a/libc/upstream-openbsd/android/include/arc4random.h b/libc/upstream-openbsd/android/include/arc4random.h
index 8d965e0..0d70c81 100644
--- a/libc/upstream-openbsd/android/include/arc4random.h
+++ b/libc/upstream-openbsd/android/include/arc4random.h
@@ -28,6 +28,7 @@
 #include <signal.h>
 
 #include "private/bionic_prctl.h"
+#include "private/libc_logging.h"
 
 // Android gets these from "thread_private.h".
 #include "thread_private.h"
@@ -46,7 +47,7 @@
 static inline void
 _getentropy_fail(void)
 {
-	raise(SIGKILL);
+	__libc_fatal("getentropy failed");
 }
 
 volatile sig_atomic_t _rs_forked;
@@ -68,21 +69,21 @@
 static inline int
 _rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
 {
-	if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
+	// OpenBSD's arc4random_linux.h allocates two separate mappings, but for
+	// themselves they just allocate both structs into one mapping like this.
+	struct {
+		struct _rs rs;
+		struct _rsx rsx;
+	} *p;
+
+	if ((p = mmap(NULL, sizeof(*p), PROT_READ|PROT_WRITE,
 	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
 		return (-1);
 
-	prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, *rsp, sizeof(**rsp),
-	    "arc4random _rs structure");
+	prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, sizeof(*p), "arc4random data");
 
-	if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
-	    MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
-		munmap(*rsxp, sizeof(**rsxp));
-		return (-1);
-	}
-
-	prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, *rsxp, sizeof(**rsxp),
-	    "arc4random _rsx structure");
+	*rsp = &p->rs;
+	*rsxp = &p->rsx;
 
 	return (0);
 }