Merge "Update bionic headers to 9dbfd8ad7."
diff --git a/NOTICE b/NOTICE
index 1b996e9..6882d0c 100644
--- a/NOTICE
+++ b/NOTICE
@@ -382,6 +382,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2007 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.
+
+-------------------------------------------------------------------
+
 Copyright (C) 2008 The Android Open Source Project
 
 Licensed under the Apache License, Version 2.0 (the "License");
@@ -933,22 +961,6 @@
 -------------------------------------------------------------------
 
 Copyright (C) 2017 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
-Copyright (C) 2017 The Android Open Source Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/headers/android/legacy_termios_inlines.h b/headers/android/legacy_termios_inlines.h
index 4424bdb..02e9429 100644
--- a/headers/android/legacy_termios_inlines.h
+++ b/headers/android/legacy_termios_inlines.h
@@ -91,6 +91,18 @@
   s->c_cflag |= CS8;
 }
 
+static __inline int cfsetspeed(struct termios* s, speed_t speed) {
+  // TODO: check 'speed' is valid.
+  s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
+  return 0;
+}
+
+static __inline int tcdrain(int fd) {
+  // A non-zero argument to TCSBRK means "don't send a break".
+  // The drain is a side-effect of the ioctl!
+  return ioctl(fd, TCSBRK, __BIONIC_CAST(static_cast, unsigned long, 1));
+}
+
 __END_DECLS
 
 #endif
diff --git a/headers/fcntl.h b/headers/fcntl.h
index 9efed05..86e9a08 100644
--- a/headers/fcntl.h
+++ b/headers/fcntl.h
@@ -71,13 +71,14 @@
 int creat64(const char*, mode_t) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-int openat(int, const char*, int, ...);
+int openat(int, const char*, int, ...) __overloadable
+        __RENAME_CLANG(openat);
 
 #if __ANDROID_API__ >= 21
 int openat64(int, const char*, int, ...) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-int open(const char*, int, ...);
+int open(const char*, int, ...) __overloadable __RENAME_CLANG(open);
 
 #if __ANDROID_API__ >= 21
 int open64(const char*, int, ...) __INTRODUCED_IN(21);
@@ -128,22 +129,77 @@
 
 #if __ANDROID_API__ >= 17
 int __open_2(const char*, int) __INTRODUCED_IN(17);
-#endif /* __ANDROID_API__ >= 17 */
-
-int __open_real(const char*, int, ...) __RENAME(open);
-
-#if __ANDROID_API__ >= 17
 int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
 #endif /* __ANDROID_API__ >= 17 */
 
+/*
+ * These are the easiest way to call the real open even in clang FORTIFY.
+ */
+int __open_real(const char*, int, ...) __RENAME(open);
 int __openat_real(int, const char*, int, ...) __RENAME(openat);
-__errordecl(__creat_missing_mode, "called with O_CREAT, but missing mode");
-__errordecl(__creat_too_many_args, "too many arguments");
+
 
 #if defined(__BIONIC_FORTIFY)
+#define __open_too_many_args_error "too many arguments"
+#define __open_too_few_args_error "called with O_CREAT, but missing mode"
+#if defined(__clang__)
 
-#if !defined(__clang__)
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+        __errorattr(__open_too_many_args_error);
 
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int open(const char* pathname, int flags) __overloadable
+        __enable_if(flags & O_CREAT, __open_too_few_args_error)
+        __errorattr(__open_too_few_args_error);
+
+/*
+ * pass_object_size serves two purposes here, neither of which involve __bos: it
+ * disqualifies this function from having its address taken (so &open works),
+ * and it makes overload resolution prefer open(const char *, int) over
+ * open(const char *, int, ...).
+ */
+__BIONIC_FORTIFY_INLINE
+int open(const char* const __pass_object_size pathname,
+         int flags) __overloadable {
+    return __open_2(pathname, flags);
+}
+
+__BIONIC_FORTIFY_INLINE
+int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
+        __overloadable {
+    return __open_real(pathname, flags, modes);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int openat(int dirfd, const char* pathname, int flags) __overloadable
+        __enable_if(flags & O_CREAT, __open_too_few_args_error)
+        __errorattr(__open_too_few_args_error);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+        __overloadable
+        __errorattr(__open_too_many_args_error);
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* const __pass_object_size pathname,
+           int flags) __overloadable {
+    return __openat_2(dirfd, pathname, flags);
+}
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* const __pass_object_size pathname, int flags,
+           mode_t modes) __overloadable {
+    return __openat_real(dirfd, pathname, flags, modes);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#else /* defined(__clang__) */
+__errordecl(__creat_missing_mode, __open_too_few_args_error);
+__errordecl(__creat_too_many_args, __open_too_many_args_error);
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
 __BIONIC_FORTIFY_INLINE
 int open(const char* pathname, int flags, ...) {
     if (__builtin_constant_p(flags)) {
@@ -181,9 +237,12 @@
 
     return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
 }
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
-#endif /* !defined(__clang__) */
+#endif /* defined(__clang__) */
 
+#undef __open_too_many_args_error
+#undef __open_too_few_args_error
 #endif /* defined(__BIONIC_FORTIFY) */
 
 __END_DECLS
diff --git a/headers/malloc.h b/headers/malloc.h
index 12c7011..4cef300 100644
--- a/headers/malloc.h
+++ b/headers/malloc.h
@@ -24,7 +24,12 @@
 __BEGIN_DECLS
 
 #if defined(__clang__)
-#define __BIONIC_ALLOC_SIZE(...) /* clang doesn't support attribute alloc_size. */
+/* clang should support alloc_size in the nearish future. */
+#if __has_attribute(alloc_size)
+#error "We should enable alloc_size for clang."
+#else
+#define __BIONIC_ALLOC_SIZE(...)
+#endif
 #else
 #define __BIONIC_ALLOC_SIZE(...) __attribute__((__alloc_size__(__VA_ARGS__)))
 #endif
diff --git a/headers/poll.h b/headers/poll.h
index 8869846..a8895c3 100644
--- a/headers/poll.h
+++ b/headers/poll.h
@@ -38,43 +38,73 @@
 
 typedef unsigned int nfds_t;
 
-int poll(struct pollfd*, nfds_t, int);
+int poll(struct pollfd*, nfds_t, int) __overloadable __RENAME_CLANG(poll);
 
 #if __ANDROID_API__ >= 21
-int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __INTRODUCED_IN(21);
+int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*)
+        __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
 
 
 #if __ANDROID_API__ >= 23
 int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
-#endif /* __ANDROID_API__ >= 23 */
-
-int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
-__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
-
-
-#if __ANDROID_API__ >= 23
 int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
   __INTRODUCED_IN(23);
 #endif /* __ANDROID_API__ >= 23 */
 
 
-#if __ANDROID_API__ >= 21
+#if defined(__BIONIC_FORTIFY)
+#if __ANDROID_API__ >= __ANDROID_API_M__
+#if defined(__clang__)
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int poll(struct pollfd* fds, nfds_t fd_count, int timeout) __overloadable
+        __enable_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                    __bos(fds) < sizeof(*fds) * fd_count,
+                    "selected when there aren't fd_count fds")
+        __errorattr("too many fds specified");
+
+__BIONIC_FORTIFY_INLINE
+int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count,
+        int timeout) __overloadable {
+  size_t bos_fds = __bos(fds);
+
+  if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+      return __call_bypassing_fortify(poll)(fds, fd_count, timeout);
+  }
+
+  return __poll_chk(fds, fd_count, timeout, bos_fds);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
+          const sigset_t* mask)  __overloadable
+        __enable_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                    __bos(fds) < sizeof(*fds) * fd_count,
+                    "selected when there aren't fd_count fds")
+        __errorattr("too many fds specified");
+
+__BIONIC_FORTIFY_INLINE
+int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count,
+          const struct timespec* timeout, const sigset_t* mask) __overloadable {
+  size_t bos_fds = __bos(fds);
+
+  if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+      return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask);
+  }
+
+  return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds);
+}
+#else /* defined(__clang__) */
+int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
+__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
+
 int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll)
   __INTRODUCED_IN(21);
-#endif /* __ANDROID_API__ >= 21 */
-
 __errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
 
-#if defined(__BIONIC_FORTIFY)
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
 __BIONIC_FORTIFY_INLINE
 int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
-#if defined(__clang__)
-  return __poll_chk(fds, fd_count, timeout, __bos(fds));
-#else
   if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
     if (!__builtin_constant_p(fd_count)) {
       return __poll_chk(fds, fd_count, timeout, __bos(fds));
@@ -83,14 +113,11 @@
     }
   }
   return __poll_real(fds, fd_count, timeout);
-#endif
 }
 
 __BIONIC_FORTIFY_INLINE
