Merge "Rename fortify_sprintf_warnings.cpp to fortify_compilation_test.cpp."
diff --git a/libc/bionic/locale.cpp b/libc/bionic/locale.cpp
index 90aa7b8..b42b440 100644
--- a/libc/bionic/locale.cpp
+++ b/libc/bionic/locale.cpp
@@ -58,15 +58,18 @@
   DISALLOW_COPY_AND_ASSIGN(__locale_t);
 };
 
+size_t __ctype_get_mb_cur_max() {
+  locale_t l = uselocale(NULL);
+  if (l == LC_GLOBAL_LOCALE) {
+    return __bionic_current_locale_is_utf8 ? 4 : 1;
+  } else {
+    return l->mb_cur_max;
+  }
+}
+
 static pthread_once_t g_locale_once = PTHREAD_ONCE_INIT;
 static lconv g_locale;
 
-// We don't use pthread_once for this so that we know when the resource (a TLS slot) will be taken.
-static pthread_key_t g_uselocale_key;
-__attribute__((constructor)) static void __bionic_tls_uselocale_key_init() {
-  pthread_key_create(&g_uselocale_key, NULL);
-}
-
 static void __locale_init() {
   g_locale.decimal_point = const_cast<char*>(".");
 
@@ -97,15 +100,6 @@
   g_locale.int_n_sign_posn = CHAR_MAX;
 }
 
-size_t __ctype_get_mb_cur_max() {
-  locale_t l = reinterpret_cast<locale_t>(pthread_getspecific(g_uselocale_key));
-  if (l == nullptr || l == LC_GLOBAL_LOCALE) {
-    return __bionic_current_locale_is_utf8 ? 4 : 1;
-  } else {
-    return l->mb_cur_max;
-  }
-}
-
 static bool __is_supported_locale(const char* locale) {
   return (strcmp(locale, "") == 0 ||
           strcmp(locale, "C") == 0 ||
@@ -162,7 +156,16 @@
   return const_cast<char*>(__bionic_current_locale_is_utf8 ? "C.UTF-8" : "C");
 }
 
+// We can't use a constructor to create g_uselocal_key, because it may be used in constructors.
+static pthread_once_t g_uselocale_once = PTHREAD_ONCE_INIT;
+static pthread_key_t g_uselocale_key;
+
+static void g_uselocale_key_init() {
+  pthread_key_create(&g_uselocale_key, NULL);
+}
+
 locale_t uselocale(locale_t new_locale) {
+  pthread_once(&g_uselocale_once, g_uselocale_key_init);
   locale_t old_locale = static_cast<locale_t>(pthread_getspecific(g_uselocale_key));
 
   // If this is the first call to uselocale(3) on this thread, we return LC_GLOBAL_LOCALE.
diff --git a/libc/dns/resolv/res_state.c b/libc/dns/resolv/res_state.c
index 7533d19..459f073 100644
--- a/libc/dns/resolv/res_state.c
+++ b/libc/dns/resolv/res_state.c
@@ -39,6 +39,8 @@
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #include <sys/_system_properties.h>
 
+#include "private/ThreadLocalBuffer.h"
+
 /* Set to 1 to enable debug traces */
 #define DEBUG 0
 
@@ -50,8 +52,6 @@
 #  define D(...)  do{}while(0)
 #endif
 
-static pthread_key_t   _res_key;
-
 typedef struct {
     int                  _h_errno;
     // TODO: Have one __res_state per network so we don't have to repopulate frequently.
@@ -105,12 +105,7 @@
     free(rt);
 }
 
-__attribute__((constructor))
-static void
-_res_init_key( void )
-{
-    pthread_key_create( &_res_key, _res_thread_free );
-}
+BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR(_res_key, _res_thread_free);
 
 static _res_thread*
 _res_thread_get(void)
diff --git a/libc/private/ThreadLocalBuffer.h b/libc/private/ThreadLocalBuffer.h
index e5bd28c..cc47317 100644
--- a/libc/private/ThreadLocalBuffer.h
+++ b/libc/private/ThreadLocalBuffer.h
@@ -38,15 +38,17 @@
 
 // We used to use pthread_once to initialize the keys, but life is more predictable
 // if we allocate them all up front when the C library starts up, via __constructor__.
+#define BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR(key_name, key_destructor) \
+  static pthread_key_t key_name; \
+  __attribute__((constructor)) static void __bionic_tls_ ## key_name ## _key_init() { \
+    pthread_key_create(&key_name, key_destructor); \
+  }
 
 #define GLOBAL_INIT_THREAD_LOCAL_BUFFER(name) \
-  static pthread_key_t __bionic_tls_ ## name ## _key; \
   static void __bionic_tls_ ## name ## _key_destroy(void* buffer) { \
     free(buffer); \
   } \
