Merge "Put back inline definitions if using an old API."
diff --git a/CPPLINT.cfg b/CPPLINT.cfg
new file mode 100644
index 0000000..560d791
--- /dev/null
+++ b/CPPLINT.cfg
@@ -0,0 +1,2 @@
+set noparent
+filter=-build/header_guard,-runtime/int,-readability/function
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index a648c9f..0fa2a1e 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -134,7 +134,7 @@
 int fchmodat(int, const char*, mode_t, int)  all
 int fchownat(int, const char*, uid_t, gid_t, int)  all
 int fstatat64|fstatat:fstatat64(int, const char*, struct stat*, int)   arm,mips,x86
-int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)  arm64,mips64,x86_64
+int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)  arm64,x86_64
 int linkat(int, const char*, int, const char*, int)  all
 int mkdirat(int, const char*, mode_t)  all
 int mknodat(int, const char*, mode_t, dev_t)  all
@@ -179,7 +179,7 @@
 int statfs64|statfs:statfs(const char*, struct statfs*)  arm64,mips64,x86_64
 
 int     fstat64|fstat:fstat64(int, struct stat*)    arm,mips,x86
-int     fstat64|fstat:fstat(int, struct stat*)    arm64,mips64,x86_64
+int     fstat64|fstat:fstat(int, struct stat*)    arm64,x86_64
 
 # file system
 int     chdir(const char*)              all
diff --git a/libc/arch-mips64/bionic/stat.cpp b/libc/arch-mips64/bionic/stat.cpp
new file mode 100644
index 0000000..df63906
--- /dev/null
+++ b/libc/arch-mips64/bionic/stat.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <asm/unistd.h>
+
+struct kernel_stat {
+ unsigned int st_dev;
+ unsigned int st_pad0[3];
+ unsigned long st_ino;
+ mode_t st_mode;
+ __u32 st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ unsigned int st_rdev;
+ unsigned int st_pad1[3];
+ __kernel_off_t st_size;
+ unsigned int _st_atime;
+ unsigned int st_atime_nsec;
+ unsigned int _st_mtime;
+ unsigned int st_mtime_nsec;
+ unsigned int _st_ctime;
+ unsigned int st_ctime_nsec;
+ unsigned int st_blksize;
+ unsigned int st_pad2;
+ unsigned long st_blocks;
+};
+
+void copy_stat(struct stat *st, struct kernel_stat *s)
+{
+  st->st_dev = static_cast<dev_t>(s->st_dev);
+  st->st_ino = static_cast<ino_t>(s->st_ino);
+  st->st_mode = static_cast<mode_t>(s->st_mode);
+  st->st_nlink = static_cast<nlink_t>(s->st_nlink);
+  st->st_uid = static_cast<uid_t>(s->st_uid);
+  st->st_gid = static_cast<gid_t>(s->st_gid);
+  st->st_rdev = static_cast<dev_t>(s->st_rdev);
+  st->st_size = static_cast<off_t>(s->st_size);
+  st->st_blksize = static_cast<int>(s->st_blksize);
+  st->st_blocks = static_cast<long>(s->st_blocks);
+  st->st_atim.tv_sec = static_cast<time_t>(s->_st_atime);
+  st->st_atim.tv_nsec = static_cast<long>(s->st_atime_nsec);
+  st->st_mtim.tv_sec = static_cast<time_t>(s->_st_mtime);
+  st->st_mtim.tv_nsec = static_cast<long>(s->st_mtime_nsec);
+  st->st_ctim.tv_sec = static_cast<time_t>(s->_st_ctime);
+  st->st_ctim.tv_nsec = static_cast<long>(s->st_ctime_nsec);
+}
+
+int fstat(int fp, struct stat *st)
+{
+  kernel_stat s;
+  int ret;
+  ret = syscall (__NR_fstat, fp, &s);
+  copy_stat (st, &s);
+  return ret;
+}
+__strong_alias(fstat64, fstat);
+
+int newfstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
+{
+   kernel_stat s;
+   int ret;
+   ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
+   copy_stat(buf, &s);
+   return ret;
+}
+
+int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags)
+{
+   kernel_stat s;
+   int ret;
+   ret = syscall(__NR_newfstatat, dirfd, pathname, &s, flags);
+   copy_stat(buf, &s);
+   return ret;
+}
+__strong_alias(fstatat64, fstatat);
diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk
index 7990c69..1376395 100644
--- a/libc/arch-mips64/mips64.mk
+++ b/libc/arch-mips64/mips64.mk
@@ -52,6 +52,7 @@
     arch-mips64/bionic/setjmp.S \
     arch-mips64/bionic/syscall.S \
     arch-mips64/bionic/vfork.S \