-int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask) {
-#if defined(__clang__)
-  return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
-#else
+int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
+          const sigset_t* mask) {
   if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
     if (!__builtin_constant_p(fd_count)) {
       return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
@@ -99,11 +126,11 @@
     }
   }
   return __ppoll_real(fds, fd_count, timeout, mask);
-#endif
 }
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
 
-#endif
+#endif /* defined(__clang__) */
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+#endif /* defined(__BIONIC_FORTIFY) */
 
 __END_DECLS
 
diff --git a/headers/stdio.h b/headers/stdio.h
index 70b89a9..c9976aa 100644
--- a/headers/stdio.h
+++ b/headers/stdio.h
@@ -121,13 +121,16 @@
 int	 ferror(FILE *);
 int	 fflush(FILE *);
 int	 fgetc(FILE *);
-char	*fgets(char * __restrict, int, FILE * __restrict);
+char	*fgets(char * __restrict, int, FILE * __restrict) __overloadable
+  __RENAME_CLANG(fgets);
 int	 fprintf(FILE * __restrict , const char * __restrict _Nonnull, ...) __printflike(2, 3);
 int	 fputc(int, FILE *);
 int	 fputs(const char * __restrict, FILE * __restrict);
-size_t	 fread(void * __restrict, size_t, size_t, FILE * __restrict);
+size_t	 fread(void * __restrict, size_t, size_t, FILE * __restrict)
+      __overloadable __RENAME_CLANG(fread);
 int	 fscanf(FILE * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3);
-size_t	 fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);
+size_t	 fwrite(const void * __restrict, size_t, size_t, FILE * __restrict)
+    __overloadable __RENAME_CLANG(fwrite);
 int	 getc(FILE *);
 int	 getchar(void);
 
@@ -163,12 +166,17 @@
     (defined(__cplusplus) && __cplusplus <= 201103L)
 char* gets(char*) __attribute__((deprecated("gets is unsafe, use fgets instead")));
 #endif
-int sprintf(char* __restrict, const char* __restrict _Nonnull, ...) __printflike(2, 3);
-int vsprintf(char* __restrict, const char* __restrict _Nonnull, __va_list) __printflike(2, 0);
-char* tmpnam(char*) __attribute__((deprecated("tmpnam is unsafe, use mkstemp or tmpfile instead")));
+int sprintf(char* __restrict, const char* __restrict _Nonnull, ...)
+    __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf")
+    __overloadable __RENAME_CLANG(sprintf);
+int vsprintf(char* __restrict, const char* __restrict _Nonnull, __va_list)
+    __overloadable __printflike(2, 0) __RENAME_CLANG(vsprintf)
+    __warnattr_strict("vsprintf is often misused; please use vsnprintf");
+char* tmpnam(char*)
+    __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
 #define P_tmpdir "/tmp/" /* deprecated */
 char* tempnam(const char*, const char*)
-    __attribute__((deprecated("tempnam is unsafe, use mkstemp or tmpfile instead")));
+    __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
 
 int rename(const char*, const char*);
 int renameat(int, const char*, int, const char*);
@@ -238,10 +246,12 @@
 #endif /* __ANDROID_API__ >= 24 */
 
 
-int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...) __printflike(3, 4);
+int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...)
+    __printflike(3, 4) __overloadable __RENAME_CLANG(snprintf);
 int vfscanf(FILE* __restrict, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
 int vscanf(const char* _Nonnull , __va_list) __scanflike(1, 0);
-int vsnprintf(char* __restrict, size_t, const char* __restrict _Nonnull, __va_list) __printflike(3, 0);
+int vsnprintf(char* __restrict, size_t, const char* __restrict _Nonnull, __va_list)
+    __printflike(3, 0) __overloadable __RENAME_CLANG(vsnprintf);
 int vsscanf(const char* __restrict _Nonnull, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
 
 #define L_ctermid 1024 /* size for ctermid() */
@@ -298,74 +308,189 @@
 char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
 #endif /* __ANDROID_API__ >= 17 */
 
-char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
-__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
-__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
-
 
 #if __ANDROID_API__ >= 24
 size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
-  __INTRODUCED_IN(24);
+    __INTRODUCED_IN(24);
+size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
+    __INTRODUCED_IN(24);
 #endif /* __ANDROID_API__ >= 24 */
 
+
+#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE __printflike(3, 0)
+int vsnprintf(char *const __pass_object_size dest, size_t size,
+              const char *_Nonnull format, __va_list ap) __overloadable {
+    return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
+}
+
+__BIONIC_FORTIFY_INLINE __printflike(2, 0)
+int vsprintf(char *const __pass_object_size dest, const char *_Nonnull format,
+             __va_list ap) __overloadable {
+    return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if defined(__clang__)
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+/*
+ * Simple case: `format` can't have format specifiers, so we can just compare
+ * its length to the length of `dest`
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int snprintf(char *__restrict dest, size_t size, const char *__restrict format)
+    __overloadable
+    __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                __bos(dest) < __builtin_strlen(format),
+                "format string will always overflow destination buffer")
+    __errorattr("format string will always overflow destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+__printflike(3, 4)
+int snprintf(char *__restrict const __pass_object_size dest,
+             size_t size, const char *__restrict format, ...) __overloadable {
+    va_list va;
+    va_start(va, format);
+    int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
+    va_end(va);
+    return result;
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int sprintf(char *__restrict dest, const char *__restrict format) __overloadable
+    __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                __bos(dest) < __builtin_strlen(format),
+                "format string will always overflow destination buffer")
+    __errorattr("format string will always overflow destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+__printflike(2, 3)
+int sprintf(char *__restrict const __pass_object_size dest,
+        const char *__restrict format, ...) __overloadable {
+    va_list va;
+    va_start(va, format);
+    int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
+    va_end(va);
+    return result;
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict buf, size_t size, size_t count,
+             FILE *__restrict stream) __overloadable
+        __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
+        __errorattr("size * count overflows");
+
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict buf, size_t size, size_t count,
+             FILE *__restrict stream) __overloadable
+    __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
+    __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                size * count > __bos(buf), "size * count is too large")
+    __errorattr("size * count is too large");
+
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict const __pass_object_size0 buf, size_t size,
+             size_t count, FILE *__restrict stream) __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(fread)(buf, size, count, stream);
+    }
+
+    return __fread_chk(buf, size, count, stream, bos);
+}
+
+size_t fwrite(const void * __restrict buf, size_t size,
+              size_t count, FILE * __restrict stream) __overloadable
+    __enable_if(__unsafe_check_mul_overflow(size, count),
+                "size * count overflows")
+    __errorattr("size * count overflows");
+
+size_t fwrite(const void * __restrict buf, size_t size,
+              size_t count, FILE * __restrict stream) __overloadable
+    __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
+    __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                size * count > __bos(buf), "size * count is too large")
+    __errorattr("size * count is too large");
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void * __restrict const __pass_object_size0 buf,
+              size_t size, size_t count, FILE * __restrict stream)
+        __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
+    }
+
+    return __fwrite_chk(buf, size, count, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char *fgets(char* __restrict dest, int size, FILE* stream) __overloadable
+    __enable_if(size < 0, "size is negative")
+    __errorattr("size is negative");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char *fgets(char* dest, int size, FILE* stream) __overloadable
+    __enable_if(size >= 0 && size > __bos(dest),
+                "size is larger than the destination buffer")
+    __errorattr("size is larger than the destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+char *fgets(char* __restrict const __pass_object_size dest,
+        int size, FILE* stream) __overloadable {
+    size_t bos = __bos(dest);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(fgets)(dest, size, stream);
+    }
+
+    return __fgets_chk(dest, size, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#else /* defined(__clang__) */
+
 size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
 __errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
 __errordecl(__fread_overflow, "fread called with overflowing size * count");
 
-
-#if __ANDROID_API__ >= 24
-size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
-  __INTRODUCED_IN(24);
-#endif /* __ANDROID_API__ >= 24 */
+char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
+__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
+__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
 
 size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
 __errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
 __errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
 
-#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-__printflike(3, 0) int vsnprintf(char* dest, size_t size, const char* _Nonnull format, __va_list ap) {
-    return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
+__BIONIC_FORTIFY_INLINE __printflike(3, 4)
+int snprintf(char *__restrict dest, size_t size, const char* _Nonnull format, ...)
+{
+    return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format,
+                                    __builtin_va_arg_pack());
 }
 
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 0) int vsprintf(char* dest, const char* _Nonnull format, __va_list ap) {
-    return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
+__BIONIC_FORTIFY_INLINE __printflike(2, 3)
+int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
+    return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
+                                   __builtin_va_arg_pack());
 }
