Merge "Use O_APPEND for stdio append mode."
diff --git a/libc/Android.bp b/libc/Android.bp
index 02dc934..d9b8a2b 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -42,6 +42,7 @@
     "-Wextra",
     "-Wunused",
     "-Wno-deprecated-declarations",
+    "-Wno-gcc-compat",
     "-Wframe-larger-than=2048",
 
     // Try to catch typical 32-bit assumptions that break with 64-bit pointers.
@@ -780,12 +781,7 @@
 // ========================================================
 cc_library_static {
     defaults: ["libc_defaults"],
-    srcs: [
-        "bionic/__memcpy_chk.cpp",
-        "bionic/__strcat_chk.cpp",
-        "bionic/__strcpy_chk.cpp",
-        "bionic/fortify.cpp",
-    ],
+    srcs: ["bionic/fortify.cpp"],
 
     name: "libc_fortify",
 
@@ -795,120 +791,86 @@
 
     arch: {
         arm: {
+            cflags: ["-DNO___MEMCPY_CHK"],
             srcs: [
                 "arch-arm/generic/bionic/__memcpy_chk.S",
             ],
-            exclude_srcs: [
-                "bionic/__memcpy_chk.cpp",
-            ],
             cortex_a7: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/cortex-a7/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a7/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             cortex_a53: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/cortex-a53/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a53/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             cortex_a53_a57: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/cortex-a15/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             cortex_a8: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/cortex-a15/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             cortex_a9: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/cortex-a9/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a9/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             cortex_a15: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/cortex-a15/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             cortex_a73: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/denver/bionic/__strcat_chk.S",
                     "arch-arm/denver/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             denver: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/denver/bionic/__strcat_chk.S",
                     "arch-arm/denver/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             krait: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/krait/bionic/__strcat_chk.S",
                     "arch-arm/krait/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
             kryo: {
+                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
                 srcs: [
                     "arch-arm/krait/bionic/__strcat_chk.S",
                     "arch-arm/krait/bionic/__strcpy_chk.S",
                 ],
-                exclude_srcs: [
-                    "bionic/__strcat_chk.cpp",
-                    "bionic/__strcpy_chk.cpp",
-                ],
             },
         },
         arm64: {
+            cflags: ["-DNO___MEMCPY_CHK"],
             srcs: [
                 "arch-arm64/generic/bionic/__memcpy_chk.S",
             ],
-            exclude_srcs: [
-                "bionic/__memcpy_chk.cpp",
-            ],
         },
     },
 }
@@ -2006,7 +1968,7 @@
             local_include_dirs: ["arch-x86_64/include"],
         },
     },
