Merge "Remove the obsolete _thread_created_hook."
diff --git a/libc/Android.mk b/libc/Android.mk
index 078be59..b0a9fb1 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -107,7 +107,7 @@
     bionic/clearenv.cpp \
     bionic/clock.cpp \
     bionic/clone.cpp \
-    bionic/cmsg_nxthdr.cpp \
+    bionic/__cmsg_nxthdr.cpp \
     bionic/connect.cpp \
     bionic/__cxa_guard.cpp \
     bionic/__cxa_pure_virtual.cpp \
@@ -491,6 +491,10 @@
     -D_LIBC=1 \
     -Wall -Wextra -Wunused \
 
+ifneq ($(TARGET_USES_LOGD),false)
+libc_common_cflags += -DTARGET_USES_LOGD
+endif
+
 # Try to catch typical 32-bit assumptions that break with 64-bit pointers.
 libc_common_cflags += \
     -Werror=pointer-to-int-cast \
@@ -783,10 +787,6 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
-ifneq ($(TARGET_USES_LOGD),false)
-LOCAL_CFLAGS += -DTARGET_USES_LOGD
-endif
-
 $(eval $(call patch-up-arch-specific-flags,LOCAL_CFLAGS,libc_common_cflags))
 $(eval $(call patch-up-arch-specific-flags,LOCAL_SRC_FILES,libc_bionic_src_files))
 include $(BUILD_STATIC_LIBRARY)
@@ -1011,6 +1011,7 @@
 LOCAL_SRC_FILES := \
     bionic/debug_mapinfo.cpp \
     bionic/debug_stacktrace.cpp \
+    bionic/libc_logging.cpp \
     bionic/malloc_debug_leak.cpp \
     bionic/malloc_debug_check.cpp \
 
@@ -1018,7 +1019,6 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 
 LOCAL_SHARED_LIBRARIES := libc libdl
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
 
@@ -1044,13 +1044,13 @@
 LOCAL_C_INCLUDES := $(libc_common_c_includes)
 
 LOCAL_SRC_FILES := \
-    bionic/malloc_debug_qemu.cpp
+    bionic/libc_logging.cpp \
+    bionic/malloc_debug_qemu.cpp \
 
 LOCAL_MODULE := libc_malloc_debug_qemu
 LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
 
 LOCAL_SHARED_LIBRARIES := libc libdl
-LOCAL_WHOLE_STATIC_LIBRARIES := libc_common
 LOCAL_SYSTEM_SHARED_LIBRARIES :=
 
 # Don't install on release build
diff --git a/libc/bionic/cmsg_nxthdr.cpp b/libc/bionic/__cmsg_nxthdr.cpp
similarity index 95%
rename from libc/bionic/cmsg_nxthdr.cpp
rename to libc/bionic/__cmsg_nxthdr.cpp
index 8a2b33e..f962788 100644
--- a/libc/bionic/cmsg_nxthdr.cpp
+++ b/libc/bionic/__cmsg_nxthdr.cpp
@@ -37,6 +37,3 @@
   }
   return ptr;
 }
-
-// TODO: remove after NDK refresh.
-__weak_alias(cmsg_nxthdr, __cmsg_nxthdr);
diff --git a/libc/bionic/malloc_debug_check.cpp b/libc/bionic/malloc_debug_check.cpp
index e4e4c2e..1b6f8ea 100644
--- a/libc/bionic/malloc_debug_check.cpp
+++ b/libc/bionic/malloc_debug_check.cpp
@@ -123,6 +123,7 @@
 static unsigned g_malloc_debug_backlog = 100;
 
 __LIBC_HIDDEN__ HashTable* g_hash_table;
+__LIBC_HIDDEN__ const MallocDebug* g_malloc_dispatch;
 
 static inline void init_front_guard(hdr_t* hdr) {
     memset(hdr->front_guard, FRONT_GUARD, FRONT_GUARD_LEN);
@@ -324,7 +325,7 @@
     while (backlog_num > g_malloc_debug_backlog) {
         hdr_t* gone = backlog_tail;
         del_from_backlog_locked(gone);
-        Malloc(free)(gone->base);
+        g_malloc_dispatch->free(gone->base);
     }
 }
 