+    arch-mips64/bionic/stat.cpp \
 
 libc_crt_target_cflags_mips64 := \
     $($(my_2nd_arch_prefix)TARGET_GLOBAL_CFLAGS) \
diff --git a/libc/arch-mips64/syscalls/fstat64.S b/libc/arch-mips64/syscalls/fstat64.S
deleted file mode 100644
index a14d51c..0000000
--- a/libc/arch-mips64/syscalls/fstat64.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(fstat64)
-    .set push
-    .set noreorder
-    li v0, __NR_fstat
-    syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
-    nop
-1:
-    move t0, ra
-    bal     2f
-    nop
-2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
-    .cpreturn
-    j t9
-    move ra, t0
-    .set pop
-END(fstat64)
-
-    .globl fstat
-    .equ fstat, fstat64
diff --git a/libc/arch-mips64/syscalls/fstatat64.S b/libc/arch-mips64/syscalls/fstatat64.S
deleted file mode 100644
index 7888a43..0000000
--- a/libc/arch-mips64/syscalls/fstatat64.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Generated by gensyscalls.py. Do not edit. */
-
-#include <private/bionic_asm.h>
-
-ENTRY(fstatat64)
-    .set push
-    .set noreorder
-    li v0, __NR_newfstatat
-    syscall
-    bnez a3, 1f
-    move a0, v0
-    j ra
-    nop
-1:
-    move t0, ra
-    bal     2f
-    nop
-2:
-    .cpsetup ra, t1, 2b
-    LA t9,__set_errno_internal
-    .cpreturn
-    j t9
-    move ra, t0
-    .set pop
-END(fstatat64)
-
-    .globl fstatat
-    .equ fstatat, fstatat64
diff --git a/libc/bionic/__cxa_guard.cpp b/libc/bionic/__cxa_guard.cpp
index 5b0d57d..5b34b58 100644
--- a/libc/bionic/__cxa_guard.cpp
+++ b/libc/bionic/__cxa_guard.cpp
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
-#include <stddef.h>
 #include <endian.h>
+#include <limits.h>
+#undef _USING_LIBCXX  // Prevent using of <atomic>.
+#include <stdatomic.h>
 
-#include "private/bionic_atomic_inline.h"
+#include <stddef.h>
+
 #include "private/bionic_futex.h"
 
 // This file contains C++ ABI support functions for one time
@@ -49,66 +52,82 @@
 // values. The LSB is tested by the compiler-generated code before calling
 // __cxa_guard_acquire.
 union _guard_t {
-    int volatile state;
-    int32_t aligner;
+  atomic_int state;
+  int32_t aligner;
 };
 
-const static int ready = 0x1;
-const static int pending = 0x2;
-const static int waiting = 0x6;
-
 #else
 // The Itanium/x86 C++ ABI (used by all other architectures) mandates that
 // guard variables are 64-bit aligned, 64-bit values. The LSB is tested by
 // the compiler-generated code before calling __cxa_guard_acquire.
 union _guard_t {
-    int volatile state;
-    int64_t aligner;
+  atomic_int state;
+  int64_t aligner;
 };
 
-const static int ready     = letoh32(0x1);
-const static int pending   = letoh32(0x100);
-const static int waiting   = letoh32(0x10000);
 #endif
 