-
-#if defined(__clang__)
-  #if !defined(snprintf)
-    #define __wrap_snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)
-    #define snprintf(...) __wrap_snprintf(__VA_ARGS__)
-  #endif
-#else
-__BIONIC_FORTIFY_INLINE
-__printflike(3, 4) int snprintf(char* dest, size_t size, const char* _Nonnull format, ...) {
-    return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack());
-}
-#endif
-
-#if defined(__clang__)
-  #if !defined(sprintf)
-    #define __wrap_sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__)
-    #define sprintf(...) __wrap_sprintf(__VA_ARGS__)
-  #endif
-#else
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 3) int sprintf(char* dest, const char* _Nonnull format, ...) {
-    return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack());
-}
-#endif
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
 #if __ANDROID_API__ >= __ANDROID_API_N__
 __BIONIC_FORTIFY_INLINE
-size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
+size_t fread(void *__restrict buf, size_t size, size_t count, FILE * __restrict stream) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __fread_real(buf, size, count, stream);
     }
@@ -382,7 +507,6 @@
 
         return __fread_real(buf, size, count, stream);
     }
-#endif
 
     return __fread_chk(buf, size, count, stream, bos);
 }
@@ -391,7 +515,6 @@
 size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __fwrite_real(buf, size, count, stream);
     }
@@ -408,14 +531,12 @@
 
         return __fwrite_real(buf, size, count, stream);
     }
-#endif
 
     return __fwrite_chk(buf, size, count, stream, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
 
-#if !defined(__clang__)
-
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
 __BIONIC_FORTIFY_INLINE
 char *fgets(char* dest, int size, FILE* stream) {
     size_t bos = __bos(dest);
@@ -445,9 +566,9 @@
 
     return __fgets_chk(dest, size, stream, bos);
 }
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
-#endif /* !defined(__clang__) */
-
+#endif /* defined(__clang__) */
 #endif /* defined(__BIONIC_FORTIFY) */
 
 #if defined(__clang__)
diff --git a/headers/stdlib.h b/headers/stdlib.h
index 8f44409..d16bb2c 100644
--- a/headers/stdlib.h
+++ b/headers/stdlib.h
@@ -115,8 +115,9 @@
 long atol(const char*) __attribute_pure__;
 long long atoll(const char*) __attribute_pure__;
 
-char* realpath(const char* path, char* resolved);
-int system(const char* string);
+char * realpath(const char *path, char *resolved) __overloadable
+        __RENAME_CLANG(realpath);
+int system(const char *string);
 
 void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
               int (*compar)(const void*, const void*));
@@ -220,24 +221,44 @@
 #endif
 
 #if defined(__BIONIC_FORTIFY)
+#define __realpath_buf_too_small_str \
+    "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer"
+
+/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
+#define __PATH_MAX 4096
+
+#if defined(__clang__)
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* realpath(const char* path, char* resolved) __overloadable
+    __enable_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                __bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str)
+    __errorattr(__realpath_buf_too_small_str);
+
+/* No need for a FORTIFY version; the only things we can catch are at
+ * compile-time.
+ */
+
+#else /* defined(__clang__) */
 
 char* __realpath_real(const char*, char*) __RENAME(realpath);
-__errordecl(__realpath_size_error, "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer");
+__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
 
-#if !defined(__clang__)
 __BIONIC_FORTIFY_INLINE
 char* realpath(const char* path, char* resolved) {
     size_t bos = __bos(resolved);
 
-    /* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
-    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < 4096) {
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
         __realpath_size_error();
     }
 
     return __realpath_real(path, resolved);
 }
-#endif
 
+#endif /* defined(__clang__) */
+
+#undef __PATH_MAX
+#undef __realpath_buf_too_small_str
 #endif /* defined(__BIONIC_FORTIFY) */
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
diff --git a/headers/string.h b/headers/string.h
index 0b957d2..08f6722 100644
--- a/headers/string.h
+++ b/headers/string.h
@@ -47,10 +47,13 @@
 #endif
 
 void* memccpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, int, size_t);
-void* memchr(const void* _Nonnull, int, size_t) __attribute_pure__;
-void* memrchr(const void* _Nonnull, int, size_t) __attribute_pure__;
+void* memchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable
+        __RENAME_CLANG(memchr);
+void* memrchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable
+        __RENAME_CLANG(memrchr);
 int memcmp(const void* _Nonnull, const void* _Nonnull, size_t) __attribute_pure__;
-void* memcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t);
+void* memcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t)
+        __overloadable __RENAME_CLANG(memcpy);
 #if defined(__USE_GNU)
 
 #if __ANDROID_API__ >= 23
@@ -58,11 +61,13 @@
 #endif /* __ANDROID_API__ >= 23 */
 
 #endif
-void* memmove(void* _Nonnull, const void* _Nonnull, size_t);
-void* memset(void* _Nonnull, int, size_t);
+void* memmove(void* _Nonnull, const void* _Nonnull, size_t) __overloadable
+        __RENAME_CLANG(memmove);
+void* memset(void* _Nonnull, int, size_t) __overloadable __RENAME_CLANG(memset);
 void* memmem(const void* _Nonnull, size_t, const void* _Nonnull, size_t) __attribute_pure__;
 
-char* strchr(const char* _Nonnull, int) __attribute_pure__;
+char* strchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
+        __RENAME_CLANG(strchr);
 
 #if __ANDROID_API__ >= 18
 char* __strchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
@@ -81,28 +86,33 @@
 #endif
 #endif
 
-char* strrchr(const char* _Nonnull, int) __attribute_pure__;
+char* strrchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
+        __RENAME_CLANG(strrchr);
 
 #if __ANDROID_API__ >= 18
 char* __strrchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
 #endif /* __ANDROID_API__ >= 18 */
 
 
-size_t strlen(const char* _Nonnull) __attribute_pure__;
+size_t strlen(const char* _Nonnull) __attribute_pure__ __overloadable
+        __RENAME_CLANG(strlen);
 
 #if __ANDROID_API__ >= 17
 size_t __strlen_chk(const char* _Nonnull, size_t) __INTRODUCED_IN(17);
 #endif /* __ANDROID_API__ >= 17 */
 
+
 int strcmp(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
 
 #if __ANDROID_API__ >= 21
-char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull__restrict) __INTRODUCED_IN(21);
+char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
+        __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict);
-char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict);
-
+char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
+        __overloadable __RENAME_CLANG(strcpy);
+char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict)
+        __overloadable __RENAME_CLANG(strcat);
 char* strdup(const char* _Nonnull);
 
 char* strstr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
@@ -116,29 +126,30 @@
 char* strerror_l(int, locale_t) __INTRODUCED_IN(23);
 #endif /* __ANDROID_API__ >= 23 */
 
-#if defined(__USE_GNU)
-
-#if __ANDROID_API__ >= 23
+#if defined(__USE_GNU) && __ANDROID_API__ >= 23
 char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23);
-#endif /* __ANDROID_API__ >= 23 */
-
 #else /* POSIX */
 int strerror_r(int, char*, size_t);
 #endif
 
 size_t strnlen(const char* _Nonnull, size_t) __attribute_pure__;
-char* strncat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t);
+char* strncat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
+        __overloadable __RENAME_CLANG(strncat);
 char* strndup(const char* _Nonnull, size_t);
 int strncmp(const char* _Nonnull, const char* _Nonnull, size_t) __attribute_pure__;
 
 #if __ANDROID_API__ >= 21
-char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) __INTRODUCED_IN(21);
+char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
+        __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t);
+char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
+        __overloadable __RENAME_CLANG(strncpy);
 
