Merge "Only use NDK libraries in the benchmarks."
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index 880bc1d..7330dc4 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -18,17 +18,24 @@
 #include <langinfo.h>
 #include <locale.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <benchmark/benchmark.h>
 #include "util.h"
 
 static void BM_stdlib_malloc_free(benchmark::State& state) {
   const size_t nbytes = state.range(0);
+  int pagesize = getpagesize();
 
-  void* c;
-  while (state.KeepRunning()) {
-    c = malloc(nbytes);
-    free(c);
+  void* ptr;
+  for (auto _ : state) {
+    ptr = malloc(nbytes);
+    // Make the entire allocation resident.
+    uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
+    for (size_t i = 0; i < nbytes; i += pagesize) {
+      data[i] = 1;
+    }
+    free(ptr);
   }
 
   state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
@@ -70,7 +77,7 @@
   buf[l++] = 0;
 
   volatile size_t c __attribute__((unused)) = 0;
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     c = mbstowcs(widebuf_aligned, buf_aligned, 500000);
   }
 
@@ -110,7 +117,7 @@
   buf[l++] = 0;
 
   wchar_t wc = 0;
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     for (j = 0; buf_aligned[j]; j+=mbrtowc(&wc, buf_aligned + j, 4, nullptr)) {
     }
   }
@@ -120,42 +127,42 @@
 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc, "0");
 
 void BM_stdlib_atoi(benchmark::State& state) {
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     benchmark::DoNotOptimize(atoi(" -123"));
   }
 }
 BIONIC_BENCHMARK(BM_stdlib_atoi);
 
 void BM_stdlib_atol(benchmark::State& state) {
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     benchmark::DoNotOptimize(atol(" -123"));
   }
 }
 BIONIC_BENCHMARK(BM_stdlib_atol);
 
 void BM_stdlib_strtol(benchmark::State& state) {
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     benchmark::DoNotOptimize(strtol(" -123", nullptr, 0));
   }
 }
 BIONIC_BENCHMARK(BM_stdlib_strtol);
 
 void BM_stdlib_strtoll(benchmark::State& state) {
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     benchmark::DoNotOptimize(strtoll(" -123", nullptr, 0));
   }
 }
 BIONIC_BENCHMARK(BM_stdlib_strtoll);
 
 void BM_stdlib_strtoul(benchmark::State& state) {
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     benchmark::DoNotOptimize(strtoul(" -123", nullptr, 0));
   }
 }
 BIONIC_BENCHMARK(BM_stdlib_strtoul);
 
 void BM_stdlib_strtoull(benchmark::State& state) {
-  while (state.KeepRunning()) {
+  for (auto _ : state) {
     benchmark::DoNotOptimize(strtoull(" -123", nullptr, 0));
   }
 }
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 8645df2..758b295 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -36,12 +36,18 @@
 #include "private/bionic_ssp.h"
 #include "pthread_internal.h"
 
-extern "C" int __set_tls(void* ptr);
 extern "C" int __set_tid_address(int* tid_address);
 
 // Declared in "private/bionic_ssp.h".
 uintptr_t __stack_chk_guard = 0;
 
+static pthread_internal_t main_thread;
+
+__attribute__((no_sanitize("hwaddress")))
+pthread_internal_t* __get_main_thread() {
+  return &main_thread;
+}
+
 // Setup for the main thread. For dynamic executables, this is called by the
 // linker _before_ libc is mapped in memory. This means that all writes to
 // globals from this function will apply to linker-private copies and will not
@@ -62,8 +68,6 @@
   __libc_init_sysinfo(args);
 #endif
 
-  static pthread_internal_t main_thread;
-
   // The -fstack-protector implementation uses TLS, so make sure that's
   // set up before we call any function that might get a stack check inserted.
   // TLS also needs to be set up before errno (and therefore syscalls) can be used.
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
index b895305..2a6ab41 100644
--- a/libc/bionic/clone.cpp
+++ b/libc/bionic/clone.cpp
@@ -41,6 +41,7 @@
 extern "C" __noreturn void __exit(int status);
 
 // Called from the __bionic_clone assembler to call the thread function then exit.
+__attribute__((no_sanitize("hwaddress")))
 extern "C" __LIBC_HIDDEN__ void __start_thread(int (*fn)(void*), void* arg) {
   BIONIC_STOP_UNWIND;
 
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 55506a3..38a04f8 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -127,20 +127,25 @@
   exit(slingshot(args.argc, args.argv, args.envp));
 }
 
-#if __has_feature(hwaddress_sanitizer)
+extern "C" void __hwasan_init();
+
 __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();
+  // Install main thread TLS early. It will be initialized later in __libc_init_main_thread. For now
+  // all we need is access to TLS_SLOT_TSAN.
+  pthread_internal_t* main_thread = __get_main_thread();
+  __set_tls(main_thread->tls);
+  // Initialize HWASan. This sets up TLS_SLOT_TSAN, among other things.
+  __hwasan_init();
+  // We are ready to run HWASan-instrumented code, proceed with libc initialization...
 #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/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 15366af..543fdc5 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -240,17 +240,18 @@
   return 0;
 }
 
+__attribute__((no_sanitize("hwaddress")))
 static int __pthread_start(void* arg) {
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
 
+  __hwasan_thread_enter();
+
   // Wait for our creating thread to release us. This lets it have time to
   // notify gdb about this thread before we start doing anything.
   // This also provides the memory barrier needed to ensure that all memory
   // 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_internal.h b/libc/bionic/pthread_internal.h
index 1ec201b..65ec5ff 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -151,6 +151,9 @@
   return *__get_thread()->bionic_tls;
 }
 
+extern __LIBC_HIDDEN__ pthread_internal_t* __get_main_thread();
+extern "C" __LIBC_HIDDEN__ int __set_tls(void* ptr);
+
 __LIBC_HIDDEN__ void pthread_key_clean_all(void);
 
 // Address space is precious on LP32, so use the minimum unit: one page.
diff --git a/libc/upstream-netbsd/android/include/reentrant.h b/libc/upstream-netbsd/android/include/reentrant.h
index 3ca8fd6..e27a87b 100644
--- a/libc/upstream-netbsd/android/include/reentrant.h
+++ b/libc/upstream-netbsd/android/include/reentrant.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_NETBSD_REENTRANT_H_included
-#define _BIONIC_NETBSD_REENTRANT_H_included
+#pragma once
 
 #define _REENTRANT
 
@@ -23,18 +22,10 @@
 #include <signal.h>
 
 //
-// Map NetBSD libc internal locking to pthread locking.
+// Map NetBSD libc internal locking onto regular pthread locking.
 //
 
 #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
 #define mutex_t pthread_mutex_t
 #define mutex_lock(x) pthread_mutex_lock(x)
 #define mutex_unlock(x) pthread_mutex_unlock(x)
-
-#define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
-#define rwlock_t pthread_rwlock_t
-#define rwlock_rdlock pthread_rwlock_rdlock
-#define rwlock_unlock pthread_rwlock_unlock
-#define rwlock_wrlock pthread_rwlock_wrlock
-
-#endif