+// Set construction state values according to reference documentation.
+// 0 is the initialization value.
+// Arm requires ((*gv & 1) == 1) after __cxa_guard_release, ((*gv & 3) == 0) after __cxa_guard_abort.
+// X86 requires first byte not modified by __cxa_guard_acquire, first byte is non-zero after
+// __cxa_guard_release.
+
+#define CONSTRUCTION_NOT_YET_STARTED                0
+#define CONSTRUCTION_COMPLETE                       1
+#define CONSTRUCTION_UNDERWAY_WITHOUT_WAITER    0x100
+#define CONSTRUCTION_UNDERWAY_WITH_WAITER       0x200
+
 extern "C" int __cxa_guard_acquire(_guard_t* gv) {
-    // 0 -> pending, return 1
-    // pending -> waiting, wait and return 0
-    // waiting: untouched, wait and return 0
-    // ready: untouched, return 0
+  int old_value = atomic_load_explicit(&gv->state, memory_order_relaxed);
 
-retry:
-    if (__bionic_cmpxchg(0, pending, &gv->state) == 0) {
-        ANDROID_MEMBAR_FULL();
-        return 1;
-    }
-    __bionic_cmpxchg(pending, waiting, &gv->state); // Indicate there is a waiter
-    __futex_wait(&gv->state, waiting, NULL);
-
-    if (gv->state != ready) {
-        // __cxa_guard_abort was called, let every thread try since there is no return code for this condition
-        goto retry;
+  while (true) {
+    if (old_value == CONSTRUCTION_COMPLETE) {
+      // A load_acquire operation is need before exiting with COMPLETE state, as we have to ensure
+      // that all the stores performed by the construction function are observable on this CPU
+      // after we exit.
+      atomic_thread_fence(memory_order_acquire);
+      return 0;
+    } else if (old_value == CONSTRUCTION_NOT_YET_STARTED) {
+      if (!atomic_compare_exchange_weak_explicit(&gv->state, &old_value,
+                                                  CONSTRUCTION_UNDERWAY_WITHOUT_WAITER,
+                                                  memory_order_relaxed,
+                                                  memory_order_relaxed)) {
+        continue;
+      }
+      // The acquire fence may not be needed. But as described in section 3.3.2 of
+      // the Itanium C++ ABI specification, it probably has to behave like the
+      // acquisition of a mutex, which needs an acquire fence.
+      atomic_thread_fence(memory_order_acquire);
+      return 1;
+    } else if (old_value == CONSTRUCTION_UNDERWAY_WITHOUT_WAITER) {
+      if (!atomic_compare_exchange_weak_explicit(&gv->state, &old_value,
+                                                 CONSTRUCTION_UNDERWAY_WITH_WAITER,
+                                                 memory_order_relaxed,
+                                                 memory_order_relaxed)) {
+        continue;
+      }
     }
 
-    ANDROID_MEMBAR_FULL();
-    return 0;
+    __futex_wait_ex(&gv->state, false, CONSTRUCTION_UNDERWAY_WITH_WAITER, NULL);
+    old_value = atomic_load_explicit(&gv->state, memory_order_relaxed);
+  }
 }
 
 extern "C" void __cxa_guard_release(_guard_t* gv) {
-    // pending -> ready
-    // waiting -> ready, and wake
-
-    ANDROID_MEMBAR_FULL();
-    if (__bionic_cmpxchg(pending, ready, &gv->state) == 0) {
-        return;
-    }
-
-    gv->state = ready;
-    __futex_wake(&gv->state, 0x7fffffff);
+  // Release fence is used to make all stores performed by the construction function
+  // visible in other threads.
+  int old_value = atomic_exchange_explicit(&gv->state, CONSTRUCTION_COMPLETE, memory_order_release);
+  if (old_value == CONSTRUCTION_UNDERWAY_WITH_WAITER) {
+    __futex_wake_ex(&gv->state, false, INT_MAX);
+  }
 }
 
 extern "C" void __cxa_guard_abort(_guard_t* gv) {
-    ANDROID_MEMBAR_FULL();
-    gv->state= 0;
-    __futex_wake(&gv->state, 0x7fffffff);
+  // Release fence is used to make all stores performed by the construction function
+  // visible in other threads.
+  int old_value = atomic_exchange_explicit(&gv->state, CONSTRUCTION_NOT_YET_STARTED, memory_order_release);
+  if (old_value == CONSTRUCTION_UNDERWAY_WITH_WAITER) {
+    __futex_wake_ex(&gv->state, false, INT_MAX);
+  }
 }
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index c74a52c..10521cf 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -19,6 +19,7 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "private/bionic_systrace.h"
 #include "private/libc_logging.h"
diff --git a/libc/bionic/debug_stacktrace.cpp b/libc/bionic/debug_stacktrace.cpp
index 7d3c76e..c6ce714 100644
--- a/libc/bionic/debug_stacktrace.cpp
+++ b/libc/bionic/debug_stacktrace.cpp
@@ -30,6 +30,7 @@
 
 #include <dlfcn.h>
 #include <inttypes.h>
+#include <malloc.h>
 #include <unistd.h>
 #include <unwind.h>
 #include <sys/types.h>
diff --git a/libc/bionic/dirent.cpp b/libc/bionic/dirent.cpp
index 6d87097..fb45398 100644
--- a/libc/bionic/dirent.cpp
+++ b/libc/bionic/dirent.cpp
@@ -30,6 +30,8 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <malloc.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
diff --git a/libc/bionic/getcwd.cpp b/libc/bionic/getcwd.cpp
index 47c807f..a8bbcf3 100644
--- a/libc/bionic/getcwd.cpp
+++ b/libc/bionic/getcwd.cpp
@@ -26,8 +26,10 @@
  * SUCH DAMAGE.
  */
 
-#include <unistd.h>
 #include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
 
 extern "C" int __getcwd(char* buf, size_t size);
 
diff --git a/libc/bionic/malloc_debug_common.cpp b/libc/bionic/malloc_debug_common.cpp
index 38c6583..1a2765a 100644
--- a/libc/bionic/malloc_debug_common.cpp
+++ b/libc/bionic/malloc_debug_common.cpp
@@ -41,6 +41,7 @@
 
 #include <pthread.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include "private/ScopedPthreadMutexLocker.h"
diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp
index 2f4949b..fa40b35 100644
--- a/libc/bionic/malloc_debug_qemu.cpp
+++ b/libc/bionic/malloc_debug_qemu.cpp
@@ -45,6 +45,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <stdio.h>
+#include <string.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/param.h>
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index 3c664d9..9991573 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -31,6 +31,7 @@
 #include "private/kernel_sigset_t.h"
 
 #include <errno.h>
+#include <malloc.h>
 #include <stdio.h>
 #include <string.h>
 
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 7406b35..c6d8494 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -29,6 +29,7 @@
 #include <pthread.h>
 
 #include <errno.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <unistd.h>
 
diff --git a/libc/bionic/pthread_once.cpp b/libc/bionic/pthread_once.cpp
index 6d9d7d1..7688a23 100644
--- a/libc/bionic/pthread_once.cpp
+++ b/libc/bionic/pthread_once.cpp
@@ -27,74 +27,59 @@
  */
 
 #include <pthread.h>
+#include <stdatomic.h>
 
-#include "private/bionic_atomic_inline.h"
 #include "private/bionic_futex.h"
 
-#define ONCE_INITIALIZING           (1 << 0)
-#define ONCE_COMPLETED              (1 << 1)
+#define ONCE_INITIALIZATION_NOT_YET_STARTED   0
+#define ONCE_INITIALIZATION_UNDERWAY          1
+#define ONCE_INITIALIZATION_COMPLETE          2
 
 /* NOTE: this implementation doesn't support a init function that throws a C++ exception
  *       or calls fork()
  */
 int pthread_once(pthread_once_t* once_control, void (*init_routine)(void)) {
-  volatile pthread_once_t* once_control_ptr = once_control;
+  static_assert(sizeof(atomic_int) == sizeof(pthread_once_t),
+                "pthread_once_t should actually be atomic_int in implementation.");
 
-  // PTHREAD_ONCE_INIT is 0, we use the following bit flags
-  //   bit 0 set  -> initialization is under way
-  //   bit 1 set  -> initialization is complete
+  // We prefer casting to atomic_int instead of declaring pthread_once_t to be atomic_int directly.
+  // Because using the second method pollutes pthread.h, and causes an error when compiling libcxx.
+  atomic_int* once_control_ptr = reinterpret_cast<atomic_int*>(once_control);
 
   // First check if the once is already initialized. This will be the common
   // case and we want to make this as fast as possible. Note that this still
   // requires a load_acquire operation here to ensure that all the
   // stores performed by the initialization function are observable on
   // this CPU after we exit.
-  if (__predict_true((*once_control_ptr & ONCE_COMPLETED) != 0)) {
-    ANDROID_MEMBAR_FULL();
-    return 0;
-  }
+  int old_value = atomic_load_explicit(once_control_ptr, memory_order_acquire);
 
   while (true) {
-    // Try to atomically set the INITIALIZING flag.
-    // This requires a cmpxchg loop, and we may need
-    // to exit prematurely if we detect that
-    // COMPLETED is now set.
-    int32_t  old_value, new_value;
-
-    do {
-      old_value = *once_control_ptr;
-      if ((old_value & ONCE_COMPLETED) != 0) {
-        break;
-      }
-
-      new_value = old_value | ONCE_INITIALIZING;
-    } while (__bionic_cmpxchg(old_value, new_value, once_control_ptr) != 0);
-
-    if ((old_value & ONCE_COMPLETED) != 0) {
-      // We detected that COMPLETED was set while in our loop.
-      ANDROID_MEMBAR_FULL();
+    if (__predict_true(old_value == ONCE_INITIALIZATION_COMPLETE)) {
       return 0;
     }
 
-    if ((old_value & ONCE_INITIALIZING) == 0) {
-      // We got there first, we can jump out of the loop to handle the initialization.
-      break;
+    // Try to atomically set the initialization underway flag. This requires a compare exchange
+    // in a loop, and we may need to exit prematurely if the initialization is complete.
+    if (!atomic_compare_exchange_weak_explicit(once_control_ptr, &old_value,
+                                               ONCE_INITIALIZATION_UNDERWAY,
+                                               memory_order_acquire, memory_order_acquire)) {
+      continue;
     }
 
-    // Another thread is running the initialization and hasn't completed
-    // yet, so wait for it, then try again.
+    if (old_value == ONCE_INITIALIZATION_NOT_YET_STARTED) {
+      // We got here first, we can handle the initialization.
+      (*init_routine)();
+
+      // Do a store_release indicating that initialization is complete.
+      atomic_store_explicit(once_control_ptr, ONCE_INITIALIZATION_COMPLETE, memory_order_release);
+
+      // Wake up any waiters, if any.
+      __futex_wake_ex(once_control_ptr, 0, INT_MAX);
+      return 0;
+    }
+
+    // The initialization is underway, wait for its finish.
     __futex_wait_ex(once_control_ptr, 0, old_value, NULL);
+    old_value = atomic_load_explicit(once_control_ptr, memory_order_acquire);
   }
-
-  // Call the initialization function.
-  (*init_routine)();
-
-  // Do a store_release indicating that initialization is complete.
-  ANDROID_MEMBAR_FULL();
-  *once_control_ptr = ONCE_COMPLETED;
-
-  // Wake up any waiters, if any.
-  __futex_wake_ex(once_control_ptr, 0, INT_MAX);
-
-  return 0;
 }
diff --git a/libc/bionic/pthread_setname_np.cpp b/libc/bionic/pthread_setname_np.cpp
index 93d4b2f..c4e9fb8 100644
--- a/libc/bionic/pthread_setname_np.cpp
+++ b/libc/bionic/pthread_setname_np.cpp
@@ -30,6 +30,7 @@
 
 #include <fcntl.h>
 #include <stdio.h> // For snprintf.
+#include <string.h>
 #include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index 645f072..a240663 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <link.h>
+#include <string.h>
 #include <sys/auxv.h>
 #include <unistd.h>
 
diff --git a/libc/dns/net/getservent.c b/libc/dns/net/getservent.c
index 9f6ec32..0a727c7 100644
--- a/libc/dns/net/getservent.c
+++ b/libc/dns/net/getservent.c
@@ -28,6 +28,7 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>
 #include <endian.h>
+#include <malloc.h>
 #include <netdb.h>
 #include "servent.h"
 #include "services.h"
diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c
index 573fcbe..5a78450 100644
--- a/libc/dns/resolv/res_cache.c
+++ b/libc/dns/resolv/res_cache.c
@@ -104,10 +104,6 @@
  */
 #define  CONFIG_ENV  "BIONIC_DNSCACHE"
 
-/* entries older than CONFIG_SECONDS seconds are always discarded.
- */
-#define  CONFIG_SECONDS    (60*10)    /* 10 minutes */
-
 /* default number of entries kept in the cache. This value has been
  * determined by browsing through various sites and counting the number
  * of corresponding requests. Keep in mind that our framework is currently
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 2178789..4281132 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -112,7 +112,7 @@
 
 typedef int pthread_key_t;
 
-typedef volatile int pthread_once_t;
+typedef int pthread_once_t;
 
 #define PTHREAD_ONCE_INIT 0
 
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 308007a..cbd7aeb 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -95,7 +95,7 @@
 _BIONIC_NOT_BEFORE_21(extern long long llabs(long long) __pure2;)
 
 extern char * realpath(const char *path, char *resolved);
-extern int system(const char * string);
+extern int system(const char *string);
 
 extern void * bsearch(const void *key, const void *base0,
 	size_t nmemb, size_t size,
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 620f46a..c22516f 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -36,7 +36,7 @@
 
 __BEGIN_DECLS
 
-#if defined(__aarch64__)
+#if defined(__aarch64__) || (defined(__mips__) && defined(__LP64__))
 #define __STAT64_BODY \
   dev_t st_dev; \
   ino_t st_ino; \
@@ -56,7 +56,7 @@
   unsigned int __unused4; \
   unsigned int __unused5; \
 
-#elif defined(__mips__) /* and mips64 */
+#elif defined(__mips__) && !defined(__LP64__)
 #define __STAT64_BODY \
   unsigned int st_dev; \
   unsigned int __pad0[3]; \
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index c889544..6fe9524 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -30,9 +30,11 @@
 
 #include <errno.h>
 #include <inttypes.h>
+#include <pthread.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <sys/socket.h>
@@ -212,6 +214,23 @@
     return;
   }
 
+  // Mutex to prevent multiple crashing threads from trying to talk
+  // to debuggerd at the same time.
+  static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER;
+  int ret = pthread_mutex_trylock(&crash_mutex);
+  if (ret != 0) {
+    if (ret == EBUSY) {
+      __libc_format_log(ANDROID_LOG_INFO, "libc",
+                        "Another thread has contacted debuggerd first, stop and wait for process to die.");
+      // This will never complete since the lock is never released.
+      pthread_mutex_lock(&crash_mutex);
+    } else {
+      __libc_format_log(ANDROID_LOG_INFO, "libc",
+                        "pthread_mutex_trylock failed: %s", strerror(ret));
+    }
+    return;
+  }
+
   int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM | SOCK_CLOEXEC);
   if (s == -1) {
     __libc_format_log(ANDROID_LOG_FATAL, "libc", "Unable to open connection to debuggerd: %s",
@@ -228,7 +247,7 @@
   msg.tid = gettid();
   msg.abort_msg_address = reinterpret_cast<uintptr_t>(g_abort_message);
   msg.original_si_code = (info != nullptr) ? info->si_code : 0;
-  int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
+  ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
   if (ret == sizeof(msg)) {
     char debuggerd_ack;
     ret = TEMP_FAILURE_RETRY(read(s, &debuggerd_ack, 1));
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 7ef94c0..9a8dbc9 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -20,6 +20,7 @@
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <android/dlext.h>
 
 #include <bionic/pthread_internal.h>
diff --git a/linker/linker_allocator.cpp b/linker/linker_allocator.cpp
index 92220e8..ac11b97 100644
--- a/linker/linker_allocator.cpp
+++ b/linker/linker_allocator.cpp
@@ -13,8 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "linker_allocator.h"
 #include <inttypes.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <unistd.h>
 
diff --git a/linker/linker_environ.cpp b/linker/linker_environ.cpp
index daee56f..7272f4e 100644
--- a/linker/linker_environ.cpp
+++ b/linker/linker_environ.cpp
@@ -31,6 +31,7 @@
 #include <linux/auxvec.h>
 #include <stddef.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include "private/KernelArgumentBlock.h"
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index af4dc25..91a2fb8 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -29,6 +29,7 @@
 #include "linker_phdr.h"
 
 #include <errno.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index b0740b0..e199449 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -91,6 +91,8 @@
          "  --warnline=[TIME_IN_MS]\n"
          "      Test running longer than [TIME_IN_MS] will be warned.\n"
          "      It takes effect only in isolation mode. Default warnline is 2000 ms.\n"
+         "  --gtest-filter=POSITIVE_PATTERNS[-NEGATIVE_PATTERNS]\n"
+         "      Used as a synonym for --gtest_filter option in gtest.\n"
          "\nDefault bionic unit test option is -j.\n"
          "\n");
 }
@@ -720,6 +722,15 @@
   return static_cast<size_t>(sysconf(_SC_NPROCESSORS_ONLN));
 }
 
+static void AddGtestFilterSynonym(std::vector<char*>& args) {
+  // Support --gtest-filter as a synonym for --gtest_filter.
+  for (size_t i = 1; i < args.size(); ++i) {
+    if (strncmp(args[i], "--gtest-filter", strlen("--gtest-filter")) == 0) {
+      args[i][7] = '_';
+    }
+  }
+}
+
 struct IsolationTestOptions {
   bool isolate;
   size_t job_count;
@@ -748,6 +759,8 @@
     }
   }
 
+  AddGtestFilterSynonym(args);
+
   // if --bionic-selftest argument is used, only enable self tests, otherwise remove self tests.
   bool enable_selftest = false;
   for (size_t i = 1; i < args.size(); ++i) {