-size_t strlcat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t);
-size_t strlcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t);
+size_t strlcat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
+        __overloadable __RENAME_CLANG(strlcat);
+size_t strlcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
+        __overloadable __RENAME_CLANG(strlcpy);
 
 size_t strcspn(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
 char* strpbrk(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
@@ -177,18 +188,9 @@
 
 #if __ANDROID_API__ >= 23
 void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-#endif /* __ANDROID_API__ >= 23 */
-
-__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
-
-
-#if __ANDROID_API__ >= 23
 void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
 #endif /* __ANDROID_API__ >= 23 */
 
-__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
-void* __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr);
-
 
 #if __ANDROID_API__ >= 21
 char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
@@ -197,27 +199,288 @@
   __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-size_t __strlcpy_real(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) __RENAME(strlcpy);
 
 #if __ANDROID_API__ >= 17
 size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
-#endif /* __ANDROID_API__ >= 17 */
-
-size_t __strlcat_real(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) __RENAME(strlcat);
-
-#if __ANDROID_API__ >= 17
 size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
 #endif /* __ANDROID_API__ >= 17 */
 
 
+/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
+ * have the definition out here.
+ */
+struct __bionic_zero_size_is_okay_t {};
+
 #if defined(__BIONIC_FORTIFY)
+// These can share their implementation between gcc and clang with minimal
+// trickery...
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0,
+        const void* _Nonnull __restrict src, size_t copy_amount) __overloadable {
+    return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memmove(void* const _Nonnull dst __pass_object_size0,
+        const void* _Nonnull src, size_t len) __overloadable {
+    return __builtin___memmove_chk(dst, src, len, __bos0(dst));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpcpy(char* _Nonnull __restrict const dst __pass_object_size,
+        const char* _Nonnull __restrict src) __overloadable {
+    return __builtin___stpcpy_chk(dst, src, __bos(dst));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+char* strcpy(char* _Nonnull __restrict const dst __pass_object_size,
+        const char* _Nonnull __restrict src) __overloadable {
+    return __builtin___strcpy_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strcat(char* _Nonnull __restrict const dst __pass_object_size,
+        const char* _Nonnull __restrict src) __overloadable {
+    return __builtin___strcat_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncat(char* const _Nonnull __restrict dst __pass_object_size,
+        const char* _Nonnull __restrict src, size_t n) __overloadable {
+    return __builtin___strncat_chk(dst, src, n, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n)
+        __overloadable {
+    return __builtin___memset_chk(s, c, n, __bos0(s));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+
+#if defined(__clang__)
+
+#define __error_if_overflows_dst(name, dst, n, what) \
+    __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
+                __bos0(dst) < (n), "selected when the buffer is too small") \
+    __errorattr(#name " called with " what " bigger than buffer")
+
+/*
+ * N.B. _Nonnull isn't necessary on params, since these functions just emit
+ * errors.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
+        __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memmove(void *dst, const void* src, size_t len) __overloadable
+        __error_if_overflows_dst(memmove, dst, len, "size");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memset(void* s, int c, size_t n) __overloadable
+        __error_if_overflows_dst(memset, s, n, "size");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* stpcpy(char* dst, const char* src) __overloadable
+        __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* strcpy(char* dst, const char* src) __overloadable
+        __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
 
 #if __ANDROID_API__ >= __ANDROID_API_M__
 __BIONIC_FORTIFY_INLINE
-void* memchr(const void* s, int c, size_t n) {
+void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
+        __overloadable {
     size_t bos = __bos(s);
 
-#if !defined(__clang__)
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_memchr(s, c, n);
+    }
+
+    return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
+        __overloadable {
+    size_t bos = __bos(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(memrchr)(s, c, n);
+    }
+
+    return __memrchr_chk(s, c, n, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size,
+        const char* __restrict const _Nonnull src __pass_object_size,
+        size_t n) __overloadable {
+    size_t bos_dst = __bos(dst);
+    size_t bos_src = __bos(src);
+
+    /* Ignore dst size checks; they're handled in strncpy_chk */
+    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+    }
+
+    return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncpy(char* __restrict const _Nonnull dst __pass_object_size,
+        const char* __restrict const _Nonnull src __pass_object_size,
+        size_t n) __overloadable {
+    size_t bos_dst = __bos(dst);
+    size_t bos_src = __bos(src);
+
+    /* Ignore dst size checks; they're handled in strncpy_chk */
+    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin___strncpy_chk(dst, src, n, bos_dst);
+    }
+
+    return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size,
+        const char *_Nonnull __restrict src, size_t size) __overloadable {
+    size_t bos = __bos(dst);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(strlcpy)(dst, src, size);
+    }
+
+    return __strlcpy_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size,
+        const char* _Nonnull __restrict src, size_t size) __overloadable {
+    size_t bos = __bos(dst);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(strlcat)(dst, src, size);
+    }
+
+    return __strlcat_chk(dst, src, size, bos);
+}
+
+/*
+ * If we can evaluate the size of s at compile-time, just call __builtin_strlen
+ * on it directly. This makes it way easier for compilers to fold things like
+ * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
+ * because it's large.
+ */
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* const _Nonnull s __pass_object_size)
+        __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
+                                   "enabled if s is a known good string.") {
+    return __builtin_strlen(s);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* const _Nonnull s __pass_object_size0)
+        __overloadable {
+    size_t bos = __bos0(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strlen(s);
+    }
+
+    // return __builtin_strlen(s);
+    return __strlen_chk(s, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if  __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+char* strchr(const char* const _Nonnull s __pass_object_size0, int c)
+        __overloadable {
+    size_t bos = __bos0(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strchr(s, c);
+    }
+
+    // return __builtin_strchr(s, c);
+    return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
+        __overloadable {
+    size_t bos = __bos(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strrchr(s, c);
+    }
+
+    return __strrchr_chk(s, c, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
+ * flipped the size + value arguments. However, there may be cases (e.g. with
+ * macros) where it's okay for the size to fold to zero. We should warn on this,
+ * but we should also provide a FORTIFY'ed escape hatch.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memset(void* _Nonnull s, int c, size_t n,
+             struct __bionic_zero_size_is_okay_t ok)
+        __overloadable
+        __error_if_overflows_dst(memset, s, n, "size");
+
+__BIONIC_FORTIFY_INLINE
+void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n,
+             struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
+        __overloadable {
+    return __builtin___memset_chk(s, c, n, __bos0(s));
+}
+
+extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
+/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
+ * flipping size + count will do nothing.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memset(void* _Nonnull s, int c, size_t n) __overloadable
+        __enable_if(c && !n, "selected when we'll set zero bytes")
+        __RENAME_CLANG(memset)
+        __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
+                        "(Add __bionic_zero_size_is_okay as a fourth argument "
+                        "to silence this.)");
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#undef __error_zero_size
+#undef __error_if_overflows_dst
+#else // defined(__clang__)
+extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strcpy);
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
+    __RENAME(strlcpy);
+extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
+    __RENAME(strlcat);
+
+__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
+__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
+    size_t bos = __bos(s);
+
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __builtin_memchr(s, c, n);
     }
@@ -229,7 +492,6 @@
     if (__builtin_constant_p(n) && (n <= bos)) {
         return __builtin_memchr(s, c, n);
     }
-#endif
 
     return __memchr_chk(s, c, n, bos);
 }
@@ -238,7 +500,6 @@
 void* memrchr(const void* s, int c, size_t n) {
     size_t bos = __bos(s);
 
-#if !defined(__clang__)
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __memrchr_real(s, c, n);
     }
@@ -250,38 +511,11 @@
     if (__builtin_constant_p(n) && (n <= bos)) {
         return __memrchr_real(s, c, n);
     }
-#endif
 
     return __memrchr_chk(s, c, n, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
 
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-void* memcpy(void* _Nonnull __restrict dst, const void* _Nonnull __restrict src, size_t copy_amount) {
-    return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memmove(void* _Nonnull dst, const void* _Nonnull src, size_t len) {
-    return __builtin___memmove_chk(dst, src, len, __bos0(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src) {
-    return __builtin___stpcpy_chk(dst, src, __bos(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-char* strcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src) {
-    return __builtin___strcpy_chk(dst, src, __bos(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
 #if __ANDROID_API__ >= __ANDROID_API_L__
 __BIONIC_FORTIFY_INLINE
 char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
@@ -310,7 +544,7 @@
     size_t bos_src = __bos(src);
 
     if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin___strncpy_chk(dst, src, n, bos_dst);
+        return __strncpy_real(dst, src, n);
     }
 
     if (__builtin_constant_p(n) && (n <= bos_src)) {
@@ -328,25 +562,10 @@
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
 __BIONIC_FORTIFY_INLINE
-char* strcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src) {
-    return __builtin___strcat_chk(dst, src, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-char *strncat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
-    return __builtin___strncat_chk(dst, src, n, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memset(void* _Nonnull s, int c, size_t n) {
-    return __builtin___memset_chk(s, c, n, __bos0(s));
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
+size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size,
+        const char* _Nonnull __restrict src, size_t size) {
     size_t bos = __bos(dst);
 
-#if !defined(__clang__)
     // Compiler doesn't know destination size. Don't call __strlcpy_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __strlcpy_real(dst, src, size);
@@ -357,17 +576,14 @@
     if (__builtin_constant_p(size) && (size <= bos)) {
         return __strlcpy_real(dst, src, size);
     }
-#endif /* !defined(__clang__) */
 
     return __strlcpy_chk(dst, src, size, bos);
 }
 
-
 __BIONIC_FORTIFY_INLINE
 size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
     size_t bos = __bos(dst);
 
-#if !defined(__clang__)
     // Compiler doesn't know destination size. Don't call __strlcat_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __strlcat_real(dst, src, size);
@@ -378,16 +594,14 @@
     if (__builtin_constant_p(size) && (size <= bos)) {
         return __strlcat_real(dst, src, size);
     }
-#endif /* !defined(__clang__) */
 
     return __strlcat_chk(dst, src, size, bos);
 }
 
 __BIONIC_FORTIFY_INLINE
-size_t strlen(const char* _Nonnull s) {
+size_t strlen(const char* _Nonnull s) __overloadable {
     size_t bos = __bos(s);
 
-#if !defined(__clang__)
     // Compiler doesn't know destination size. Don't call __strlen_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __builtin_strlen(s);
@@ -397,7 +611,6 @@
     if (__builtin_constant_p(slen)) {
         return slen;
     }
-#endif /* !defined(__clang__) */
 
     return __strlen_chk(s, bos);
 }
@@ -408,7 +621,6 @@
 char* strchr(const char* _Nonnull s, int c) {
     size_t bos = __bos(s);
 
-#if !defined(__clang__)
     // Compiler doesn't know destination size. Don't call __strchr_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __builtin_strchr(s, c);
@@ -418,7 +630,6 @@
     if (__builtin_constant_p(slen) && (slen < bos)) {
         return __builtin_strchr(s, c);
     }
-#endif /* !defined(__clang__) */
 
     return __strchr_chk(s, c, bos);
 }
@@ -427,7 +638,6 @@
 char* strrchr(const char* _Nonnull s, int c) {
     size_t bos = __bos(s);
 
-#if !defined(__clang__)
     // Compiler doesn't know destination size. Don't call __strrchr_chk
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __builtin_strrchr(s, c);
@@ -437,12 +647,11 @@
     if (__builtin_constant_p(slen) && (slen < bos)) {
         return __builtin_strrchr(s, c);
     }
-#endif /* !defined(__clang__) */
 
     return __strrchr_chk(s, c, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
+#endif /* defined(__clang__) */
 #endif /* defined(__BIONIC_FORTIFY) */
 
 #if defined(__clang__)
diff --git a/headers/sys/_system_properties.h b/headers/sys/_system_properties.h
index ffa6d2e..186d390 100644
--- a/headers/sys/_system_properties.h
+++ b/headers/sys/_system_properties.h
@@ -30,6 +30,8 @@
 #define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
 
 #include <sys/cdefs.h>
+#include <stdbool.h>
+#include <stdint.h>
 
 #ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #error you should #include <sys/system_properties.h> instead
@@ -91,7 +93,7 @@
 **
 ** Returns the serial number on success, -1 on error.
 */
-unsigned int __system_property_area_serial();
+uint32_t __system_property_area_serial();
 
 /* Add a new system property.  Can only be done by a single
 ** process that has write access to the property area, and
@@ -118,12 +120,26 @@
 **
 ** Returns the serial number on success, -1 on error.
 */
-unsigned int __system_property_serial(const prop_info *pi);
+uint32_t __system_property_serial(const prop_info* pi);
 
-/* Wait for any system property to be updated.  Caller must pass
-** in 0 the first time, and the previous return value on each
-** successive call. */
-unsigned int __system_property_wait_any(unsigned int serial);
+/*
+ * Waits for the specific system property identified by `pi` to be updated
+ * past `old_serial`. Waits no longer than `relative_timeout`, or forever
+ * if `relaive_timeout` is null.
+ *
+ * If `pi` is null, waits for the global serial number instead.
+ *
+ * If you don't know the current serial, use 0.
+ *
+ * Returns true and updates `*new_serial_ptr` on success, or false if the call
+ * timed out.
+ */
+struct timespec;
+bool __system_property_wait(const prop_info* pi,
+                            uint32_t old_serial,
+                            uint32_t* new_serial_ptr,
+                            const struct timespec* relative_timeout)
+    __INTRODUCED_IN_FUTURE;
 
 /* Initialize the system properties area in read only mode.
  * Should be done by all processes that need to read system
@@ -133,6 +149,9 @@
  */
 int __system_properties_init();
 
+/* Deprecated: use __system_property_wait instead. */
+uint32_t __system_property_wait_any(uint32_t old_serial);
+
 __END_DECLS
 
 #endif
diff --git a/headers/sys/cdefs.h b/headers/sys/cdefs.h
index 63e782e..dab252d 100644
--- a/headers/sys/cdefs.h
+++ b/headers/sys/cdefs.h
@@ -181,12 +181,29 @@
 #define __wur __attribute__((__warn_unused_result__))
 
 #ifdef __clang__
-#define __errorattr(msg) __attribute__((unavailable(msg)))
+#  define __errorattr(msg) __attribute__((unavailable(msg)))
+#  define __warnattr(msg) __attribute__((deprecated(msg)))
+#  define __warnattr_real(msg) __attribute__((deprecated(msg)))
+#  define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
 #else
-#define __errorattr(msg) __attribute__((__error__(msg)))
+#  define __errorattr(msg) __attribute__((__error__(msg)))
+#  define __warnattr(msg) __attribute__((__warning__(msg)))
+#  define __warnattr_real __warnattr
+/* enable_if doesn't exist on other compilers; give an error if it's used. */
+
+/* errordecls really don't work as well in clang as they do in GCC. */
+#  define __errordecl(name, msg) extern void name(void) __errorattr(msg)
 #endif
 
-#define __errordecl(name, msg) extern void name(void) __errorattr(msg)
+#if defined(ANDROID_STRICT)
+/*
+ * For things that are sketchy, but not necessarily an error. FIXME: Enable
+ * this.
+ */
+#  define __warnattr_strict(msg) /* __warnattr(msg) */
+#else
+#  define __warnattr_strict(msg)
+#endif
 
 /*
  * Some BSD source needs these macros.
@@ -242,21 +259,60 @@
  * See
  * http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html for details.
  */
+
+#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
+
 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
 #  define __BIONIC_FORTIFY 1
 #  if _FORTIFY_SOURCE == 2
-#    define __bos(s) __builtin_object_size((s), 1)
+#    define __bos_level 1
 #  else
-#    define __bos(s) __builtin_object_size((s), 0)
+#    define __bos_level 0
 #  endif
-#  define __bos0(s) __builtin_object_size((s), 0)
+#  define __bosn(s, n) __builtin_object_size((s), (n))
+#  define __bos(s) __bosn((s), __bos_level)
+#  define __bos0(s) __bosn((s), 0)
 #  if defined(__clang__)
-#    define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline))
+#    define __pass_object_size_n(n) __attribute__((pass_object_size(n)))
+/*
+ * FORTIFY'ed functions all have either enable_if or pass_object_size, which
+ * makes taking their address impossible. Saying (&read)(foo, bar, baz); will
+ * therefore call the unFORTIFYed version of read.
+ */
+#    define __call_bypassing_fortify(fn) (&fn)
+/*
+ * Because clang-FORTIFY uses overloads, we can't mark functions as `extern
+ * inline` without making them available externally.
+ */
+#    define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline
+/* Error functions don't have bodies, so they can just be static. */
+#    define __BIONIC_ERROR_FUNCTION_VISIBILITY static
 #  else
+/*
+ * Where they can, GCC and clang-style FORTIFY share implementations.
+ * So, make these nops in GCC.
+ */
+#    define __pass_object_size_n(n)
+#    define __call_bypassing_fortify(fn) (fn)
+/* __BIONIC_FORTIFY_NONSTATIC_INLINE is pointless in GCC's FORTIFY */
 #    define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
 #  endif
+#  define __pass_object_size __pass_object_size_n(__bos_level)
+#  define __pass_object_size0 __pass_object_size_n(0)
 #endif
-#define __BIONIC_FORTIFY_UNKNOWN_SIZE __BIONIC_CAST(static_cast, size_t, -1)
+
+/* Used to support clangisms with FORTIFY. This isn't in the FORTIFY section
+ * because these change how symbols are emitted. The linker must be kept happy.
+ */
+#ifdef __clang__
+#  define __overloadable __attribute__((overloadable))
+// Don't use __RENAME directly because on gcc, this could result in a number of
+// unnecessary renames.
+#  define __RENAME_CLANG(x) __RENAME(x)
+#else
+#  define __overloadable
+#  define __RENAME_CLANG(x)
+#endif
 
 /* Used to tag non-static symbols that are private and never exposed by the shared library. */
 #define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
@@ -291,17 +347,15 @@
 }
 #endif
 
+#if defined(__clang__)
 /*
- * TODO(danalbert): Remove this once we've moved entirely off prebuilts/ndk.
- *
- * The NDK used to have a __NDK_FPABI__ that was defined to empty for most cases
- * but `__attribute__((pcs("aapcs")))` for the now defunct armeabi-v7a-hard ABI.
- *
- * During the transition from prebuilts/ndk to ndk_headers, we'll have some
- * headers that still use __NDK_FPABI__ while the libc headers have stopped
- * defining it. In the interim, just provide an empty definition to keep the
- * build working.
+ * Used when we need to check for overflow when multiplying x and y. This
+ * should only be used where __size_mul_overflow can not work, because it makes
+ * assumptions that __size_mul_overflow doesn't (x and y are positive, ...),
+ * *and* doesn't make use of compiler intrinsics, so it's probably slower than
+ * __size_mul_overflow.
  */
-#define __NDK_FPABI__
+#define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y))
+#endif
 
 #endif /* !_SYS_CDEFS_H_ */
diff --git a/headers/sys/socket.h b/headers/sys/socket.h
index 8724626..21a30c5 100644
--- a/headers/sys/socket.h
+++ b/headers/sys/socket.h
@@ -329,29 +329,101 @@
 __socketcall int socket(int, int, int);
 __socketcall int socketpair(int, int, int, int*);
 
-ssize_t recv(int, void*, size_t, int);
-ssize_t send(int, const void*, size_t, int);
+ssize_t recv(int, void*, size_t, int) __overloadable __RENAME_CLANG(recv);
+ssize_t send(int, const void*, size_t, int) __overloadable __RENAME_CLANG(send);
 
-__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
-__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*, socklen_t*);
+__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
+        __overloadable __RENAME_CLANG(sendto);
+__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*,
+        socklen_t*) __overloadable __RENAME_CLANG(recvfrom);
 
-__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer");
+
+#if __ANDROID_API__ >= __ANDROID_API_FUTURE__
+extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
+        socklen_t) __INTRODUCED_IN_FUTURE;
+#endif /* __ANDROID_API__ >= __ANDROID_API_FUTURE__ */
+
 
 #if __ANDROID_API__ >= 21
-ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*, socklen_t*)
-  __INTRODUCED_IN(21);
+ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
+        socklen_t*) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
 
 #if defined(__BIONIC_FORTIFY)
 
+#define __recvfrom_bad_size "recvfrom called with size bigger than buffer"
+#define __sendto_bad_size "sendto called with size bigger than buffer"
+#if defined(__clang__)
 #if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
+                 int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+        __overloadable
+        __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                    __bos(buf) < len, "selected when the buffer is too small")
+        __errorattr(__recvfrom_bad_size);
+
 __BIONIC_FORTIFY_INLINE
-ssize_t recvfrom(int fd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len) {
+ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
+                 int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+      __overloadable {
   size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
+  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr,
+              addr_len);
+  }
+
+  return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t sendto(int fd, const void* buf, size_t len, int flags,
+               const struct sockaddr* dest_addr, socklen_t addr_len)
+        __overloadable
+        __enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                    __bos0(buf) < len, "selected when the buffer is too small")
+        __errorattr(__sendto_bad_size);
+
+__BIONIC_FORTIFY_INLINE
+ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len,
+               int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
+      __overloadable {
+  size_t bos = __bos0(buf);
+
+  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr,
+              addr_len);
+  }
+
+  return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t send(int socket, const void* buf, size_t len, int flags)
+        __overloadable
+        __enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                    __bos0(buf) < len, "selected when the buffer is too small")
+        __errorattr("send called with size bigger than buffer");
+#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
+
+#else /* defined(__clang__) */
+ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
+__errordecl(__recvfrom_error, __recvfrom_bad_size);
+
+extern ssize_t __sendto_real(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
+        __RENAME(sendto);
+__errordecl(__sendto_error, __sendto_bad_size);
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
+                 struct sockaddr* src_addr, socklen_t* addr_len) {
+  size_t bos = __bos0(buf);
+
   if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
     return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
   }
@@ -363,17 +435,49 @@
   if (__builtin_constant_p(len) && (len > bos)) {
     __recvfrom_error();
   }
-#endif
 
   return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
 
+#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
 __BIONIC_FORTIFY_INLINE
-ssize_t recv(int socket, void* buf, size_t len, int flags) {
+ssize_t sendto(int fd, const void* buf, size_t len, int flags,
+               const struct sockaddr* dest_addr, socklen_t addr_len) {
+  size_t bos = __bos0(buf);
+
+  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
+  }
+
+  if (__builtin_constant_p(len) && (len <= bos)) {
+    return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
+  }
+
+  if (__builtin_constant_p(len) && (len > bos)) {
+    __sendto_error();
+  }
+
+  return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
+
+#endif /* defined(__clang__) */
+#undef __recvfrom_bad_size
+#undef __sendto_bad_size
+
+__BIONIC_FORTIFY_INLINE
+ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
+             int flags) __overloadable {
   return recvfrom(socket, buf, len, flags, NULL, 0);
 }
 
+__BIONIC_FORTIFY_INLINE
+ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
+        __overloadable {
+  return sendto(socket, buf, len, flags, NULL, 0);
+}
+
 #endif /* __BIONIC_FORTIFY */
 
 #undef __socketcall
diff --git a/headers/sys/stat.h b/headers/sys/stat.h
index 753ad7f..b2dde3c 100644
--- a/headers/sys/stat.h
+++ b/headers/sys/stat.h
@@ -177,33 +177,56 @@
 
 
 int mknod(const char*, mode_t, dev_t);
-mode_t umask(mode_t);
+mode_t umask(mode_t) __overloadable __RENAME_CLANG(umask);
 
 
 #if __ANDROID_API__ >= 18
 mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
 #endif /* __ANDROID_API__ >= 18 */
 
-mode_t __umask_real(mode_t) __RENAME(umask);
-__errordecl(__umask_invalid_mode, "umask called with invalid mode");
 
 #if defined(__BIONIC_FORTIFY)
+#define __umask_invalid_mode_str "umask called with invalid mode"
+
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+/*
+ * Abuse enable_if to make these be seen as overloads of umask, rather than
+ * definitions.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+mode_t umask(mode_t mode) __overloadable
+        __enable_if(1, "")
+        __enable_if(mode & ~0777, __umask_invalid_mode_str)
+        __errorattr(__umask_invalid_mode_str);
+
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode) __enable_if(1, "") __overloadable {
+  return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#else /* defined(__clang__) */
+__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
+extern mode_t __umask_real(mode_t) __RENAME(umask);
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
 __BIONIC_FORTIFY_INLINE
 mode_t umask(mode_t mode) {
-#if !defined(__clang__)
   if (__builtin_constant_p(mode)) {
     if ((mode & 0777) != mode) {
       __umask_invalid_mode();
     }
     return __umask_real(mode);
   }
-#endif
   return __umask_chk(mode);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
 
+#endif /* defined(__clang__) */
+#undef __umask_invalid_mode_str
+
 #endif /* defined(__BIONIC_FORTIFY) */
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
diff --git a/headers/sys/system_properties.h b/headers/sys/system_properties.h
index b3fbc48..f7d1bac 100644
--- a/headers/sys/system_properties.h
+++ b/headers/sys/system_properties.h
@@ -31,82 +31,48 @@
 
 #include <sys/cdefs.h>
 #include <stddef.h>
+#include <stdint.h>
 
 __BEGIN_DECLS
 
 typedef struct prop_info prop_info;
 
-#define PROP_NAME_MAX   32
 #define PROP_VALUE_MAX  92
 
-/* Look up a system property by name, copying its value and a
-** \0 terminator to the provided pointer.  The total bytes
-** copied will be no greater than PROP_VALUE_MAX.  Returns
-** the string length of the value.  A property that is not
-** defined is identical to a property with a length 0 value.
-*/
-int __system_property_get(const char *name, char *value);
-
-/* Set a system property by name.
-**/
+/*
+ * Sets system property `key` to `value`, creating the system property if it doesn't already exist.
+ */
 
 #if __ANDROID_API__ >= 12
 int __system_property_set(const char* key, const char* value) __INTRODUCED_IN(12);
 #endif /* __ANDROID_API__ >= 12 */
 
 
-/* Return a pointer to the system property named name, if it
-** exists, or NULL if there is no such property.  Use 
-** __system_property_read() to obtain the string value from
-** the returned prop_info pointer.
-**
-** It is safe to cache the prop_info pointer to avoid future
-** lookups.  These returned pointers will remain valid for
-** the lifetime of the system.
-*/
-const prop_info *__system_property_find(const char *name);
+/*
+ * Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist.
+ * Use __system_property_read_callback to query the current value.
+ *
+ * Property lookup is expensive, so it can be useful to cache the result of this function.
+ */
+const prop_info* __system_property_find(const char* name);
 
-/* Read the value of a system property.  Returns the length
-** of the value.  Copies the value and \0 terminator into
-** the provided value pointer.  Total length (including
-** terminator) will be no greater that PROP_VALUE_MAX for
-** __system_property_read.
-**
-** If name is nonzero, up to PROP_NAME_MAX bytes will be
-** copied into the provided name pointer.  The name will
-** be \0 terminated.
-*/
-int __system_property_read(const prop_info *pi, char *name, char *value);
+/*
+ * Calls `callback` with a consistent trio of name, value, and serial number for property `pi`.
+ */
 
 #if __ANDROID_API__ >= __ANDROID_API_FUTURE__
 void __system_property_read_callback(const prop_info *pi,
-                                     void (*)(void* cookie, const char *name, const char *value),
-                                     void* cookie) __INTRODUCED_IN_FUTURE;
+    void (*callback)(void* cookie, const char *name, const char *value, uint32_t serial),
+    void* cookie) __INTRODUCED_IN_FUTURE;
 #endif /* __ANDROID_API__ >= __ANDROID_API_FUTURE__ */
 
 
-/* Return a prop_info for the nth system property, or NULL if 
-** there is no nth property.  Use __system_property_read() to
-** read the value of this property.
-**
-** Please do not call this method.  It only exists to provide
-** backwards compatibility to NDK apps.  Its implementation
-** is inefficient and order of results may change from call
-** to call.
-*/ 
-const prop_info *__system_property_find_nth(unsigned n)
-  __REMOVED_IN(26);
-
-/* Pass a prop_info for each system property to the provided
-** callback.  Use __system_property_read() to read the value
-** of this property.
-**
-** This method is for inspecting and debugging the property
-** system.  Please use __system_property_find() instead.
-**
-** Order of results may change from call to call.  This is
-** not a bug.
-*/
+/*
+ * Passes a `prop_info` for each system property to the provided
+ * callback.  Use __system_property_read_callback() to read the value.
+ *
+ * This method is for inspecting and debugging the property system, and not generally useful.
+ */
 
 #if __ANDROID_API__ >= 19
 int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie)
@@ -114,6 +80,15 @@
 #endif /* __ANDROID_API__ >= 19 */
 
 
+/* Deprecated. In Android O and above, there's no limit on property name length. */
+#define PROP_NAME_MAX   32
+/* Deprecated. Use __system_property_read_callback instead. */
+int __system_property_read(const prop_info *pi, char *name, char *value);
+/* Deprecated. Use __system_property_read_callback instead. */
+int __system_property_get(const char *name, char *value);
+/* Deprecated. Use __system_property_foreach instead. Aborts in Android O and above. */
+const prop_info *__system_property_find_nth(unsigned n) __REMOVED_IN(26);
+
 __END_DECLS
 
 #endif
diff --git a/headers/termios.h b/headers/termios.h
index ab27d9d..66ae71c 100644
--- a/headers/termios.h
+++ b/headers/termios.h
@@ -40,8 +40,10 @@
 speed_t cfgetispeed(const struct termios*) __INTRODUCED_IN(21);
 speed_t cfgetospeed(const struct termios*) __INTRODUCED_IN(21);
 void cfmakeraw(struct termios*) __INTRODUCED_IN(21);
+int cfsetspeed(struct termios*, speed_t) __INTRODUCED_IN(21);
 int cfsetispeed(struct termios*, speed_t) __INTRODUCED_IN(21);
 int cfsetospeed(struct termios*, speed_t) __INTRODUCED_IN(21);
+int tcdrain(int) __INTRODUCED_IN(21);
 int tcflow(int, int) __INTRODUCED_IN(21);
 int tcflush(int, int) __INTRODUCED_IN(21);
 int tcgetattr(int, struct termios*) __INTRODUCED_IN(21);
@@ -50,13 +52,6 @@
 int tcsetattr(int, int, const struct termios*) __INTRODUCED_IN(21);
 #endif
 
-
-#if __ANDROID_API__ >= 21
-int cfsetspeed(struct termios*, speed_t) __INTRODUCED_IN(21);
-int tcdrain(int) __INTRODUCED_IN(21);
-#endif /* __ANDROID_API__ >= 21 */
-
-
 __END_DECLS
 
 #include <android/legacy_termios_inlines.h>
diff --git a/headers/unistd.h b/headers/unistd.h
index a1e23fc..15359a1 100644
--- a/headers/unistd.h
+++ b/headers/unistd.h
@@ -159,25 +159,29 @@
 int symlinkat(const char* __oldpath, int __newdirfd, const char* __newpath) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz);
+ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz)
+    __overloadable __RENAME_CLANG(readlink);
 
 #if __ANDROID_API__ >= 21
 ssize_t readlinkat(int __dirfd, const char* __path, char* __buf,
-                   size_t __bufsiz) __INTRODUCED_IN(21);
+                   size_t __bufsiz)
+    __INTRODUCED_IN(21) __overloadable __RENAME_CLANG(readlinkat);
 #endif /* __ANDROID_API__ >= 21 */
 
 int chown(const char* __path, uid_t __owner, gid_t __group);
 int fchown(int __fd, uid_t __owner, gid_t __group);
 int fchownat(int __dirfd, const char* __path, uid_t __owner, gid_t __group, int __flags);
 int lchown(const char* __path, uid_t __owner, gid_t __group);
