Merge "HWASan support in bionic."
diff --git a/libc/Android.bp b/libc/Android.bp
index 7356c64..61d00cd 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -71,7 +71,8 @@
     stl: "none",
     system_shared_libs: [],
     sanitize: {
-        never: true,
+        address: false,
+        integer_overflow: false,
     },
     native_coverage: false,
     recovery_available: true,
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 9eb574a..55506a3 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -45,6 +45,10 @@
 #include "private/bionic_tls.h"
 #include "private/KernelArgumentBlock.h"
 
+#if __has_feature(hwaddress_sanitizer)
+#include <sanitizer/hwasan_interface.h>
+#endif
+
 // Leave the variable uninitialized for the sake of the dynamic loader, which
 // links in this file. The loader will initialize this variable before
 // relocating itself.
@@ -85,11 +89,10 @@
 //
 // The 'structors' parameter contains pointers to various initializer
 // arrays that must be run before the program's 'main' routine is launched.
-
-__noreturn void __libc_init(void* raw_args,
-                            void (*onexit)(void) __unused,
-                            int (*slingshot)(int, char**, char**),
-                            structors_array_t const * const structors) {
+__noreturn static void __real_libc_init(void *raw_args,
+                                        void (*onexit)(void) __unused,
+                                        int (*slingshot)(int, char**, char**),
+                                        structors_array_t const * const structors) {
   BIONIC_STOP_UNWIND;
 
   KernelArgumentBlock args(raw_args);
@@ -124,6 +127,20 @@
   exit(slingshot(args.argc, args.argv, args.envp));
 }
 
+#if __has_feature(hwaddress_sanitizer)
+__attribute__((no_sanitize("hwaddress")))
+#endif
+__noreturn void __libc_init(void* raw_args,
+                            void (*onexit)(void) __unused,
+                            int (*slingshot)(int, char**, char**),
+                            structors_array_t const * const structors) {
+#if __has_feature(hwaddress_sanitizer)
+  __hwasan_shadow_init();
+#endif
+  __real_libc_init(raw_args, onexit, slingshot, structors);
+}
+
+
 static uint32_t g_target_sdk_version{__ANDROID_API__};
 
 extern "C" uint32_t android_get_application_target_sdk_version() {
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 40a0023..5a5ec76 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -47,8 +47,26 @@
 #include <private/bionic_globals.h>
 #include <private/bionic_malloc_dispatch.h>
 
+#if __has_feature(hwaddress_sanitizer)
+// FIXME: implement these in HWASan allocator.
+extern "C" int __sanitizer_iterate(uintptr_t base __unused, size_t size __unused,
+                                   void (*callback)(uintptr_t base, size_t size, void* arg) __unused,
+                                   void* arg __unused) {
+  return 0;
+}
+
+extern "C" void __sanitizer_malloc_disable() {
+}
+
+extern "C" void __sanitizer_malloc_enable() {
+}
+#include <sanitizer/hwasan_interface.h>
+#define Malloc(function)  __sanitizer_ ## function
+
+#else // __has_feature(hwaddress_sanitizer)
 #include "jemalloc.h"
 #define Malloc(function)  je_ ## function
+#endif
 
 static constexpr MallocDispatch __libc_malloc_default_dispatch
   __attribute__((unused)) = {
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index c95d400..98d1726 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -249,6 +249,8 @@
   // accesses previously made by the creating thread are visible to us.
   thread->startup_handshake_lock.lock();
 
+  __hwasan_thread_enter();
+
   __init_alternate_signal_stack(thread);
 
   void* result = thread->start_routine(thread->start_routine_arg);
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index ac5d429..220f7a0 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -126,6 +126,7 @@
       // That's one last thing we can do before dropping to assembler.
       ScopedSignalBlocker ssb;
       __pthread_unmap_tls(thread);
+      __hwasan_thread_exit();
       _exit_with_stack_teardown(thread->attr.stack_base, thread->mmap_size);
     }
   }
@@ -133,5 +134,6 @@
   // No need to free mapped space. Either there was no space mapped, or it is left for
   // the pthread_join caller to clean up.
   __pthread_unmap_tls(thread);
+  __hwasan_thread_exit();
   __exit(0);
 }
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 18f5aee..1ec201b 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -31,6 +31,13 @@
 #include <pthread.h>
 #include <stdatomic.h>
 
+#if __has_feature(hwaddress_sanitizer)
+#include <sanitizer/hwasan_interface.h>
+#else
+#define __hwasan_thread_enter()
+#define __hwasan_thread_exit()
+#endif
+
 #include "private/bionic_lock.h"
 #include "private/bionic_tls.h"
 
diff --git a/linker/Android.bp b/linker/Android.bp
index fb6aa7d..b809f76 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -228,6 +228,10 @@
     // Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
     // looking up symbols in the linker by mistake.
     prefix_symbols: "__dl_",
+
+    sanitize: {
+        hwaddress: false,
+    },
 }
 
 cc_library {