bionic_allocator: more detailed and consistent error reporting.

I only came to improve the signature mismatch error, but I was then annoyed by the copy & paste of the other checks.

get_chunk_size() seems to be deliberately avoiding any checks, though I think that might be a bug, and there should be a get_chunk_size() that _does_ check for most callers, and a get_chunk_size_unchecked() for the <sys/thread_properties.h> stuff that seems to want to only be "best effort" (but does still have _some_ possibility of aborting, in addition to the possibility of segfaulting).

Also a bit of "include what you use" after cider complained about all the unused includes in bionic_allocator.h.

Bug: https://issuetracker.google.com/341850283
Change-Id: I278b495601353733af516a2d60ed10feb9cef36b
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index 80e8b08..41baf8b 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -299,7 +299,7 @@
     log2_size = kSmallObjectMinSizeLog2;
   }
 
-  return get_small_object_allocator(log2_size)->alloc();
+  return get_small_object_allocator_unchecked(log2_size)->alloc();
 }
 
 void* BionicAllocator::alloc(size_t size) {
@@ -330,9 +330,10 @@
 inline page_info* BionicAllocator::get_page_info(void* ptr) {
   page_info* info = get_page_info_unchecked(ptr);
   if (memcmp(info->signature, kSignature, sizeof(kSignature)) != 0) {
-    async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr);
+    async_safe_fatal("invalid pointer %p (page signature %04x instead of %04x)", ptr,
+                     *reinterpret_cast<const unsigned*>(info->signature),
+                     *reinterpret_cast<const unsigned*>(kSignature));
   }
-
   return info;
 }
 
@@ -353,12 +354,7 @@
   if (info->type == kLargeObject) {
     old_size = info->allocated_size - (static_cast<char*>(ptr) - reinterpret_cast<char*>(info));
   } else {
-    BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
-    if (allocator != info->allocator_addr) {
-      async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr);
-    }
-
-    old_size = allocator->get_block_size();
+    old_size = get_small_object_allocator(info, ptr)->get_block_size();
   }
 
   if (old_size < size) {
@@ -377,16 +373,10 @@
   }
 
   page_info* info = get_page_info(ptr);
-
   if (info->type == kLargeObject) {
     munmap(info, info->allocated_size);
   } else {
-    BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
-    if (allocator != info->allocator_addr) {
-      async_safe_fatal("invalid pointer %p (invalid allocator address for the page)", ptr);
-    }
-
-    allocator->free(ptr);
+    get_small_object_allocator(info, ptr)->free(ptr);
   }
 }
 
@@ -402,7 +392,7 @@
     return info->allocated_size - (static_cast<char*>(ptr) - reinterpret_cast<char*>(info));
   }
 
-  BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
+  BionicSmallObjectAllocator* allocator = get_small_object_allocator_unchecked(info->type);
   if (allocator != info->allocator_addr) {
     // Invalid pointer.
     return 0;
@@ -410,7 +400,7 @@
   return allocator->get_block_size();
 }
 
-BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator(uint32_t type) {
+BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator_unchecked(uint32_t type) {
   if (type < kSmallObjectMinSizeLog2 || type > kSmallObjectMaxSizeLog2) {
     async_safe_fatal("invalid type: %u", type);
   }
@@ -418,3 +408,11 @@
   initialize_allocators();
   return &allocators_[type - kSmallObjectMinSizeLog2];
 }
+
+BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator(page_info* pi, void* ptr) {
+  BionicSmallObjectAllocator* result = get_small_object_allocator_unchecked(pi->type);
+  if (result != pi->allocator_addr) {
+    async_safe_fatal("invalid pointer %p (invalid allocator address for the page)", ptr);
+  }
+  return result;
+}
\ No newline at end of file