-char* getcwd(char* __buf, size_t __size);
+char* getcwd(char* __buf, size_t __size) __overloadable __RENAME_CLANG(getcwd);
 
 void sync(void);
 
 int close(int __fd);
 
-ssize_t read(int __fd, void* __buf, size_t __count);
-ssize_t write(int __fd, const void* __buf, size_t __count);
+ssize_t read(int __fd, void* __buf, size_t __count) __overloadable
+    __RENAME_CLANG(read);
+ssize_t write(int __fd, const void* __buf, size_t __count) __overloadable
+    __RENAME_CLANG(write);
 
 int dup(int __oldfd);
 int dup2(int __oldfd, int __newfd);
@@ -199,15 +203,17 @@
 
 #if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__
 int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21);
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __RENAME(pread64)
-  __INTRODUCED_IN(12);
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
+  __overloadable __RENAME(pread64) __INTRODUCED_IN(12);
 ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset)
-  __RENAME(pwrite64) __INTRODUCED_IN(12);
+  __overloadable __RENAME(pwrite64) __INTRODUCED_IN(12);
 int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64) __INTRODUCED_IN(12);
 #else
 int truncate(const char* __path, off_t __length);
-ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset);
-ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset);
+ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset)
+    __overloadable __RENAME_CLANG(pread);
+ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset)
+    __overloadable __RENAME_CLANG(pwrite);
 int ftruncate(int __fd, off_t __length);
 #endif
 