-  __attribute__((constructor)) static void __bionic_tls_ ## name ## _key_init() { \
-    pthread_key_create(&__bionic_tls_ ## name ## _key, __bionic_tls_ ## name ## _key_destroy); \
-  }
+  BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR(__bionic_tls_ ## name ## _key, __bionic_tls_ ## name ## _key_destroy)
 
 // Leaves "name_tls_buffer" and "name_tls_buffer_size" defined and initialized.
 #define LOCAL_INIT_THREAD_LOCAL_BUFFER(type, name, byte_count) \
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 04f5fd2..1ab8d4a 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -72,13 +72,13 @@
 
 /*
  * Bionic uses some pthread keys internally. All pthread keys used internally
- * should be created in constructors.
+ * should be created in constructors, except for keys that may be used in or before constructors.
  * We need to manually maintain the count of pthread keys used internally, but
  * pthread_test should fail if we forget.
  * Following are current pthread keys used internally by libc:
  *  basename               libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  dirname                libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- *  uselocale              libc
+ *  uselocale              libc (can be used in constructors)
  *  getmntent_mntent       libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  getmntent_strings      libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  ptsname                libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
@@ -87,7 +87,7 @@
  *  strsignal              libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  passwd                 libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
  *  group                  libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- *  _res_key               libc
+ *  _res_key               libc (BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR)
  */
 
 #define LIBC_PTHREAD_KEY_RESERVED_COUNT 12
diff --git a/libm/Android.mk b/libm/Android.mk
index 3139bc2..15c390c 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -252,8 +252,6 @@
 # -----------------------------------------------------------------------------
 LOCAL_SRC_FILES_arm += \
     arm/fenv.c \
-    upstream-freebsd/lib/msun/src/e_sqrt.c \
-    upstream-freebsd/lib/msun/src/e_sqrtf.c \
     upstream-freebsd/lib/msun/src/s_ceil.c \
     upstream-freebsd/lib/msun/src/s_ceilf.c \
     upstream-freebsd/lib/msun/src/s_fma.c \
@@ -277,9 +275,17 @@
 
 # Use the C version on armv7-a since it doesn't support neon instructions.
 ifeq ($(arch_variant),armv7-a)
-LOCAL_SRC_FILES_arm += upstream-freebsd/lib/msun/src/s_floor.c
+LOCAL_SRC_FILES_arm += \
+    upstream-freebsd/lib/msun/src/e_sqrt.c \
+    upstream-freebsd/lib/msun/src/e_sqrtf.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
+
 else
-LOCAL_SRC_FILES_arm += arm/s_floor.S
+LOCAL_SRC_FILES_arm += \
+    arm/e_sqrt.S \
+    arm/e_sqrtf.S \
+    arm/s_floor.S \
+
 endif
 
 # -----------------------------------------------------------------------------
diff --git a/libm/arm/e_sqrt.S b/libm/arm/e_sqrt.S
new file mode 100644
index 0000000..669212f
--- /dev/null
+++ b/libm/arm/e_sqrt.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA Corporation.  All rights reserved.
+ * Johnny Qiu <joqiu@nvidia.com>
+ * Shu Zhang <chazhang@nvidia.com>
+ *
+ * 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.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 <float.h>
+#include <private/bionic_asm.h>
+
+ENTRY(sqrt)
+    vmov.f64    d0, r0, r1
+    vsqrt.f64   d0, d0
+    vmov.f64    r0, r1, d0
+    bx          lr
+END(sqrt)
+
+#if LDBL_MANT_DIG == 53
+    .weak       sqrtl
+    .equ        sqrtl, sqrt
+#endif
diff --git a/libm/arm/e_sqrtf.S b/libm/arm/e_sqrtf.S
new file mode 100644
index 0000000..ddefb22
--- /dev/null
+++ b/libm/arm/e_sqrtf.S
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013-2014, NVIDIA Corporation.  All rights reserved.
+ * Johhnny Qiu <joqiu@nvidia.com>
+ * Shu Zhang <chazhang@nvidia.com>
+ *
+ * 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.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 <private/bionic_asm.h>
+
+ENTRY(sqrtf)
+    vmov.f32    s0, r0
+    vsqrt.f32   s0, s0
+    vmov.f32    r0, s0
+    bx          lr
+END(sqrtf)