Merge "Lose bionic_atomic stuff."
diff --git a/libc/include/paths.h b/libc/include/paths.h
index 1eba536..33c2eee 100644
--- a/libc/include/paths.h
+++ b/libc/include/paths.h
@@ -39,7 +39,6 @@
 #define	_PATH_CONSOLE	"/dev/console"
 #define	_PATH_DEVNULL	"/dev/null"
 #define	_PATH_KLOG	"/proc/kmsg"
-#define	_PATH_MEM	"/dev/mem"
 
 #define	_PATH_MOUNTED	"/proc/mounts"
 #define	_PATH_TTY	"/dev/tty"
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c
index bac8dad..f3f0127 100644
--- a/libc/stdio/fread.c
+++ b/libc/stdio/fread.c
@@ -102,6 +102,12 @@
 		 * avoid copying it through the buffer?
 		 */
 		if (total > (size_t) fp->_bf._size) {
+			/*
+			 * Make sure that fseek doesn't think it can
+			 * reuse the buffer since we are going to read
+			 * directly from the file descriptor.
+			 */
+			fp->_flags |= __SMOD;
 			break;
 		}
 
diff --git a/libm/Android.mk b/libm/Android.mk
index dc6c704..ebc3c9f 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -130,7 +130,6 @@
     upstream-freebsd/lib/msun/src/s_fdim.c \
     upstream-freebsd/lib/msun/src/s_finite.c \
     upstream-freebsd/lib/msun/src/s_finitef.c \
-    upstream-freebsd/lib/msun/src/s_floor.c \
     upstream-freebsd/lib/msun/src/s_floorf.c \
     upstream-freebsd/lib/msun/src/s_fma.c \
     upstream-freebsd/lib/msun/src/s_fmaf.c \
@@ -264,20 +263,39 @@
 LOCAL_SRC_FILES_arm += \
     arm/fenv.c \
 
+# s_floor.S requires neon instructions.
+ifdef TARGET_2ND_ARCH
+arch_variant := $(TARGET_2ND_ARCH_VARIANT)
+else
+arch_variant := $(TARGET_ARCH_VARIANT)
+endif
+
+# 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
+else
+LOCAL_SRC_FILES_arm += arm/s_floor.S
+endif
+
 LOCAL_SRC_FILES_arm64 += \
     arm64/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_mips += \
     mips/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_mips64 += \
     mips/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_x86 += \
     i387/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_x86_64 += \
     amd64/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_C_INCLUDES_x86 += $(LOCAL_PATH)/i387
 
@@ -297,6 +315,9 @@
     -Wno-unknown-pragmas \
     -fvisibility=hidden \
 
+LOCAL_ASFLAGS := \
+    -Ibionic/libc \
+
 # Workaround the GCC "(long)fn -> lfn" optimization bug which will result in
 # self recursions for lrint, lrintf, and lrintl.
 # BUG: 14225968
diff --git a/libm/arm/s_floor.S b/libm/arm/s_floor.S
new file mode 100644
index 0000000..4405358
--- /dev/null
+++ b/libm/arm/s_floor.S
@@ -0,0 +1,142 @@
+/*
+ * 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(floor)    /* x in r0, r1 */
+
+        and             r3, r1, #0x80000000     /* sign(x) */
+        bic             r1, r1, #0x80000000     /* x = abs(x) */
+
+        /* extract exp of x */
+        lsr             r2, r1, #20
+        sub             r2, r2, #0x3fc
+        subs            r2, r2, #0x3            /* r2 <- exp */
+
+        /* |x| < 1.0? */
+        blt             .Lx_lt_one
+
+        /* x < 0? */
+        cmp             r3, #0
+        bne             .Lclr_frac_neg
+
+        /* |x| <= 2^20? */
+        cmp             r2, #20
+        ble             .Lclr_frac_r1
+
+        /* |x| < 2^52? */
+        cmp             r2, #52
+        blt             .Lclr_frac_r0
+
+        /* return x */
+        bx              lr
+
+.Lclr_frac_r1:
+        rsb             r2, r2, #20
+        lsr             r1, r1, r2
+        lsl             r1, r1, r2
+        mov             r0, #0
+        bx              lr
+
+.Lclr_frac_r0:
+        rsb             r2, r2, #52
+        lsr             r0, r0, r2
+        lsl             r0, r0, r2
+        bx              lr
+
+.Lclr_frac_neg:
+        /* |x| <= 2^20? */
+        cmp             r2, #20
+        ble             .Lclr_frac_r1_neg
+
+        /* |x| < 2^52? */
+        cmp             r2, #52
+        blt             .Lclr_frac_r0_neg
+
+        /* return x */
+        orr             r1, r1, #0x80000000
+        bx              lr
+
+.Lclr_frac_r1_neg:
+        rsb             r2, r2, #20
+        mov             r3, #1
+        lsl             r3, r3, r2
+        sub             r3, r3, #1
+        and             r3, r1, r3
+        orr             r3, r3, r0
+        lsr             r1, r1, r2
+        lsl             r1, r1, r2
+        mov             r0, #0
+        b               .Lreturn_x_neg
+
+.Lclr_frac_r0_neg:
+        rsb             r2, r2, #52
+        mov             r3, #1
+        lsl             r3, r3, r2
+        sub             r3, r3, #1
+        and             r3, r0, r3
+        lsr             r0, r0, r2
+        lsl             r0, r0, r2
+        b               .Lreturn_x_neg
+
+.Lx_lt_one:
+        /* x == +-0? */
+        cmp             r0, #0
+        cmpeq           r1, #0
+        orreq           r1, r1, r3
+        bxeq            lr
+
+        /* (x > 0) ? 0 : -1 */
+        mov             r1, #0x00100000
+        mov             r0, #0
+        cmp             r3, #0
+        movne           r1, #0xc0000000
+        sub             r1, r1, #0x00100000
+        bx              lr
+
+.Lreturn_x_neg:
+        cmp             r3, #0
+        orr             r1, r1, #0x80000000
+        bxeq            lr
+
+        vmov            d16, r0, r1
+        vmov.f64        d18, #1.0
+        vsub.f64        d16, d16, d18
+        vmov            r0, r1, d16
+        bx              lr
+
+END(floor)
+
+#if LDBL_MANT_DIG == 53
+        .weak           floorl
+        .equ            floorl,floor
+#endif
diff --git a/tests/Android.mk b/tests/Android.mk
index bd4695f..b3eea06 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -211,7 +211,7 @@
 include $(LOCAL_PATH)/Android.build.mk
 
 # -----------------------------------------------------------------------------