-    clang: false,
+    clang: true,
 }
 
 cc_defaults {
diff --git a/libc/arch-arm/generic/bionic/__memcpy_chk.S b/libc/arch-arm/generic/bionic/__memcpy_chk.S
index 7044e5f..7ee2a8f 100644
--- a/libc/arch-arm/generic/bionic/__memcpy_chk.S
+++ b/libc/arch-arm/generic/bionic/__memcpy_chk.S
@@ -28,16 +28,16 @@
 
 #include <private/bionic_asm.h>
 
-         .syntax unified
+  .syntax unified
 
 ENTRY(__memcpy_chk)
-        cmp         r2, r3
-        bls         memcpy
+  cmp         r2, r3
+  bls         memcpy
 
-        // Preserve lr for backtrace.
-        push        {lr}
-        .cfi_def_cfa_offset 4
-        .cfi_rel_offset lr, 0
+  // Preserve lr for backtrace.
+  push        {lr}
+  .cfi_def_cfa_offset 4
+  .cfi_rel_offset lr, 0
 
-        bl          __memcpy_chk_fail
+  bl          __memcpy_chk_fail
 END(__memcpy_chk)
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index d3a0f07..45c9ea7 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -30,16 +30,13 @@
 #include <stddef.h>
 #include <stdint.h>
 
-__attribute__((__section__(".preinit_array")))
-void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+#define SECTION(name) __attribute__((__section__(name)))
+SECTION(".preinit_array") void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
+SECTION(".init_array") void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
+SECTION(".fini_array") void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
+#undef SECTION
 
-__attribute__((__section__(".init_array")))
-void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
-
-__attribute__((__section__(".fini_array")))
-void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
-
-static void _start_main(void* raw_args) {
+static void _start_main(void* raw_args) __used {
   structors_array_t array;
   array.preinit_array = &__PREINIT_ARRAY__;
   array.init_array = &__INIT_ARRAY__;
diff --git a/libc/bionic/__memcpy_chk.cpp b/libc/bionic/__memcpy_chk.cpp
deleted file mode 100644
index 9463954..0000000
--- a/libc/bionic/__memcpy_chk.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 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 <string.h>
-
-#include "private/bionic_fortify.h"
-
-// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
-extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
-  __check_count("memcpy", "count", count);
-  __check_buffer_access("memcpy", "write into", count, dst_len);
-  return memcpy(dst, src, count);
-}
diff --git a/libc/bionic/__strcat_chk.cpp b/libc/bionic/__strcat_chk.cpp
deleted file mode 100644
index 16b2327..0000000
--- a/libc/bionic/__strcat_chk.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 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 <string.h>
-
-#include "private/bionic_fortify.h"
-
-// Runtime implementation of __builtin____strcat_chk (used directly by compiler, not in headers).
-extern "C" char* __strcat_chk(char* __restrict dst, const char* __restrict src,
-                              size_t dst_buf_size) {
-  char* save = dst;
-  size_t dst_len = __strlen_chk(dst, dst_buf_size);
-
-  dst += dst_len;
-  dst_buf_size -= dst_len;
-
-  while ((*dst++ = *src++) != '\0') {
-    dst_buf_size--;
-    if (__predict_false(dst_buf_size == 0)) {
-      __fortify_fatal("strcat: prevented write past end of %zu-byte buffer", dst_buf_size);
-    }
-  }
-
-  return save;
-}
diff --git a/libc/bionic/__strcpy_chk.cpp b/libc/bionic/__strcpy_chk.cpp
deleted file mode 100644
index 6fbfb8b..0000000
--- a/libc/bionic/__strcpy_chk.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 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 <string.h>
-
-#include "private/bionic_fortify.h"
-
-// Runtime implementation of __builtin____strcpy_chk (used directly by compiler, not in headers).
-extern "C" char* __strcpy_chk(char* dst, const char* src, size_t dst_len) {
-  // TODO: optimize so we don't scan src twice.
-  size_t src_len = strlen(src) + 1;
-  __check_buffer_access("strcpy", "write into", src_len, dst_len);
-  return strcpy(dst, src);
-}
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index b888f09..4a7ff13 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -456,3 +456,43 @@
   __check_buffer_access("write", "read from", count, buf_size);
   return write(fd, buf, count);
 }
+
+#if !defined(NO___STRCAT_CHK)
+// Runtime implementation of __builtin____strcat_chk (used directly by compiler, not in headers).
+extern "C" char* __strcat_chk(char* __restrict dst, const char* __restrict src,
+                              size_t dst_buf_size) {
+  char* save = dst;
+  size_t dst_len = __strlen_chk(dst, dst_buf_size);
+
+  dst += dst_len;
+  dst_buf_size -= dst_len;
+
+  while ((*dst++ = *src++) != '\0') {
+    dst_buf_size--;
+    if (__predict_false(dst_buf_size == 0)) {
+      __fortify_fatal("strcat: prevented write past end of %zu-byte buffer", dst_buf_size);
+    }
+  }
+
+  return save;
+}
+#endif // NO___STRCAT_CHK
+
+#if !defined(NO___STRCPY_CHK)
+// Runtime implementation of __builtin____strcpy_chk (used directly by compiler, not in headers).
+extern "C" char* __strcpy_chk(char* dst, const char* src, size_t dst_len) {
+  // TODO: optimize so we don't scan src twice.
+  size_t src_len = strlen(src) + 1;
+  __check_buffer_access("strcpy", "write into", src_len, dst_len);
+  return strcpy(dst, src);
+}
+#endif // NO___STRCPY_CHK
+
+#if !defined(NO___MEMCPY_CHK)
+// Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
+extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
+  __check_count("memcpy", "count", count);
+  __check_buffer_access("memcpy", "write into", count, dst_len);
+  return memcpy(dst, src, count);
+}
+#endif // NO___MEMCPY_CHK
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index c83c18d..7e3aa99 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -41,6 +41,8 @@
 
 #ifndef __ANDROID_API__
 #define __ANDROID_API__ __ANDROID_API_FUTURE__
+#else
+#define __ANDROID_NDK__ 1
 #endif
 
 #define __ANDROID_API_G__ 9
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index 82186c7..e26e5f2 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -29,6 +29,8 @@
 #ifndef _ANDROID_LEGACY_STDLIB_INLINES_H_
 #define _ANDROID_LEGACY_STDLIB_INLINES_H_
 
+#include <errno.h>
+#include <float.h>
 #include <stdlib.h>
 #include <sys/cdefs.h>
 
@@ -36,10 +38,16 @@
 
 __BEGIN_DECLS
 
-__noreturn void _Exit(int) __RENAME(_exit);
-
-static __inline float strtof(const char *nptr, char **endptr) {
-  return (float)strtod(nptr, endptr);
+static __inline float strtof(const char* nptr, char** endptr) {
+  double d = strtod(nptr, endptr);
+  if (d > FLT_MAX) {
+    errno = ERANGE;
+    return __builtin_huge_valf();
+  } else if (d < -FLT_MAX) {
+    errno = ERANGE;
+    return -__builtin_huge_valf();
+  }
+  return __BIONIC_CAST(static_cast, float, d);
 }
 
 static __inline double atof(const char *nptr) { return (strtod(nptr, NULL)); }