[GWP-ASan] Integrate GWP-ASan into bionc's malloc() (using hooks).

This patch introduces GWP-ASan - a sampled allocator framework that
finds use-after-free and heap-buffer-overflow bugs in production
environments.

GWP-ASan is being introduced in an always-disabled mode. This means that
GWP-ASan will be permanently disabled until a further patch turns on
support. As such, there should be no visible functional change for the
time being.

GWP-ASan requires -fno-emulated-tls wherever it's linked from. We
intentionally link GWP-ASan into libc so that it's part of the initial
set of libraries, and thus has static TLS storage (so we can use
Initial-Exec TLS instead of Global-Dynamic). As a benefit, this reduces
overhead for a sampled process.

GWP-ASan is always initialised via. a call to
mallopt(M_INITIALIZE_GWP_ASAN, which must be done before a process is
multithreaded).

More information about GWP-ASan can be found in the upstream
documentation: http://llvm.org/docs/GwpAsan.html

Bug: 135634846
Test: atest bionic
Change-Id: Ib9bd33337d17dab39ac32f4536bff71bd23498b0
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index e08083f..da68c80 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -41,6 +41,7 @@
 #include <private/bionic_config.h>
 #include <platform/bionic/malloc.h>
 
+#include "gwp_asan_wrappers.h"
 #include "heap_tagging.h"
 #include "malloc_common.h"
 #include "malloc_limit.h"
@@ -316,8 +317,42 @@
   if (opcode == M_SET_HEAP_TAGGING_LEVEL) {
     return SetHeapTaggingLevel(arg, arg_size);
   }
+  if (opcode == M_INITIALIZE_GWP_ASAN) {
+    if (arg == nullptr || arg_size != sizeof(bool)) {
+      errno = EINVAL;
+      return false;
+    }
+    return MaybeInitGwpAsan(*reinterpret_cast<bool*>(arg));
+  }
   errno = ENOTSUP;
   return false;
 }
 #endif
 // =============================================================================
+
+static constexpr MallocDispatch __libc_malloc_default_dispatch __attribute__((unused)) = {
+  Malloc(calloc),
+  Malloc(free),
+  Malloc(mallinfo),
+  Malloc(malloc),
+  Malloc(malloc_usable_size),
+  Malloc(memalign),
+  Malloc(posix_memalign),
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  Malloc(pvalloc),
+#endif
+  Malloc(realloc),
+#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
+  Malloc(valloc),
+#endif
+  Malloc(malloc_iterate),
+  Malloc(malloc_disable),
+  Malloc(malloc_enable),
+  Malloc(mallopt),
+  Malloc(aligned_alloc),
+  Malloc(malloc_info),
+};
+
+const MallocDispatch* NativeAllocatorDispatch() {
+  return &__libc_malloc_default_dispatch;
+}