-# Library of bionic customized gtest main function.
+# Library of bionic customized gtest main function, with simplified output format.
 # -----------------------------------------------------------------------------
 libBionicGtestMain_src_files := gtest_main.cpp
 
@@ -228,6 +228,24 @@
 include $(LOCAL_PATH)/Android.build.mk
 
 # -----------------------------------------------------------------------------
+# Library of bionic customized gtest main function, with normal gtest output format,
+# which is needed by bionic cts test.
+# -----------------------------------------------------------------------------
+libBionicCtsGtestMain_src_files := gtest_main.cpp
+
+libBionicCtsGtestMain_cflags := $(test_cflags)
+
+libBionicCtsGtestMain_cppflags := $(test_cppflags) -DUSING_GTEST_OUTPUT_FORMAT
+
+module := libBionicCtsGtestMain
+module_tag := optional
+build_type := target
+build_target := STATIC_TEST_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+build_type := host
+include $(LOCAL_PATH)/Android.build.mk
+
+# -----------------------------------------------------------------------------
 # Tests for the device using bionic's .so. Run with:
 #   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests32
 #   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests64
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 664e4a1..b1953fc 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -295,6 +295,32 @@
   fflush(stdout);
 }
 
+// bionic cts test needs gtest output format.
+#if defined(USING_GTEST_OUTPUT_FORMAT)
+
+static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
+  ColoredPrintf(COLOR_GREEN, "[ RUN      ] ");
+  printf("%s\n", testcase.GetTestName(test_id).c_str());
+
+  const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
+  printf("%s", test_output.c_str());
+
+  TestResult result = testcase.GetTestResult(test_id);
+  if (result == TEST_SUCCESS) {
+    ColoredPrintf(COLOR_GREEN, "[       OK ] ");
+  } else {
+    ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+  }
+  printf("%s", testcase.GetTestName(test_id).c_str());
+  if (testing::GTEST_FLAG(print_time)) {
+    printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
+  }
+  printf("\n");
+  fflush(stdout);
+}
+
+#else  // !defined(USING_GTEST_OUTPUT_FORMAT)
+
 static void OnTestEndPrint(const TestCase& testcase, size_t test_id) {
   TestResult result = testcase.GetTestResult(test_id);
   if (result == TEST_SUCCESS) {
@@ -307,16 +333,17 @@
 
   printf("%s", testcase.GetTestName(test_id).c_str());
   if (testing::GTEST_FLAG(print_time)) {
-    printf(" (%" PRId64 " ms)\n", testcase.GetTestTime(test_id) / 1000000);
-  } else {
-    printf("\n");
+    printf(" (%" PRId64 " ms)", testcase.GetTestTime(test_id) / 1000000);
   }
+  printf("\n");
 
   const std::string& test_output = testcase.GetTest(test_id).GetTestOutput();
   printf("%s", test_output.c_str());
   fflush(stdout);
 }
 
+#endif  // !defined(USING_GTEST_OUTPUT_FORMAT)
+
 static void OnTestIterationEndPrint(const std::vector<TestCase>& testcase_list, size_t /*iteration*/,
                                     int64_t elapsed_time_ns) {
 
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 890e86e..2ecfc60 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -965,3 +965,41 @@
 TEST(stdio, fwrite_after_fread_fast_path) {
   test_fwrite_after_fread(64*1024);
 }
+
+// http://b/19172514
+TEST(stdio, fread_after_fseek) {
+  TemporaryFile tf;
+
+  FILE* fp = fopen(tf.filename, "w+");
+  ASSERT_TRUE(fp != nullptr);
+
+  char file_data[12288];
+  for (size_t i = 0; i < 12288; i++) {
+    file_data[i] = i;
+  }
+  ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp));
+  fclose(fp);
+
+  fp = fopen(tf.filename, "r");
+  ASSERT_TRUE(fp != nullptr);
+
+  char buffer[8192];
+  size_t cur_location = 0;
+  // Small read to populate internal buffer.
+  ASSERT_EQ(100U, fread(buffer, 1, 100, fp));
+  ASSERT_EQ(memcmp(file_data, buffer, 100), 0);
+
+  cur_location = static_cast<size_t>(ftell(fp));
+  // Large read to force reading into the user supplied buffer and bypassing
+  // the internal buffer.
+  ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp));
+  ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0);
+
+  // Small backwards seek to verify fseek does not reuse the internal buffer.
+  ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR));
+  cur_location = static_cast<size_t>(ftell(fp));
+  ASSERT_EQ(22U, fread(buffer, 1, 22, fp));
+  ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0);
+
+  fclose(fp);
+}