@@ -218,9 +224,10 @@
 
 
 #if __ANDROID_API__ >= 12
-ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(12);
+ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset)
+    __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pread64);
 ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset)
-  __INTRODUCED_IN(12);
+    __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pwrite64);
 int ftruncate64(int __fd, off64_t __length) __INTRODUCED_IN(12);
 #endif /* __ANDROID_API__ >= 12 */
 
@@ -280,16 +287,12 @@
 char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
 #endif /* __ANDROID_API__ >= 24 */
 
-__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
-char* __getcwd_real(char*, size_t) __RENAME(getcwd);
 
 
 #if __ANDROID_API__ >= 23
 ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
 #endif /* __ANDROID_API__ >= 23 */
 
-__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
-__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
 ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
 
 
@@ -297,8 +300,6 @@
 ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
 #endif /* __ANDROID_API__ >= 23 */
 
-__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
-__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
 
 #if __ANDROID_API__ >= 12
 ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
@@ -310,8 +311,6 @@
 ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
 #endif /* __ANDROID_API__ >= 24 */
 
-__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
-__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
 ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
 
 
@@ -319,11 +318,10 @@
 ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
 #endif /* __ANDROID_API__ >= 24 */
 
-__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
-__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
 
 #if __ANDROID_API__ >= 12
-ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64) __INTRODUCED_IN(12);
+ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
+  __INTRODUCED_IN(12);
 #endif /* __ANDROID_API__ >= 12 */
 
 
