Fix debug malloc.

Previously the dynamically-loaded part of the debug malloc implementation
wanted to access hidden symbols in libc itself.

Bug: 15426546
Change-Id: I6a366ef626854d1af1d705ca24842817b1c02a19
diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp
index 035765f..aa7c072 100644
--- a/libc/bionic/malloc_debug_leak.cpp
+++ b/libc/bionic/malloc_debug_leak.cpp
@@ -58,10 +58,8 @@
 #error MALLOC_LEAK_CHECK is not defined.
 #endif  // !MALLOC_LEAK_CHECK
 
-// Global variables defined in malloc_debug_common.c
 extern int gMallocLeakZygoteChild;
-extern pthread_mutex_t g_allocations_mutex;
-extern HashTable g_hash_table;
+extern HashTable* g_hash_table;
 
 // =============================================================================
 // stack trace functions
@@ -137,7 +135,7 @@
         size |= SIZE_FLAG_ZYGOTE_CHILD;
     }
 
-    HashEntry* entry = find_entry(&g_hash_table, slot, backtrace, numEntries, size);
+    HashEntry* entry = find_entry(g_hash_table, slot, backtrace, numEntries, size);
 
     if (entry != NULL) {
         entry->allocations++;
@@ -150,58 +148,54 @@
         entry->allocations = 1;
         entry->slot = slot;
         entry->prev = NULL;
-        entry->next = g_hash_table.slots[slot];
+        entry->next = g_hash_table->slots[slot];
         entry->numEntries = numEntries;
         entry->size = size;
 
         memcpy(entry->backtrace, backtrace, numEntries * sizeof(uintptr_t));
 
-        g_hash_table.slots[slot] = entry;
+        g_hash_table->slots[slot] = entry;
 
         if (entry->next != NULL) {
             entry->next->prev = entry;
         }
 
         // we just added an entry, increase the size of the hashtable
-        g_hash_table.count++;
+        g_hash_table->count++;
     }
 
     return entry;
 }
 
 static int is_valid_entry(HashEntry* entry) {
-    if (entry != NULL) {
-        int i;
-        for (i = 0 ; i < HASHTABLE_SIZE ; i++) {
-            HashEntry* e1 = g_hash_table.slots[i];
-
-            while (e1 != NULL) {
-                if (e1 == entry) {
-                    return 1;
-                }
-
-                e1 = e1->next;
-            }
+  if (entry != NULL) {
+    for (size_t i = 0; i < HASHTABLE_SIZE; ++i) {
+      HashEntry* e1 = g_hash_table->slots[i];
+      while (e1 != NULL) {
+        if (e1 == entry) {
+          return 1;
         }
+        e1 = e1->next;
+      }
     }
-
-    return 0;
+  }
+  return 0;
 }
 
 static void remove_entry(HashEntry* entry) {
-    HashEntry* prev = entry->prev;
-    HashEntry* next = entry->next;
+  HashEntry* prev = entry->prev;
+  HashEntry* next = entry->next;
 
-    if (prev != NULL) entry->prev->next = next;
-    if (next != NULL) entry->next->prev = prev;
+  if (prev != NULL) entry->prev->next = next;
+  if (next != NULL) entry->next->prev = prev;
 
-    if (prev == NULL) {
-        // we are the head of the list. set the head to be next
-        g_hash_table.slots[entry->slot] = entry->next;
-    }
+  if (prev == NULL) {
+    // we are the head of the list. set the head to be next
+    g_hash_table->slots[entry->slot] = entry->next;
+  }
 
-    // we just removed and entry, decrease the size of the hashtable
-    g_hash_table.count--;
+  // we just removed and entry, decrease the size of the hashtable
+  g_hash_table->count--;
 }
 
 // =============================================================================
@@ -276,7 +270,7 @@
 
     void* base = Malloc(malloc)(size);
     if (base != NULL) {
-        ScopedPthreadMutexLocker locker(&g_allocations_mutex);
+        ScopedPthreadMutexLocker locker(&g_hash_table->lock);
 
         uintptr_t backtrace[BACKTRACE_SIZE];
         size_t numEntries = get_backtrace(backtrace, BACKTRACE_SIZE);
@@ -294,43 +288,45 @@
 }
 
 extern "C" void leak_free(void* mem) {
-    if (mem != NULL) {
-        ScopedPthreadMutexLocker locker(&g_allocations_mutex);
+  if (mem == NULL) {
+    return;
+  }
 
-        // check the guard to make sure it is valid
-        AllocationEntry* header = to_header(mem);
+  ScopedPthreadMutexLocker locker(&g_hash_table->lock);
 
-        if (header->guard != GUARD) {
-            // could be a memaligned block
-            if (header->guard == MEMALIGN_GUARD) {
-                // For memaligned blocks, header->entry points to the memory
-                // allocated through leak_malloc.
-                header = to_header(header->entry);
-            }
-        }
+  // check the guard to make sure it is valid
+  AllocationEntry* header = to_header(mem);
 
-        if (header->guard == GUARD || is_valid_entry(header->entry)) {
-            // decrement the allocations
-            HashEntry* entry = header->entry;
-            entry->allocations--;
-            if (entry->allocations <= 0) {
-                remove_entry(entry);
-                Malloc(free)(entry);
-            }
-
-            // now free the memory!
-            Malloc(free)(header);
-        } else {
-            debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
-                    header->guard, header->entry);
-        }
+  if (header->guard != GUARD) {
+    // could be a memaligned block
+    if (header->guard == MEMALIGN_GUARD) {
+      // For memaligned blocks, header->entry points to the memory
+      // allocated through leak_malloc.
+      header = to_header(header->entry);
     }
+  }
+
+  if (header->guard == GUARD || is_valid_entry(header->entry)) {
+    // decrement the allocations
+    HashEntry* entry = header->entry;
+    entry->allocations--;
+    if (entry->allocations <= 0) {
+      remove_entry(entry);
+      Malloc(free)(entry);
+    }
+
+    // now free the memory!
+    Malloc(free)(header);
+  } else {
+    debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
+              header->guard, header->entry);
+  }
 }
 
 extern "C" void* leak_calloc(size_t n_elements, size_t elem_size) {
-    /* Fail on overflow - just to be safe even though this code runs only
-     * within the debugging C library, not the production one */
-    if (n_elements && MAX_SIZE_T / n_elements < elem_size) {
+    // Fail on overflow - just to be safe even though this code runs only
+    // within the debugging C library, not the production one.
+    if (n_elements && SIZE_MAX / n_elements < elem_size) {
         return NULL;
     }
     size_t size = n_elements * elem_size;