Clean up abort.

* A dlmalloc usage error shouldn't call abort(3) because we want to
  cause a SIGSEGV by writing the address dlmalloc didn't like to an
  address the kernel won't like, so that debuggerd will dump the
  memory around the address that upset dlmalloc.

* Switch to the simpler FreeBSD/NetBSD style of registering stdio
  cleanup. Hopefully this will let us simplify more of the stdio
  implementation.

* Clear the stdio cleanup handler before we abort because of a dlmalloc
  corruption error. This fixes the reported bug, where we'd hang inside
  dlmalloc because the stdio cleanup reentered dlmalloc.

Bug: 9301265
Change-Id: Ief31b389455d6876e5a68f0f5429567d37277dbc
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index 23a2636..8f5bd2d 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -44,7 +44,8 @@
  * Function pointers are stored in a linked list of pages. The list
  * is initially empty, and pages are allocated on demand. The first
  * function pointer in the first allocated page (the last one in
- * the linked list) is reserved for the cleanup function.
+ * the linked list) was reserved for the cleanup function.
+ * TODO: switch to the regular FreeBSD/NetBSD atexit implementation.
  *
  * Outside the following functions, all pages are mprotect()'ed
  * to prevent unintentional/malicious corruption.
@@ -172,42 +173,3 @@
 	}
 	_ATEXIT_UNLOCK();
 }
-
-/*
- * Register the cleanup function
- */
-void
-__atexit_register_cleanup(void (*func)(void))
-{
-	struct atexit *p;
-	int pgsize = getpagesize();
-
-	if (pgsize < (int)sizeof(*p))
-		return;
-	_ATEXIT_LOCK();
-	p = __atexit;
-	while (p != NULL && p->next != NULL)
-		p = p->next;
-	if (p == NULL) {
-		p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
-		    MAP_ANON | MAP_PRIVATE, -1, 0);
-		if (p == MAP_FAILED)
-			goto unlock;
-		p->ind = 1;
-		p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
-		    sizeof(p->fns[0]);
-		p->next = NULL;
-		__atexit = p;
-		if (__atexit_invalid)
-			__atexit_invalid = 0;
-	} else {
-		if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
-			goto unlock;
-	}
-	p->fns[0].fn_ptr.std_func = func;
-	p->fns[0].fn_arg = NULL;
-	p->fns[0].fn_dso = NULL;
-	mprotect(p, pgsize, PROT_READ);
-unlock:
-	_ATEXIT_UNLOCK();
-}