@@ -332,40 +330,17 @@
 ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
 #endif /* __ANDROID_API__ >= 21 */
 
-__errordecl(__read_dest_size_error, "read called with size bigger than destination");
-__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
-ssize_t __read_real(int, void*, size_t) __RENAME(read);
-
 
 #if __ANDROID_API__ >= 24
 ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
 #endif /* __ANDROID_API__ >= 24 */
 
-__errordecl(__write_dest_size_error, "write called with size bigger than destination");
-__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
-ssize_t __write_real(int, const void*, size_t) __RENAME(write);
-
 
 #if __ANDROID_API__ >= 23
 ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-#endif /* __ANDROID_API__ >= 23 */
-
-__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
-__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
-ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
-
-
-#if __ANDROID_API__ >= 23
 ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
 #endif /* __ANDROID_API__ >= 23 */
 
-__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
-__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
-
-#if __ANDROID_API__ >= 21
-ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat) __INTRODUCED_IN(21);
-#endif /* __ANDROID_API__ >= 21 */
-
 
 
 #if __ANDROID_API__ >= __ANDROID_API_FUTURE__
@@ -376,22 +351,269 @@
 
 #if defined(__BIONIC_FORTIFY)
 
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-char* getcwd(char* buf, size_t size) {
-    size_t bos = __bos(buf);
+#if defined(__USE_FILE_OFFSET64)
+#define __PREAD_PREFIX(x) __pread64_ ## x
+#define __PWRITE_PREFIX(x) __pwrite64_ ## x
+#else
+#define __PREAD_PREFIX(x) __pread_ ## x
+#define __PWRITE_PREFIX(x) __pwrite_ ## x
+#endif
 
 #if defined(__clang__)
+#define __error_if_overflows_ssizet(what) \
+    __enable_if(what > SSIZE_MAX, #what " must be <= SSIZE_MAX") \
+    __errorattr(#what " must be <= SSIZE_MAX")
+
+#define __enable_if_no_overflow_ssizet(what) \
+    __enable_if((what) <= SSIZE_MAX, "enabled if " #what " <= SSIZE_MAX")
+
+#define __error_if_overflows_objectsize(what, objsize) \
+    __enable_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
+                    (what) > (objsize), \
+                "'" #what "' bytes overflows the given object") \
+    __errorattr("'" #what "' bytes overflows the given object")
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* getcwd(char* buf, size_t size) __overloadable
+        __error_if_overflows_objectsize(size, __bos(buf));
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* const __pass_object_size buf, size_t size) __overloadable {
+    size_t bos = __bos(buf);
+
     /*
-     * Work around LLVM's incorrect __builtin_object_size implementation here
-     * to avoid needing the workaround in the __getcwd_chk ABI forever.
-     *
-     * https://llvm.org/bugs/show_bug.cgi?id=23277
+     * Clang responds bos==0 if buf==NULL
+     * (https://llvm.org/bugs/show_bug.cgi?id=23277). Given that NULL is a valid
+     * value, we need to handle that.
      */
-    if (buf == NULL) {
-        bos = __BIONIC_FORTIFY_UNKNOWN_SIZE;
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE || buf == NULL) {
+        return __call_bypassing_fortify(getcwd)(buf, size);
     }
-#else
+
+    return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
+        __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
+        __enable_if_no_overflow_ssizet(count)
+        __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count,
+              off_t offset) __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __PREAD_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
+        __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
+        __enable_if_no_overflow_ssizet(count)
+        __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count,
+                off64_t offset) __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __pread64_real(fd, buf, count, offset);
+    }
+
+    return __pread64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
+        __overloadable
+        __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
+        __overloadable
+        __enable_if_no_overflow_ssizet(count)
+        __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count,
+               off_t offset) __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
+        __overloadable
+        __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
+        __overloadable
+        __enable_if_no_overflow_ssizet(count)
+        __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf,
+                 size_t count, off64_t offset) __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __pwrite64_real(fd, buf, count, offset);
+    }
+
+    return __pwrite64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t read(int fd, void* buf, size_t count) __overloadable
+        __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t read(int fd, void* buf, size_t count) __overloadable
+        __enable_if_no_overflow_ssizet(count)
+        __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
+        __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(read)(fd, buf, count);
+    }
+
+    return __read_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t write(int fd, const void* buf, size_t count) __overloadable
+        __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t write(int fd, const void* buf, size_t count) __overloadable
+        __enable_if_no_overflow_ssizet(count)
+        __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
+        __overloadable {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(write)(fd, buf, count);
+    }
+
+    return __write_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
+        __error_if_overflows_ssizet(size);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
+        __enable_if_no_overflow_ssizet(size)
+        __error_if_overflows_objectsize(size, __bos(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* const __pass_object_size buf,
+                 size_t size) __overloadable {
+    size_t bos = __bos(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(readlink)(path, buf, size);
+    }
+
+    return __readlink_chk(path, buf, size, bos);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
+        __overloadable
+        __error_if_overflows_ssizet(size);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
+        __overloadable
+        __enable_if_no_overflow_ssizet(size)
+        __error_if_overflows_objectsize(size, __bos(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path,
+                   char* const __pass_object_size buf, size_t size)
+        __overloadable {
+    size_t bos = __bos(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
+    }
+
+    return __readlinkat_chk(dirfd, path, buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#undef __enable_if_no_overflow_ssizet
+#undef __error_if_overflows_objectsize
+#undef __error_if_overflows_ssizet
+#else /* defined(__clang__) */
+
+char* __getcwd_real(char*, size_t) __RENAME(getcwd);
+ssize_t __read_real(int, void*, size_t) __RENAME(read);
+ssize_t __write_real(int, const void*, size_t) __RENAME(write);
+ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
+ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
+
+__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
+__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
+__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
+__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
+__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
+__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
+__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
+__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
+__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
+__errordecl(__read_dest_size_error, "read called with size bigger than destination");
+__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
+__errordecl(__write_dest_size_error, "write called with size bigger than destination");
+__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
+__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
+__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
+__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
+__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* buf, size_t size) __overloadable {
+    size_t bos = __bos(buf);
+
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __getcwd_real(buf, size);
     }
@@ -403,24 +625,16 @@
     if (__builtin_constant_p(size) && (size <= bos)) {
         return __getcwd_real(buf, size);
     }
-#endif
 
     return __getcwd_chk(buf, size, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
 
-#if defined(__USE_FILE_OFFSET64)
-#define __PREAD_PREFIX(x) __pread64_ ## x
-#else
-#define __PREAD_PREFIX(x) __pread_ ## x
-#endif
-
 #if __ANDROID_API__ >= __ANDROID_API_M__
 __BIONIC_FORTIFY_INLINE
 ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
         __PREAD_PREFIX(count_toobig_error)();
     }
@@ -436,7 +650,6 @@
     if (__builtin_constant_p(count) && (count <= bos)) {
         return __PREAD_PREFIX(real)(fd, buf, count, offset);
     }
-#endif
 
     return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
 }
@@ -445,7 +658,6 @@
 ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
         __pread64_count_toobig_error();
     }
@@ -461,24 +673,16 @@
     if (__builtin_constant_p(count) && (count <= bos)) {
         return __pread64_real(fd, buf, count, offset);
     }
-#endif
 
     return __pread64_chk(fd, buf, count, offset, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
 
-#if defined(__USE_FILE_OFFSET64)
-#define __PWRITE_PREFIX(x) __pwrite64_ ## x
-#else
-#define __PWRITE_PREFIX(x) __pwrite_ ## x
-#endif
-
 #if __ANDROID_API__ >= __ANDROID_API_N__
 __BIONIC_FORTIFY_INLINE
 ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
         __PWRITE_PREFIX(count_toobig_error)();
     }
@@ -494,7 +698,6 @@
     if (__builtin_constant_p(count) && (count <= bos)) {
         return __PWRITE_PREFIX(real)(fd, buf, count, offset);
     }
-#endif
 
     return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
 }
@@ -503,7 +706,6 @@
 ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
         __pwrite64_count_toobig_error();
     }