@@ -336,7 +337,7 @@
         errno = ENOMEM;
         return NULL;
     }
-    hdr_t* hdr = static_cast<hdr_t*>(Malloc(malloc)(size));
+    hdr_t* hdr = static_cast<hdr_t*>(g_malloc_dispatch->malloc(size));
     if (hdr) {
         hdr->base = hdr;
         hdr->bt_depth = get_backtrace(hdr->bt, MAX_BACKTRACE_DEPTH);
@@ -364,7 +365,7 @@
         return NULL;
     }
 
-    void* base = Malloc(malloc)(sizeof(hdr_t) + size + sizeof(ftr_t));
+    void* base = g_malloc_dispatch->malloc(sizeof(hdr_t) + size + sizeof(ftr_t));
     if (base != NULL) {
         // Check that the actual pointer that will be returned is aligned
         // properly.
@@ -461,7 +462,7 @@
                        user(hdr), bytes);
             log_backtrace(bt, depth);
             // just get a whole new allocation and leak the old one
-            return Malloc(realloc)(0, bytes);
+            return g_malloc_dispatch->realloc(0, bytes);
             // return realloc(user(hdr), bytes); // assuming it was allocated externally
         }
     }
@@ -474,15 +475,15 @@
     if (hdr->base != hdr) {
         // An allocation from memalign, so create another allocation and
         // copy the data out.
-        void* newMem = Malloc(malloc)(size);
+        void* newMem = g_malloc_dispatch->malloc(size);
         if (newMem == NULL) {
             return NULL;
         }
         memcpy(newMem, hdr, sizeof(hdr_t) + hdr->size);
-        Malloc(free)(hdr->base);
+        g_malloc_dispatch->free(hdr->base);
         hdr = static_cast<hdr_t*>(newMem);
     } else {
-        hdr = static_cast<hdr_t*>(Malloc(realloc)(hdr, size));
+        hdr = static_cast<hdr_t*>(g_malloc_dispatch->realloc(hdr, size));
     }
     if (hdr) {
         hdr->base = hdr;
@@ -501,7 +502,7 @@
         errno = ENOMEM;
         return NULL;
     }
-    hdr_t* hdr = static_cast<hdr_t*>(Malloc(calloc)(1, size));
+    hdr_t* hdr = static_cast<hdr_t*>(g_malloc_dispatch->calloc(1, size));
     if (hdr) {
         hdr->base = hdr;
         hdr->bt_depth = get_backtrace(hdr->bt, MAX_BACKTRACE_DEPTH);
@@ -524,7 +525,7 @@
 }
 
 extern "C" struct mallinfo chk_mallinfo() {
-  return Malloc(mallinfo)();
+  return g_malloc_dispatch->mallinfo();
 }
 
 extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) {
@@ -584,8 +585,9 @@
   }
 }
 