@@ -519,7 +721,6 @@
     if (__builtin_constant_p(count) && (count <= bos)) {
         return __pwrite64_real(fd, buf, count, offset);
     }
-#endif
 
     return __pwrite64_chk(fd, buf, count, offset, bos);
 }
@@ -530,7 +731,6 @@
 ssize_t read(int fd, void* buf, size_t count) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
         __read_count_toobig_error();
     }
@@ -546,7 +746,6 @@
     if (__builtin_constant_p(count) && (count <= bos)) {
         return __read_real(fd, buf, count);
     }
-#endif
 
     return __read_chk(fd, buf, count, bos);
 }
@@ -557,13 +756,6 @@
 ssize_t write(int fd, const void* buf, size_t count) {
     size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
-#if 0 /* work around a false positive due to a missed optimization */
-    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
-        __write_count_toobig_error();
-    }
-#endif
-
     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
         return __write_real(fd, buf, count);
     }
@@ -575,7 +767,6 @@
     if (__builtin_constant_p(count) && (count <= bos)) {
         return __write_real(fd, buf, count);
     }
-#endif
 
     return __write_chk(fd, buf, count, bos);
 }
@@ -586,7 +777,6 @@
 ssize_t readlink(const char* path, char* buf, size_t size) {
     size_t bos = __bos(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
         __readlink_size_toobig_error();
     }
@@ -602,7 +792,6 @@
     if (__builtin_constant_p(size) && (size <= bos)) {
         return __readlink_real(path, buf, size);
     }
-#endif
 
     return __readlink_chk(path, buf, size, bos);
 }
@@ -611,7 +800,6 @@
 ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
     size_t bos = __bos(buf);
 
-#if !defined(__clang__)
     if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
         __readlinkat_size_toobig_error();
     }
@@ -627,12 +815,13 @@
     if (__builtin_constant_p(size) && (size <= bos)) {
         return __readlinkat_real(dirfd, path, buf, size);
     }
-#endif
 
     return __readlinkat_chk(dirfd, path, buf, size, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
+#endif /* defined(__clang__) */
+#undef __PREAD_PREFIX
+#undef __PWRITE_PREFIX
 #endif /* defined(__BIONIC_FORTIFY) */
 
 __END_DECLS