-extern "C" bool malloc_debug_initialize(HashTable* hash_table) {
+extern "C" bool malloc_debug_initialize(HashTable* hash_table, const MallocDebug* malloc_dispatch) {
   g_hash_table = hash_table;
+  g_malloc_dispatch = malloc_dispatch;
 
   char debug_backlog[PROP_VALUE_MAX];
   if (__system_property_get("libc.debug.malloc.backlog", debug_backlog)) {
diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp
index 9399237..be16625 100644
--- a/libc/bionic/malloc_debug_common.cpp
+++ b/libc/bionic/malloc_debug_common.cpp
@@ -46,6 +46,16 @@
 
 #include "private/ScopedPthreadMutexLocker.h"
 
+#if defined(USE_JEMALLOC)
+#include "jemalloc.h"
+#define Malloc(function)  je_ ## function
+#elif defined(USE_DLMALLOC)
+#include "dlmalloc.h"
+#define Malloc(function)  dl ## function
+#else
+#error "Either one of USE_DLMALLOC or USE_JEMALLOC must be defined."
+#endif
+
 // In a VM process, this is set to 1 after fork()ing out of zygote.
 int gMallocLeakZygoteChild = 0;
 
@@ -408,7 +418,7 @@
     dlclose(malloc_impl_handle);
     return;
   }
-  if (!malloc_debug_initialize(&g_hash_table)) {
+  if (!malloc_debug_initialize(&g_hash_table, &__libc_malloc_default_dispatch)) {
     dlclose(malloc_impl_handle);
     return;
   }
diff --git a/libc/bionic/malloc_debug_common.h b/libc/bionic/malloc_debug_common.h
index fb2f03d..5c73da3 100644
--- a/libc/bionic/malloc_debug_common.h
+++ b/libc/bionic/malloc_debug_common.h
@@ -51,17 +51,6 @@
 #define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
 #endif
 
-#ifdef USE_JEMALLOC
-#include "jemalloc.h"
-#define Malloc(function)  je_ ## function
-#else
-#ifndef USE_DLMALLOC
-#error "Either one of USE_DLMALLOC or USE_JEMALLOC must be defined."
-#endif
-#include "dlmalloc.h"
-#define Malloc(function)  dl ## function
-#endif
-
 // =============================================================================
 // Structures
 // =============================================================================
@@ -116,7 +105,7 @@
 #endif
 };
 
-typedef bool (*MallocDebugInit)(HashTable*);
+typedef bool (*MallocDebugInit)(HashTable*, const MallocDebug*);
 typedef void (*MallocDebugFini)(int);
 
 // =============================================================================
diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp
index 308d40b..bc88d23 100644
--- a/libc/bionic/malloc_debug_leak.cpp
+++ b/libc/bionic/malloc_debug_leak.cpp
@@ -62,6 +62,7 @@
 
 extern int gMallocLeakZygoteChild;
 extern HashTable* g_hash_table;
+extern const MallocDebug* g_malloc_dispatch;
 
 // =============================================================================
 // stack trace functions
@@ -143,7 +144,7 @@
         entry->allocations++;
     } else {
         // create a new entry
-        entry = static_cast<HashEntry*>(Malloc(malloc)(sizeof(HashEntry) + numEntries*sizeof(uintptr_t)));
+        entry = static_cast<HashEntry*>(g_malloc_dispatch->malloc(sizeof(HashEntry) + numEntries*sizeof(uintptr_t)));
         if (!entry) {
             return NULL;
         }
@@ -208,11 +209,11 @@
 #define CHK_SENTINEL_VALUE      0xeb
 
 extern "C" void* fill_calloc(size_t n_elements, size_t elem_size) {
-    return Malloc(calloc)(n_elements, elem_size);
+    return g_malloc_dispatch->calloc(n_elements, elem_size);
 }
 
 extern "C" void* fill_malloc(size_t bytes) {
-    void* buffer = Malloc(malloc)(bytes);
+    void* buffer = g_malloc_dispatch->malloc(bytes);
     if (buffer) {
         memset(buffer, CHK_SENTINEL_VALUE, bytes);
     }
@@ -220,17 +221,17 @@
 }
 
 extern "C" void fill_free(void* mem) {
-    size_t bytes = Malloc(malloc_usable_size)(mem);
+    size_t bytes = g_malloc_dispatch->malloc_usable_size(mem);
     memset(mem, CHK_FILL_FREE, bytes);
-    Malloc(free)(mem);
+    g_malloc_dispatch->free(mem);
 }
 
 extern "C" void* fill_realloc(void* mem, size_t bytes) {
-    size_t oldSize = Malloc(malloc_usable_size)(mem);
-    void* newMem = Malloc(realloc)(mem, bytes);
+    size_t oldSize = g_malloc_dispatch->malloc_usable_size(mem);
+    void* newMem = g_malloc_dispatch->realloc(mem, bytes);
     if (newMem) {
         // If this is larger than before, fill the extra with our pattern.
-        size_t newSize = Malloc(malloc_usable_size)(newMem);
+        size_t newSize = g_malloc_dispatch->malloc_usable_size(newMem);
         if (newSize > oldSize) {
             memset(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(newMem)+oldSize), CHK_FILL_FREE, newSize-oldSize);
         }
@@ -239,7 +240,7 @@
 }
 
 extern "C" void* fill_memalign(size_t alignment, size_t bytes) {
-    void* buffer = Malloc(memalign)(alignment, bytes);
+    void* buffer = g_malloc_dispatch->memalign(alignment, bytes);
     if (buffer) {
         memset(buffer, CHK_SENTINEL_VALUE, bytes);
     }
@@ -249,11 +250,11 @@
 extern "C" size_t fill_malloc_usable_size(const void* mem) {
     // Since we didn't allocate extra bytes before or after, we can
     // report the normal usable size here.
-    return Malloc(malloc_usable_size)(mem);
+    return g_malloc_dispatch->malloc_usable_size(mem);
 }
 
 extern "C" struct mallinfo fill_mallinfo() {
-  return Malloc(mallinfo)();
+  return g_malloc_dispatch->mallinfo();
 }
 
 extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) {
@@ -298,7 +299,7 @@
         return NULL;
     }
 
-    void* base = Malloc(malloc)(size);
+    void* base = g_malloc_dispatch->malloc(size);
     if (base != NULL) {
         ScopedPthreadMutexLocker locker(&g_hash_table->lock);
 
@@ -342,11 +343,11 @@
     entry->allocations--;
     if (entry->allocations <= 0) {
       remove_entry(entry);
-      Malloc(free)(entry);
+      g_malloc_dispatch->free(entry);
     }
 
     // now free the memory!
-    Malloc(free)(header);
+    g_malloc_dispatch->free(header);
   } else {
     debug_log("WARNING bad header guard: '0x%x'! and invalid entry: %p\n",
               header->guard, header->entry);
@@ -452,7 +453,7 @@
             return 0;
         }
 
-        size_t ret = Malloc(malloc_usable_size)(header);
+        size_t ret = g_malloc_dispatch->malloc_usable_size(header);
         if (ret != 0) {
             // The usable area starts at 'mem' and stops at 'header+ret'.
             return reinterpret_cast<uintptr_t>(header) + ret - reinterpret_cast<uintptr_t>(mem);
@@ -462,7 +463,7 @@
 }
 
 extern "C" struct mallinfo leak_mallinfo() {
-  return Malloc(mallinfo)();
+  return g_malloc_dispatch->mallinfo();
 }
 
 extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) {
diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp
index fd5161a..d0069e1 100644
--- a/libc/bionic/malloc_debug_qemu.cpp
+++ b/libc/bionic/malloc_debug_qemu.cpp
@@ -336,6 +336,9 @@
 // Static data
 // =============================================================================
 
+// The underlying malloc implementation to use to get memory.
+static const MallocDebug* g_malloc_dispatch = NULL;
+
 /* Emulator's magic page address.
  * This page (mapped on /dev/qemu_trace device) is used to fire up events
  * in the emulator. */
@@ -595,7 +598,9 @@
  * Return:
  *  0 on success, or -1 on failure.
 */
-extern "C" bool malloc_debug_initialize(HashTable*) {
+extern "C" bool malloc_debug_initialize(HashTable*, const MallocDebug* malloc_dispatch) {
+    g_malloc_dispatch = malloc_dispatch;
+
     /* We will be using emulator's magic page to report memory allocation
      * activities. In essence, what magic page does, it translates writes to
      * the memory mapped spaces into writes to an I/O port that emulator
@@ -693,7 +698,7 @@
         errno = ENOMEM;
         return NULL;
     }
-    desc.ptr = Malloc(malloc)(size);
+    desc.ptr = g_malloc_dispatch->malloc(size);
     if (desc.ptr == NULL) {
         qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zu): malloc(%zu) failed.",
                        malloc_pid, getpid(), bytes, size);
@@ -704,7 +709,7 @@
     if (notify_qemu_malloc(&desc)) {
         log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ",
                   malloc_pid, getpid());
-        Malloc(free)(desc.ptr);
+        g_malloc_dispatch->free(desc.ptr);
         errno = ENOMEM;
         return NULL;
     } else {
@@ -726,7 +731,7 @@
 
     if (mem == NULL) {
         // Just let go NULL free
-        Malloc(free)(mem);
+        g_malloc_dispatch->free(mem);
         return;
     }
 
@@ -757,7 +762,7 @@
     } else {
         log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ",
                   malloc_pid, getpid(), mem);
-        Malloc(free)(desc.ptr);
+        g_malloc_dispatch->free(desc.ptr);
     }
 }
 
@@ -816,7 +821,7 @@
         total_elements++;
         desc.suffix_size += (elem_size - total_size);
     }
-    desc.ptr = Malloc(calloc)(total_elements, elem_size);
+    desc.ptr = g_malloc_dispatch->calloc(total_elements, elem_size);
     if (desc.ptr == NULL) {
         error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu(%zu), %zu) (prx=%u, sfx=%u) failed.",
                    malloc_pid, getpid(), n_elements, total_elements, elem_size,
@@ -827,7 +832,7 @@
     if (notify_qemu_malloc(&desc)) {
         log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zu(%zu), %zu): notify_malloc failed for ",
                   malloc_pid, getpid(), n_elements, total_elements, elem_size);
-        Malloc(free)(desc.ptr);
+        g_malloc_dispatch->free(desc.ptr);
         errno = ENOMEM;
         return NULL;
     } else {
@@ -905,7 +910,7 @@
         errno = ENOMEM;
         return NULL;
     }
-    new_desc.ptr = Malloc(malloc)(new_size);
+    new_desc.ptr = g_malloc_dispatch->malloc(new_size);
     if (new_desc.ptr == NULL) {
         log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed on ",
                   malloc_pid, getpid(), mem, bytes, new_size);
@@ -924,7 +929,7 @@
         log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) notify_malloc failed -> ",
                   malloc_pid, getpid(), mem, bytes);
         log_mdesc(error, &cur_desc, "                                                                <- ");
-        Malloc(free)(new_desc.ptr);
+        g_malloc_dispatch->free(new_desc.ptr);
         errno = ENOMEM;
         return NULL;
     }
@@ -940,11 +945,11 @@
         /* Since we registered new decriptor with the emulator, we need
          * to unregister it before freeing newly allocated block. */
         notify_qemu_free(mallocdesc_user_ptr(&new_desc));
-        Malloc(free)(new_desc.ptr);
+        g_malloc_dispatch->free(new_desc.ptr);
         errno = ENOMEM;
         return NULL;
     }
-    Malloc(free)(cur_desc.ptr);
+    g_malloc_dispatch->free(cur_desc.ptr);
 
     log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) -> ",
               malloc_pid, getpid(), mem, bytes);
@@ -985,7 +990,7 @@
 
         return NULL;
     }
-    desc.ptr = Malloc(memalign)(desc.prefix_size, size);
+    desc.ptr = g_malloc_dispatch->memalign(desc.prefix_size, size);
     if (desc.ptr == NULL) {
         error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed.",
                   malloc_pid, getpid(), alignment, bytes, size);
@@ -994,7 +999,7 @@
     if (notify_qemu_malloc(&desc)) {
         log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zu): notify_malloc failed for ",
                   malloc_pid, getpid(), alignment, bytes);
-        Malloc(free)(desc.ptr);
+        g_malloc_dispatch->free(desc.ptr);
         return NULL;
     }
 
@@ -1032,7 +1037,7 @@
 }
 
 extern "C" struct mallinfo qemu_instrumented_mallinfo() {
-  return Malloc(mallinfo)();
+  return g_malloc_dispatch->mallinfo();
 }
 
 extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, size_t size) {