Merge "Revert "Move back to the previous version of ion.h.""
diff --git a/libc/Android.bp b/libc/Android.bp
index 701a1b0..b0e0d8c 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -787,7 +787,7 @@
 
     // Disable FORTIFY for the compilation of these, so we don't end up having
     // FORTIFY silently call itself.
-    cflags: ["-U_FORTIFY_SOURCE"],
+    cflags: ["-U_FORTIFY_SOURCE", "-D__BIONIC_DECLARE_FORTIFY_HELPERS"],
 
     arch: {
         arm: {
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST.TXT
index 0b9dad3..9e417c4 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST.TXT
@@ -63,7 +63,7 @@
 
 # b/34651972
 int	access:access(const char *pathname, int mode)	arm,x86,mips
-int	stat64:stat64(const char *restrict path, struct stat64 *restrict buf)	arm,x86,mips
+int	stat64:stat64(const char*, struct stat64*)	arm,x86,mips
 
 # b/34813887
 int	open:open(const char *path, int oflag, ... ) arm,x86,mips
@@ -88,7 +88,7 @@
 int	unlink:unlink(const char *pathname)	arm,x86,mips
 
 # b/35059702
-int	lstat64:lstat64(const char *restrict path, struct stat64 *restrict buf)	arm,x86,mips
+int	lstat64:lstat64(const char*, struct stat64*)	arm,x86,mips
 
 # b/35217603
 int	fcntl:fcntl(int fd, int cmd, ... /* arg */ )	arm,x86,mips
@@ -126,4 +126,4 @@
 int compat_select:_newselect(int n, unsigned long* inp, unsigned long* outp, unsigned long* exp, struct timeval* timeout) arm,x86,mips
 
 # b/62090571
-int mkdir(const char *pathname, mode_t mode)	arm,x86,mips
\ No newline at end of file
+int mkdir(const char *pathname, mode_t mode)	arm,x86,mips
diff --git a/libc/async_safe/include/async_safe/log.h b/libc/async_safe/include/async_safe/log.h
index 6fdb84f..2f54742 100644
--- a/libc/async_safe/include/async_safe/log.h
+++ b/libc/async_safe/include/async_safe/log.h
@@ -78,14 +78,8 @@
 
 // These functions do return, so callers that want to abort, must do so themselves,
 // or use the macro above.
-void async_safe_fatal_no_abort(const char* _Nonnull fmt, ...) __printflike(1, 2);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-void async_safe_fatal_va_list(
-    const char* _Nullable prefix, const char* _Nonnull fmt, va_list);
-#else // defined(__mips__) || defined(__i386__)
-void async_safe_fatal_va_list(
-    const char* _Nullable prefix, const char* _Nonnull fmt, va_list _Nonnull);
-#endif
+void async_safe_fatal_no_abort(const char* fmt, ...) __printflike(1, 2);
+void async_safe_fatal_va_list(const char* prefix, const char* fmt, va_list args);
 
 //
 // Formatting routines for the C library's internal debugging.
@@ -93,26 +87,13 @@
 // These are async signal safe, so they can be called from signal handlers.
 //
 
-int async_safe_format_buffer(char* _Nonnull buf, size_t size, const char* _Nonnull fmt, ...) __printflike(3, 4);
+int async_safe_format_buffer(char* buf, size_t size, const char* fmt, ...) __printflike(3, 4);
+int async_safe_format_buffer_va_list(char* buffer, size_t buffer_size, const char* format, va_list args);
 
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-int async_safe_format_buffer_va_list(
-    char* _Nonnull buffer, size_t buffer_size, const char* _Nonnull format, va_list args);
-#else // defined(__mips__) || defined(__i386__)
-int async_safe_format_buffer_va_list(
-    char* _Nonnull buffer, size_t buffer_size, const char* _Nonnull format, va_list _Nonnull args);
-#endif
-
-int async_safe_format_fd(int fd, const char* _Nonnull format , ...) __printflike(2, 3);
-int async_safe_format_log(int pri, const char* _Nonnull tag, const char* _Nonnull fmt, ...) __printflike(3, 4);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-int async_safe_format_log_va_list(
-    int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list ap);
-#else // defined(__mips__) || defined(__i386__)
-int async_safe_format_log_va_list(
-    int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list _Nonnull ap);
-#endif
-int async_safe_write_log(int pri, const char* _Nonnull tag, const char* _Nonnull msg);
+int async_safe_format_fd(int fd, const char* format , ...) __printflike(2, 3);
+int async_safe_format_log(int pri, const char* tag, const char* fmt, ...) __printflike(3, 4);
+int async_safe_format_log_va_list( int pri, const char* tag, const char* fmt, va_list ap);
+int async_safe_write_log(int pri, const char* tag, const char* msg);
 
 #define CHECK(predicate) \
   do { \
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 4a7ff13..cbcc976 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -78,8 +78,6 @@
 //   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
 //
 
-struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
-
 int __FD_ISSET_chk(int fd, fd_set* set, size_t set_size) {
   __check_fd_set("FD_ISSET", fd, set_size);
   return FD_ISSET(fd, set);
@@ -103,8 +101,7 @@
   return fgets(dst, supplied_size, stream);
 }
 
-size_t __fread_chk(void* __restrict buf, size_t size, size_t count,
-                   FILE* __restrict stream, size_t buf_size) {
+size_t __fread_chk(void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
   size_t total;
   if (__predict_false(__size_mul_overflow(size, count, &total))) {
     // overflow: trigger the error path in fread
@@ -114,8 +111,7 @@
   return fread(buf, size, count, stream);
 }
 
-size_t __fwrite_chk(const void* __restrict buf, size_t size, size_t count,
-                    FILE* __restrict stream, size_t buf_size) {
+size_t __fwrite_chk(const void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
   size_t total;
   if (__predict_false(__size_mul_overflow(size, count, &total))) {
     // overflow: trigger the error path in fwrite
@@ -239,8 +235,7 @@
 }
 
 // Runtime implementation of __builtin____stpncpy_chk (used directly by compiler, not in headers).
-extern "C" char* __stpncpy_chk(char* __restrict dst, const char* __restrict src,
-                               size_t len, size_t dst_len) {
+extern "C" char* __stpncpy_chk(char* dst, const char* src, size_t len, size_t dst_len) {
   __check_buffer_access("stpncpy", "write into", len, dst_len);
   return stpncpy(dst, src, len);
 }
@@ -249,8 +244,7 @@
 // sure we don't read beyond the end of "src". The code for this is
 // based on the original version of stpncpy, but modified to check
 // how much we read from "src" at the end of the copy operation.
-char* __stpncpy_chk2(char* __restrict dst, const char* __restrict src,
-                     size_t n, size_t dst_len, size_t src_len) {
+char* __stpncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_t src_len) {
   __check_buffer_access("stpncpy", "write into", n, dst_len);
   if (n != 0) {
     char* d = dst;
@@ -325,8 +319,7 @@
 }
 
 // Runtime implementation of __builtin____strncat_chk (used directly by compiler, not in headers).
-extern "C" char* __strncat_chk(char* __restrict dst, const char* __restrict src,
-                               size_t len, size_t dst_buf_size) {
+extern "C" char* __strncat_chk(char* dst, const char* src, size_t len, size_t dst_buf_size) {
   if (len == 0) {
     return dst;
   }
@@ -353,8 +346,7 @@
 }
 
 // Runtime implementation of __builtin____strncpy_chk (used directly by compiler, not in headers).
-extern "C" char* __strncpy_chk(char* __restrict dst, const char* __restrict src,
-                               size_t len, size_t dst_len) {
+extern "C" char* __strncpy_chk(char* dst, const char* src, size_t len, size_t dst_len) {
   __check_buffer_access("strncpy", "write into", len, dst_len);
   return strncpy(dst, src, len);
 }
@@ -363,8 +355,7 @@
 // sure we don't read beyond the end of "src". The code for this is
 // based on the original version of strncpy, but modified to check
 // how much we read from "src" at the end of the copy operation.
-char* __strncpy_chk2(char* __restrict dst, const char* __restrict src,
-                                size_t n, size_t dst_len, size_t src_len) {
+char* __strncpy_chk2(char* dst, const char* src, size_t n, size_t dst_len, size_t src_len) {
   __check_buffer_access("strncpy", "write into", n, dst_len);
   if (n != 0) {
     char* d = dst;
@@ -459,8 +450,7 @@
 
 #if !defined(NO___STRCAT_CHK)
 // Runtime implementation of __builtin____strcat_chk (used directly by compiler, not in headers).
-extern "C" char* __strcat_chk(char* __restrict dst, const char* __restrict src,
-                              size_t dst_buf_size) {
+extern "C" char* __strcat_chk(char* dst, const char* src, size_t dst_buf_size) {
   char* save = dst;
   size_t dst_len = __strlen_chk(dst, dst_buf_size);
 
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
new file mode 100644
index 0000000..3e0a590
--- /dev/null
+++ b/libc/include/bits/fortify/fcntl.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _FCNTL_H
+#error "Never include this file directly; instead, include <fcntl.h>"
+#endif
+
+int __open_2(const char*, int) __INTRODUCED_IN(17);
+int __openat_2(int, const char*, int) __INTRODUCED_IN(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);
+
+#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 __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);
+
+/*
+ * 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
+        __clang_error_if(flags & O_CREAT, "'open' " __open_too_few_args_error) {
+    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, 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
+        __clang_error_if(flags & O_CREAT, "'openat' " __open_too_few_args_error) {
+    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)) {
+        if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
+            __creat_missing_mode();  /* Compile time error. */
+        }
+    }
+
+    if (__builtin_va_arg_pack_len() > 1) {
+        __creat_too_many_args();  /* Compile time error. */
+    }
+
+    if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
+        return __open_2(pathname, flags);
+    }
+
+    return __open_real(pathname, flags, __builtin_va_arg_pack());
+}
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* pathname, int flags, ...) {
+    if (__builtin_constant_p(flags)) {
+        if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
+            __creat_missing_mode();  /* Compile time error. */
+        }
+    }
+
+    if (__builtin_va_arg_pack_len() > 1) {
+        __creat_too_many_args();  /* Compile time error. */
+    }
+
+    if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
+        return __openat_2(dirfd, pathname, flags);
+    }
+
+    return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#endif /* defined(__clang__) */
+
+#undef __open_too_many_args_error
+#undef __open_too_few_args_error
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
new file mode 100644
index 0000000..8363e35
--- /dev/null
+++ b/libc/include/bits/fortify/poll.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _POLL_H_
+#error "Never include this file directly; instead, include <poll.h>"
+#endif
+
+int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
+int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
+  __INTRODUCED_IN(23);
+
+#if defined(__BIONIC_FORTIFY)
+#if __ANDROID_API__ >= __ANDROID_API_M__
+#if defined(__clang__)
+__BIONIC_FORTIFY_INLINE
+int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeout)
+    __overloadable
+    __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                       __bos(fds) < sizeof(*fds) * fd_count,
+                     "in call to 'poll', fd_count is larger than the given buffer") {
+  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_FORTIFY_INLINE
+int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask)
+    __overloadable
+    __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                       __bos(fds) < sizeof(*fds) * fd_count,
+                     "in call to 'ppoll', fd_count is larger than the given buffer") {
+  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);
+__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
+
+__BIONIC_FORTIFY_INLINE
+int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
+  if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (!__builtin_constant_p(fd_count)) {
+      return __poll_chk(fds, fd_count, timeout, __bos(fds));
+    } else if (__bos(fds) / sizeof(*fds) < fd_count) {
+      __poll_too_small_error();
+    }
+  }
+  return __poll_real(fds, fd_count, timeout);
+}
+
+__BIONIC_FORTIFY_INLINE
+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));
+    } else if (__bos(fds) / sizeof(*fds) < fd_count) {
+      __ppoll_too_small_error();
+    }
+  }
+  return __ppoll_real(fds, fd_count, timeout, mask);
+}
+
+#endif /* defined(__clang__) */
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
new file mode 100644
index 0000000..3e610d6
--- /dev/null
+++ b/libc/include/bits/fortify/socket.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _SYS_SOCKET_H_
+#error "Never include this file directly; instead, include <sys/socket.h>"
+#endif
+
+extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
+        socklen_t) __INTRODUCED_IN(26);
+ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
+        socklen_t*) __INTRODUCED_IN(21);
+
+#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_FORTIFY_INLINE
+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
+    __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos(buf) < len,
+                     __recvfrom_bad_size) {
+  size_t bos = __bos0(buf);
+
+  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_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
+    __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+                     __sendto_bad_size) {
+  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);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
+
+__BIONIC_FORTIFY_INLINE
+ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len, int flags)
+    __overloadable
+    __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+                     "'recv' called with size bigger than buffer") {
+  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
+    __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+                     "'send' called with size bigger than buffer") {
+  return sendto(socket, buf, len, flags, NULL, 0);
+}
+
+#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);
+  }
+
+  if (__builtin_constant_p(len) && (len <= bos)) {
+    return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
+  }
+
+  if (__builtin_constant_p(len) && (len > bos)) {
+    __recvfrom_error();
+  }
+
+  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 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__ */
+
+__BIONIC_FORTIFY_INLINE
+ssize_t recv(int socket, void* buf, size_t len, int flags) {
+  return recvfrom(socket, buf, len, flags, NULL, 0);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t send(int socket, const void* buf, size_t len, int flags) {
+  return sendto(socket, buf, len, flags, NULL, 0);
+}
+#endif /* defined(__clang__) */
+
+#undef __recvfrom_bad_size
+#undef __sendto_bad_size
+#endif /* __BIONIC_FORTIFY */
diff --git a/libc/include/bits/fortify/stat.h b/libc/include/bits/fortify/stat.h
new file mode 100644
index 0000000..c168c38
--- /dev/null
+++ b/libc/include/bits/fortify/stat.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _SYS_STAT_H_
+#error "Never include this file directly; instead, include <sys/stat.h>"
+#endif
+
+mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
+
+#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 this an overload of umask. */
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode)
+    __overloadable
+    __enable_if(1, "")
+    __clang_error_if(mode & ~0777, __umask_invalid_mode_str) {
+  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 (__builtin_constant_p(mode)) {
+    if ((mode & 0777) != mode) {
+      __umask_invalid_mode();
+    }
+    return __umask_real(mode);
+  }
+  return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#endif /* defined(__clang__) */
+#undef __umask_invalid_mode_str
+
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
new file mode 100644
index 0000000..cfc78d7
--- /dev/null
+++ b/libc/include/bits/fortify/stdio.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _STDIO_H_
+#error "Never include this file directly; instead, include <stdio.h>"
+#endif
+
+char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
+size_t __fread_chk(void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(24);
+size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(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* 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* 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* dest, size_t size, const char* 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* const __pass_object_size dest, size_t size, const char* 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* dest, const char* 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* const __pass_object_size dest, const char* 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* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+        __overloadable
+        __clang_error_if(__unsafe_check_mul_overflow(size, count),
+                         "in call to 'fread', size * count overflows")
+        __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && size * count > __bos(buf),
+                         "in call to 'fread', size * count is too large for the given buffer") {
+    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);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+        __overloadable
+        __clang_error_if(__unsafe_check_mul_overflow(size, count),
+                         "in call to 'fwrite', size * count overflows")
+        __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && size * count > __bos(buf),
+                         "in call to 'fwrite', size * count is too large for the given buffer") {
+    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_FORTIFY_INLINE
+char* fgets(char* const __pass_object_size dest, int size, FILE* stream)
+        __overloadable
+        __clang_error_if(size < 0, "in call to 'fgets', size should not be negative")
+        __clang_error_if(size > __bos(dest),
+                         "in call to 'fgets', size is larger than the destination buffer") {
+    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*, size_t, size_t, FILE*) __RENAME(fread);
+__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
+__errordecl(__fread_overflow, "fread called with overflowing size * count");
+
+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*, size_t, size_t, FILE*) __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 __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE __printflike(3, 4)
+int snprintf(char* dest, size_t size, const char* format, ...) {
+    return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack());
+}
+
+__BIONIC_FORTIFY_INLINE __printflike(2, 3)
+int sprintf(char* dest, const char* format, ...) {
+    return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack());
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+size_t fread(void* buf, size_t size, size_t count, FILE* stream) {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __fread_real(buf, size, count, stream);
+    }
+
+    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+        size_t total;
+        if (__size_mul_overflow(size, count, &total)) {
+            __fread_overflow();
+        }
+
+        if (total > bos) {
+            __fread_too_big_error();
+        }
+
+        return __fread_real(buf, size, count, stream);
+    }
+
+    return __fread_chk(buf, size, count, stream, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void* buf, size_t size, size_t count, FILE* stream) {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __fwrite_real(buf, size, count, stream);
+    }
+
+    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+        size_t total;
+        if (__size_mul_overflow(size, count, &total)) {
+            __fwrite_overflow();
+        }
+
+        if (total > bos) {
+            __fwrite_too_big_error();
+        }
+
+        return __fwrite_real(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_FORTIFY_INLINE
+char *fgets(char* dest, int size, FILE* stream) {
+    size_t bos = __bos(dest);
+
+    // Compiler can prove, at compile time, that the passed in size
+    // is always negative. Force a compiler error.
+    if (__builtin_constant_p(size) && (size < 0)) {
+        __fgets_too_small_error();
+    }
+
+    // Compiler doesn't know destination size. Don't call __fgets_chk
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __fgets_real(dest, size, stream);
+    }
+
+    // Compiler can prove, at compile time, that the passed in size
+    // is always <= the actual object size. Don't call __fgets_chk
+    if (__builtin_constant_p(size) && (size <= (int) bos)) {
+        return __fgets_real(dest, size, stream);
+    }
+
+    // Compiler can prove, at compile time, that the passed in size
+    // is always > the actual object size. Force a compiler error.
+    if (__builtin_constant_p(size) && (size > (int) bos)) {
+        __fgets_too_big_error();
+    }
+
+    return __fgets_chk(dest, size, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#endif /* defined(__clang__) */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
new file mode 100644
index 0000000..cf4b7ea
--- /dev/null
+++ b/libc/include/bits/fortify/stdlib.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _STDLIB_H
+#error "Never include this file directly; instead, include <stdlib.h>"
+#endif
+
+#if defined(__BIONIC_FORTIFY)
+#define __realpath_buf_too_small_str \
+    "'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes"
+
+/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
+#define __PATH_MAX 4096
+
+#if defined(__clang__)
+char* realpath(const char* path, char* resolved)
+        __clang_error_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                         __bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str);
+/* No need for a definition; the only issues we can catch are at compile-time. */
+
+#else /* defined(__clang__) */
+
+char* __realpath_real(const char*, char*) __RENAME(realpath);
+__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
+
+__BIONIC_FORTIFY_INLINE
+char* realpath(const char* path, char* resolved) {
+    size_t bos = __bos(resolved);
+
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
+        __realpath_size_error();
+    }
+
+    return __realpath_real(path, resolved);
+}
+
+#endif /* defined(__clang__) */
+
+#undef __PATH_MAX
+#undef __realpath_buf_too_small_str
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
new file mode 100644
index 0000000..667e21d
--- /dev/null
+++ b/libc/include/bits/fortify/string.h
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef _STRING_H
+#error "Never include this file directly; instead, include <string.h>"
+#endif
+
+void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
+void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
+char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
+char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
+size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
+size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
+
+#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* const dst __pass_object_size0, const void* src, size_t copy_amount)
+        __overloadable
+        __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount,
+                         "'memcpy' called with size bigger than buffer") {
+    return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
+        __overloadable
+        __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len,
+                         "'memmove' called with size bigger than buffer") {
+    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* const dst __pass_object_size, const char* src)
+        __overloadable
+        __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                             __bos(dst) <= __builtin_strlen(src),
+                         "'stpcpy' called with string bigger than buffer") {
+    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* const dst __pass_object_size, const char* src)
+        __overloadable
+        __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                             __bos(dst) <= __builtin_strlen(src),
+                         "'strcpy' called with string bigger than buffer") {
+    return __builtin___strcpy_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strcat(char* const dst __pass_object_size, const char* src) __overloadable {
+    return __builtin___strcat_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
+    return __builtin___strncat_chk(dst, src, n, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memset(void* const s __pass_object_size0, int c, size_t n)
+        __overloadable
+        __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n,
+                         "'memset' called with size bigger than buffer")
+        /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
+        __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
+    return __builtin___memset_chk(s, c, n, __bos0(s));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
+    size_t bos = __bos(s);
+
+    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 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* const dst __pass_object_size, const char* const 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* const dst __pass_object_size, const char* const 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 dst __pass_object_size, const char* 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 dst __pass_object_size, const char* 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 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 s __pass_object_size0) __overloadable {
+    size_t bos = __bos0(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        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 s __pass_object_size, int c) __overloadable {
+    size_t bos = __bos(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strchr(s, c);
+    }
+
+    return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* const 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__ */
+
+#else // defined(__clang__)
+extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+extern size_t __strlcpy_real(char*, const char*, size_t)
+    __RENAME(strlcpy);
+extern size_t __strlcat_real(char*, const char*, 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* 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);
+    }
+
+    if (__builtin_constant_p(n) && (n > bos)) {
+        __memchr_buf_size_error();
+    }
+
+    if (__builtin_constant_p(n) && (n <= bos)) {
+        return __builtin_memchr(s, c, n);
+    }
+
+    return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* s, int c, size_t n) {
+    size_t bos = __bos(s);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __memrchr_real(s, c, n);
+    }
+
+    if (__builtin_constant_p(n) && (n > bos)) {
+        __memrchr_buf_size_error();
+    }
+
+    if (__builtin_constant_p(n) && (n <= bos)) {
+        return __memrchr_real(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* dst, const char* src, size_t n) {
+    size_t bos_dst = __bos(dst);
+    size_t bos_src = __bos(src);
+
+    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+    }
+
+    if (__builtin_constant_p(n) && (n <= bos_src)) {
+        return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+    }
+
+    size_t slen = __builtin_strlen(src);
+    if (__builtin_constant_p(slen)) {
+        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* dst, const char* src, size_t n) {
+    size_t bos_dst = __bos(dst);
+    size_t bos_src = __bos(src);
+
+    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strncpy_real(dst, src, n);
+    }
+
+    if (__builtin_constant_p(n) && (n <= bos_src)) {
+        return __builtin___strncpy_chk(dst, src, n, bos_dst);
+    }
+
+    size_t slen = __builtin_strlen(src);
+    if (__builtin_constant_p(slen)) {
+        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* dst __pass_object_size, const char* src, size_t size) {
+    size_t bos = __bos(dst);
+
+    // Compiler doesn't know destination size. Don't call __strlcpy_chk
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strlcpy_real(dst, src, size);
+    }
+
+    // Compiler can prove, at compile time, that the passed in size
+    // is always <= the actual object size. Don't call __strlcpy_chk
+    if (__builtin_constant_p(size) && (size <= bos)) {
+        return __strlcpy_real(dst, src, size);
+    }
+
+    return __strlcpy_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlcat(char* dst, const char* src, size_t size) {
+    size_t bos = __bos(dst);
+
+    // Compiler doesn't know destination size. Don't call __strlcat_chk
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strlcat_real(dst, src, size);
+    }
+
+    // Compiler can prove, at compile time, that the passed in size
+    // is always <= the actual object size. Don't call __strlcat_chk
+    if (__builtin_constant_p(size) && (size <= bos)) {
+        return __strlcat_real(dst, src, size);
+    }
+
+    return __strlcat_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* s) __overloadable {
+    size_t bos = __bos(s);
+
+    // Compiler doesn't know destination size. Don't call __strlen_chk
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strlen(s);
+    }
+
+    size_t slen = __builtin_strlen(s);
+    if (__builtin_constant_p(slen)) {
+        return slen;
+    }
+
+    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* s, int c) {
+    size_t bos = __bos(s);
+
+    // Compiler doesn't know destination size. Don't call __strchr_chk
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strchr(s, c);
+    }
+
+    size_t slen = __builtin_strlen(s);
+    if (__builtin_constant_p(slen) && (slen < bos)) {
+        return __builtin_strchr(s, c);
+    }
+
+    return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* s, int c) {
+    size_t bos = __bos(s);
+
+    // Compiler doesn't know destination size. Don't call __strrchr_chk
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin_strrchr(s, c);
+    }
+
+    size_t slen = __builtin_strlen(s);
+    if (__builtin_constant_p(slen) && (slen < bos)) {
+        return __builtin_strrchr(s, c);
+    }
+
+    return __strrchr_chk(s, c, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+#endif /* defined(__clang__) */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
new file mode 100644
index 0000000..ea5c89d
--- /dev/null
+++ b/libc/include/bits/fortify/unistd.h
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#ifndef _UNISTD_H_
+#error "Never include this file directly; instead, include <unistd.h>"
+#endif
+
+char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
+
+ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
+
+ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
+
+ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
+
+ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
+  __INTRODUCED_IN(12);
+
+ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
+ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
+ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+
+#if defined(__BIONIC_FORTIFY)
+
+#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, fn) \
+    __clang_error_if((what) > SSIZE_MAX, "in call to '" #fn "', '" #what "' must be <= SSIZE_MAX")
+
+#define __error_if_overflows_objectsize(what, objsize, fn) \
+    __clang_error_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && (what) > (objsize), \
+                     "in call to '" #fn "', '" #what "' bytes overflows the given object")
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* const __pass_object_size buf, size_t size)
+        __overloadable
+        __error_if_overflows_objectsize(size, __bos(buf), getcwd) {
+    size_t bos = __bos(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __call_bypassing_fortify(getcwd)(buf, size);
+    }
+
+    return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count, off_t offset)
+        __overloadable
+        __error_if_overflows_ssizet(count, pread)
+        __error_if_overflows_objectsize(count, __bos0(buf), pread) {
+    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_FORTIFY_INLINE
+ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count, off64_t offset)
+        __overloadable
+        __error_if_overflows_ssizet(count, pread64)
+        __error_if_overflows_objectsize(count, __bos0(buf), pread64) {
+    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_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count, off_t offset)
+        __overloadable
+        __error_if_overflows_ssizet(count, pwrite)
+        __error_if_overflows_objectsize(count, __bos0(buf), pwrite) {
+    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_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf, size_t count, off64_t offset)
+        __overloadable
+        __error_if_overflows_ssizet(count, pwrite64)
+        __error_if_overflows_objectsize(count, __bos0(buf), pwrite64) {
+    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_FORTIFY_INLINE
+ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
+        __overloadable
+        __error_if_overflows_ssizet(count, read)
+        __error_if_overflows_objectsize(count, __bos0(buf), read) {
+    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_FORTIFY_INLINE
+ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
+        __overloadable
+        __error_if_overflows_ssizet(count, write)
+        __error_if_overflows_objectsize(count, __bos0(buf), write) {
+    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_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* const __pass_object_size buf, size_t size)
+        __overloadable
+        __error_if_overflows_ssizet(size, readlink)
+        __error_if_overflows_objectsize(size, __bos(buf), readlink) {
+    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_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path, char* const __pass_object_size buf, size_t size)
+        __overloadable
+        __error_if_overflows_ssizet(size, readlinkat)
+        __error_if_overflows_objectsize(size, __bos(buf), readlinkat) {
+    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);
+    }
+
+    if (__builtin_constant_p(size) && (size > bos)) {
+        __getcwd_dest_size_error();
+    }
+
+    if (__builtin_constant_p(size) && (size <= bos)) {
+        return __getcwd_real(buf, size);
+    }
+
+    return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#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 (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __PREAD_PREFIX(count_toobig_error)();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __PREAD_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __PREAD_PREFIX(dest_size_error)();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __PREAD_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
+    size_t bos = __bos0(buf);
+
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __pread64_count_toobig_error();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __pread64_real(fd, buf, count, offset);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __pread64_dest_size_error();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        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_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
+    size_t bos = __bos0(buf);
+
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __PWRITE_PREFIX(count_toobig_error)();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __PWRITE_PREFIX(dest_size_error)();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+    }
+
+    return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
+    size_t bos = __bos0(buf);
+
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __pwrite64_count_toobig_error();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __pwrite64_real(fd, buf, count, offset);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __pwrite64_dest_size_error();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        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_FORTIFY_INLINE
+ssize_t read(int fd, void* buf, size_t count) {
+    size_t bos = __bos0(buf);
+
+    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+        __read_count_toobig_error();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __read_real(fd, buf, count);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __read_dest_size_error();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __read_real(fd, buf, count);
+    }
+
+    return __read_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* buf, size_t count) {
+    size_t bos = __bos0(buf);
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __write_real(fd, buf, count);
+    }
+
+    if (__builtin_constant_p(count) && (count > bos)) {
+        __write_dest_size_error();
+    }
+
+    if (__builtin_constant_p(count) && (count <= bos)) {
+        return __write_real(fd, buf, count);
+    }
+
+    return __write_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* buf, size_t size) {
+    size_t bos = __bos(buf);
+
+    if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
+        __readlink_size_toobig_error();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __readlink_real(path, buf, size);
+    }
+
+    if (__builtin_constant_p(size) && (size > bos)) {
+        __readlink_dest_size_error();
+    }
+
+    if (__builtin_constant_p(size) && (size <= bos)) {
+        return __readlink_real(path, buf, size);
+    }
+
+    return __readlink_chk(path, buf, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
+    size_t bos = __bos(buf);
+
+    if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
+        __readlinkat_size_toobig_error();
+    }
+
+    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __readlinkat_real(dirfd, path, buf, size);
+    }
+
+    if (__builtin_constant_p(size) && (size > bos)) {
+        __readlinkat_dest_size_error();
+    }
+
+    if (__builtin_constant_p(size) && (size <= bos)) {
+        return __readlinkat_real(dirfd, path, buf, size);
+    }
+
+    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) */
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index 018482d..76bbdb8 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -34,11 +34,6 @@
 
 __BEGIN_DECLS
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
 typedef struct {
   /* Pathname of shared object that contains address. */
   const char* dli_fname;
@@ -51,11 +46,11 @@
 } Dl_info;
 
 void* dlopen(const char* filename, int flag);
-int dlclose(void* _Nonnull handle);
+int dlclose(void* handle);
 char* dlerror(void);
-void* dlsym(void* handle, const char* _Nonnull symbol);
-void* dlvsym(void* handle, const char* _Nonnull symbol, const char* _Nonnull version) __INTRODUCED_IN(24);
-int dladdr(const void* addr, Dl_info* _Nonnull info);
+void* dlsym(void* handle, const char* symbol);
+void* dlvsym(void* handle, const char* symbol, const char* version) __INTRODUCED_IN(24);
+int dladdr(const void* addr, Dl_info* info);
 
 #define RTLD_LOCAL    0
 #define RTLD_LAZY     0x00001
@@ -80,10 +75,6 @@
 #define RTLD_NEXT     __BIONIC_CAST(reinterpret_cast, void*, 0xfffffffe)
 #endif
 
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
 __END_DECLS
 
 #endif /* __DLFCN_H */
diff --git a/libc/include/err.h b/libc/include/err.h
index ca62c9e..7ee3608 100644
--- a/libc/include/err.h
+++ b/libc/include/err.h
@@ -35,6 +35,7 @@
 #ifndef _ERR_H_
 #define _ERR_H_
 
+#include <stdarg.h>
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
@@ -45,13 +46,13 @@
 #define __errlike(x, y) __attribute__((__format__(printf, x, y)))
 
 __noreturn void err(int, const char *, ...) __errlike(2, 3);
-__noreturn void verr(int, const char *, __va_list) __errlike(2, 0);
+__noreturn void verr(int, const char *, va_list) __errlike(2, 0);
 __noreturn void errx(int, const char *, ...) __errlike(2, 3);
-__noreturn void verrx(int, const char *, __va_list) __errlike(2, 0);
+__noreturn void verrx(int, const char *, va_list) __errlike(2, 0);
 void warn(const char *, ...) __errlike(1, 2);
-void vwarn(const char *, __va_list) __errlike(1, 0);
+void vwarn(const char *, va_list) __errlike(1, 0);
 void warnx(const char *, ...) __errlike(1, 2);
-void vwarnx(const char *, __va_list) __errlike(1, 0);
+void vwarnx(const char *, va_list) __errlike(1, 0);
 
 __END_DECLS
 
diff --git a/libc/include/error.h b/libc/include/error.h
index 05ce35d..b145afc 100644
--- a/libc/include/error.h
+++ b/libc/include/error.h
@@ -33,12 +33,12 @@
 
 __BEGIN_DECLS
 
-extern void (* _Nullable error_print_progname)(void) __INTRODUCED_IN(23);
+extern void (*error_print_progname)(void) __INTRODUCED_IN(23);
 extern unsigned int error_message_count __INTRODUCED_IN(23);
 extern int error_one_per_line __INTRODUCED_IN(23);
 
-void error(int, int, const char* _Nonnull, ...) __printflike(3, 4) __INTRODUCED_IN(23);
-void error_at_line(int, int, const char* _Nullable, unsigned int, const char* _Nonnull, ...)
+void error(int, int, const char*, ...) __printflike(3, 4) __INTRODUCED_IN(23);
+void error_at_line(int, int, const char*, unsigned int, const char*, ...)
     __printflike(5, 6) __INTRODUCED_IN(23);
 
 __END_DECLS
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index f27efdf..cd52b45 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -91,120 +91,9 @@
 int sync_file_range(int, off64_t, off64_t, unsigned int) __INTRODUCED_IN(26);
 #endif
 
-int __open_2(const char*, int) __INTRODUCED_IN(17);
-int __openat_2(int, const char*, int) __INTRODUCED_IN(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);
-
-
-#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 __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)) {
-        if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
-            __creat_missing_mode();  /* Compile time error. */
-        }
-    }
-
-    if (__builtin_va_arg_pack_len() > 1) {
-        __creat_too_many_args();  /* Compile time error. */
-    }
-
-    if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
-        return __open_2(pathname, flags);
-    }
-
-    return __open_real(pathname, flags, __builtin_va_arg_pack());
-}
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* pathname, int flags, ...) {
-    if (__builtin_constant_p(flags)) {
-        if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
-            __creat_missing_mode();  /* Compile time error. */
-        }
-    }
-
-    if (__builtin_va_arg_pack_len() > 1) {
-        __creat_too_many_args();  /* Compile time error. */
-    }
-
-    if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
-        return __openat_2(dirfd, pathname, flags);
-    }
-
-    return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-
-#undef __open_too_many_args_error
-#undef __open_too_few_args_error
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/fcntl.h>
+#endif
 
 __END_DECLS
 
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index f74afa3..43474df 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -257,10 +257,10 @@
 __BEGIN_DECLS
 intmax_t imaxabs(intmax_t) __attribute_const__ __INTRODUCED_IN(19);
 imaxdiv_t imaxdiv(intmax_t, intmax_t) __attribute_const__ __INTRODUCED_IN(19);
-intmax_t	strtoimax(const char *, char **, int);
-uintmax_t	strtoumax(const char *, char **, int);
-intmax_t wcstoimax(const wchar_t* __restrict, wchar_t** __restrict, int) __INTRODUCED_IN(21);
-uintmax_t wcstoumax(const wchar_t* __restrict, wchar_t** __restrict, int) __INTRODUCED_IN(21);
+intmax_t strtoimax(const char*, char**, int);
+uintmax_t strtoumax(const char*, char**, int);
+intmax_t wcstoimax(const wchar_t*, wchar_t**, int) __INTRODUCED_IN(21);
+uintmax_t wcstoumax(const wchar_t*, wchar_t**, int) __INTRODUCED_IN(21);
 __END_DECLS
 
 #endif /* _INTTYPES_H_ */
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 3287a0c..0f5758d 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -42,87 +42,9 @@
 int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*)
         __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
 
-int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
-int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
-  __INTRODUCED_IN(23);
-
-#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);
-__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
-
-__BIONIC_FORTIFY_INLINE
-int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
-  if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-    if (!__builtin_constant_p(fd_count)) {
-      return __poll_chk(fds, fd_count, timeout, __bos(fds));
-    } else if (__bos(fds) / sizeof(*fds) < fd_count) {
-      __poll_too_small_error();
-    }
-  }
-  return __poll_real(fds, fd_count, timeout);
-}
-
-__BIONIC_FORTIFY_INLINE
-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));
-    } else if (__bos(fds) / sizeof(*fds) < fd_count) {
-      __ppoll_too_small_error();
-    }
-  }
-  return __ppoll_real(fds, fd_count, timeout, mask);
-}
-
-#endif /* defined(__clang__) */
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/poll.h>
+#endif
 
 __END_DECLS
 
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 7dec3cc..7165738 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -38,11 +38,6 @@
 
 __BEGIN_DECLS
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
 enum {
     PTHREAD_MUTEX_NORMAL = 0,
     PTHREAD_MUTEX_RECURSIVE = 1,
@@ -90,51 +85,48 @@
 
 int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)) __INTRODUCED_IN(12);
 
-int pthread_attr_destroy(pthread_attr_t* _Nonnull);
-int pthread_attr_getdetachstate(const pthread_attr_t* _Nonnull, int* _Nonnull);
-int pthread_attr_getguardsize(const pthread_attr_t* _Nonnull, size_t* _Nonnull);
-int pthread_attr_getschedparam(const pthread_attr_t* _Nonnull, struct sched_param* _Nonnull);
-int pthread_attr_getschedpolicy(const pthread_attr_t* _Nonnull, int* _Nonnull);
-int pthread_attr_getscope(const pthread_attr_t* _Nonnull, int* _Nonnull);
-int pthread_attr_getstack(const pthread_attr_t* _Nonnull, void** _Nonnull, size_t* _Nonnull);
-int pthread_attr_getstacksize(const pthread_attr_t* _Nonnull, size_t* _Nonnull);
-int pthread_attr_init(pthread_attr_t* _Nonnull);
-int pthread_attr_setdetachstate(pthread_attr_t* _Nonnull, int);
-int pthread_attr_setguardsize(pthread_attr_t* _Nonnull, size_t);
-int pthread_attr_setschedparam(pthread_attr_t* _Nonnull, const struct sched_param* _Nonnull);
-int pthread_attr_setschedpolicy(pthread_attr_t* _Nonnull, int);
-int pthread_attr_setscope(pthread_attr_t* _Nonnull, int);
-int pthread_attr_setstack(pthread_attr_t* _Nonnull, void*, size_t);
-int pthread_attr_setstacksize(pthread_attr_t* _Nonnull, size_t);
+int pthread_attr_destroy(pthread_attr_t*);
+int pthread_attr_getdetachstate(const pthread_attr_t*, int*);
+int pthread_attr_getguardsize(const pthread_attr_t*, size_t*);
+int pthread_attr_getschedparam(const pthread_attr_t*, struct sched_param*);
+int pthread_attr_getschedpolicy(const pthread_attr_t*, int*);
+int pthread_attr_getscope(const pthread_attr_t*, int*);
+int pthread_attr_getstack(const pthread_attr_t*, void**, size_t*);
+int pthread_attr_getstacksize(const pthread_attr_t*, size_t*);
+int pthread_attr_init(pthread_attr_t*);
+int pthread_attr_setdetachstate(pthread_attr_t*, int);
+int pthread_attr_setguardsize(pthread_attr_t*, size_t);
+int pthread_attr_setschedparam(pthread_attr_t*, const struct sched_param*);
+int pthread_attr_setschedpolicy(pthread_attr_t*, int);
+int pthread_attr_setscope(pthread_attr_t*, int);
+int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
+int pthread_attr_setstacksize(pthread_attr_t*, size_t);
 
-int pthread_condattr_destroy(pthread_condattr_t* _Nonnull);
-int pthread_condattr_getclock(const pthread_condattr_t* _Nonnull, clockid_t* _Nonnull)
-  __INTRODUCED_IN(21);
-int pthread_condattr_getpshared(const pthread_condattr_t* _Nonnull, int* _Nonnull);
-int pthread_condattr_init(pthread_condattr_t* _Nonnull);
-int pthread_condattr_setclock(pthread_condattr_t* _Nonnull, clockid_t) __INTRODUCED_IN(21);
-int pthread_condattr_setpshared(pthread_condattr_t* _Nonnull, int);
+int pthread_condattr_destroy(pthread_condattr_t*);
+int pthread_condattr_getclock(const pthread_condattr_t*, clockid_t*) __INTRODUCED_IN(21);
+int pthread_condattr_getpshared(const pthread_condattr_t*, int*);
+int pthread_condattr_init(pthread_condattr_t*);
+int pthread_condattr_setclock(pthread_condattr_t*, clockid_t) __INTRODUCED_IN(21);
+int pthread_condattr_setpshared(pthread_condattr_t*, int);
 
-int pthread_cond_broadcast(pthread_cond_t* _Nonnull);
-int pthread_cond_destroy(pthread_cond_t* _Nonnull);
-int pthread_cond_init(pthread_cond_t* _Nonnull, const pthread_condattr_t*);
-int pthread_cond_signal(pthread_cond_t* _Nonnull);
-int pthread_cond_timedwait(pthread_cond_t* _Nonnull, pthread_mutex_t* _Nonnull,
-                           const struct timespec* _Nonnull);
-int pthread_cond_wait(pthread_cond_t* _Nonnull, pthread_mutex_t* _Nonnull);
+int pthread_cond_broadcast(pthread_cond_t*);
+int pthread_cond_destroy(pthread_cond_t*);
+int pthread_cond_init(pthread_cond_t*, const pthread_condattr_t*);
+int pthread_cond_signal(pthread_cond_t*);
+int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const struct timespec*);
+int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
 
-int pthread_create(pthread_t* _Nonnull, pthread_attr_t const*,
-                   void* (* _Nonnull start_routine)(void*), void*);
+int pthread_create(pthread_t*, pthread_attr_t const*, void* (*start_routine)(void*), void*);
 int pthread_detach(pthread_t);
 void pthread_exit(void*) __noreturn;
 
 int pthread_equal(pthread_t, pthread_t);
 
-int pthread_getattr_np(pthread_t, pthread_attr_t* _Nonnull);
+int pthread_getattr_np(pthread_t, pthread_attr_t*);
 
-int pthread_getcpuclockid(pthread_t, clockid_t* _Nonnull);
+int pthread_getcpuclockid(pthread_t, clockid_t*);
 
-int pthread_getschedparam(pthread_t, int* _Nonnull, struct sched_param* _Nonnull);
+int pthread_getschedparam(pthread_t, int*, struct sched_param*);
 
 void* pthread_getspecific(pthread_key_t);
 
@@ -142,23 +134,23 @@
 
 int pthread_join(pthread_t, void**);
 
-int pthread_key_create(pthread_key_t* _Nonnull, void (*)(void*));
+int pthread_key_create(pthread_key_t*, void (*)(void*));
 int pthread_key_delete(pthread_key_t);
 
-int pthread_mutexattr_destroy(pthread_mutexattr_t* _Nonnull);
-int pthread_mutexattr_getpshared(const pthread_mutexattr_t* _Nonnull, int* _Nonnull);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t* _Nonnull, int* _Nonnull);
-int pthread_mutexattr_init(pthread_mutexattr_t* _Nonnull);
-int pthread_mutexattr_setpshared(pthread_mutexattr_t* _Nonnull, int);
-int pthread_mutexattr_settype(pthread_mutexattr_t* _Nonnull, int);
+int pthread_mutexattr_destroy(pthread_mutexattr_t*);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t*, int*);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t*, int*);
+int pthread_mutexattr_init(pthread_mutexattr_t*);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
+int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
 
-int pthread_mutex_destroy(pthread_mutex_t* _Nonnull);
-int pthread_mutex_init(pthread_mutex_t* _Nonnull, const pthread_mutexattr_t*);
-int pthread_mutex_lock(pthread_mutex_t* _Nonnull);
-int pthread_mutex_timedlock(pthread_mutex_t* _Nonnull, const struct timespec* _Nonnull)
+int pthread_mutex_destroy(pthread_mutex_t*);
+int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*);
+int pthread_mutex_lock(pthread_mutex_t*);
+int pthread_mutex_timedlock(pthread_mutex_t*, const struct timespec* )
   __INTRODUCED_IN(21);
-int pthread_mutex_trylock(pthread_mutex_t* _Nonnull);
-int pthread_mutex_unlock(pthread_mutex_t* _Nonnull);
+int pthread_mutex_trylock(pthread_mutex_t*);
+int pthread_mutex_unlock(pthread_mutex_t*);
 
 #if defined(__LP32__) && __ANDROID_API__ < 21
 /*
@@ -180,59 +172,59 @@
                                        const struct timespec* reltime);
 #endif
 
-int pthread_once(pthread_once_t* _Nonnull, void (* _Nonnull init_routine)(void));
+int pthread_once(pthread_once_t*, void (*init_routine)(void));
 
-int pthread_rwlockattr_init(pthread_rwlockattr_t* _Nonnull);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t* _Nonnull);
-int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* _Nonnull, int* _Nonnull);
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _Nonnull, int);
-int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* _Nonnull, int* _Nonnull)
+int pthread_rwlockattr_init(pthread_rwlockattr_t*);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t*, int*);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t*, int*)
   __INTRODUCED_IN(23);
-int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* _Nonnull, int) __INTRODUCED_IN(23);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t*, int) __INTRODUCED_IN(23);
 
-int pthread_rwlock_destroy(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_init(pthread_rwlock_t* _Nonnull, const pthread_rwlockattr_t*);
-int pthread_rwlock_rdlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_timedrdlock(pthread_rwlock_t* _Nonnull, const struct timespec* _Nonnull);
-int pthread_rwlock_timedwrlock(pthread_rwlock_t* _Nonnull, const struct timespec* _Nonnull);
-int pthread_rwlock_tryrdlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_trywrlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull);
-int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull);
+int pthread_rwlock_destroy(pthread_rwlock_t*);
+int pthread_rwlock_init(pthread_rwlock_t*, const pthread_rwlockattr_t*);
+int pthread_rwlock_rdlock(pthread_rwlock_t*);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t*, const struct timespec*);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t*, const struct timespec*);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
+int pthread_rwlock_trywrlock(pthread_rwlock_t*);
+int pthread_rwlock_unlock(pthread_rwlock_t*);
+int pthread_rwlock_wrlock(pthread_rwlock_t*);
 
 #if __ANDROID_API__ >= __ANDROID_API_N__
-int pthread_barrierattr_init(pthread_barrierattr_t* _Nonnull attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_destroy(pthread_barrierattr_t* _Nonnull attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_getpshared(const pthread_barrierattr_t* _Nonnull attr,
-                                   int* _Nonnull pshared) __INTRODUCED_IN(24);
-int pthread_barrierattr_setpshared(pthread_barrierattr_t* _Nonnull attr, int pshared)
+int pthread_barrierattr_init(pthread_barrierattr_t* attr) __INTRODUCED_IN(24);
+int pthread_barrierattr_destroy(pthread_barrierattr_t* attr) __INTRODUCED_IN(24);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t* attr,
+                                   int* pshared) __INTRODUCED_IN(24);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared)
   __INTRODUCED_IN(24);
 #endif
 
 #if __ANDROID_API__ >= __ANDROID_API_N__
-int pthread_barrier_init(pthread_barrier_t* _Nonnull, const pthread_barrierattr_t*, unsigned)
+int pthread_barrier_init(pthread_barrier_t*, const pthread_barrierattr_t*, unsigned)
   __INTRODUCED_IN(24);
-int pthread_barrier_destroy(pthread_barrier_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_barrier_wait(pthread_barrier_t* _Nonnull) __INTRODUCED_IN(24);
+int pthread_barrier_destroy(pthread_barrier_t*) __INTRODUCED_IN(24);
+int pthread_barrier_wait(pthread_barrier_t*) __INTRODUCED_IN(24);
 #endif
 
 #if __ANDROID_API__ >= __ANDROID_API_N__
-int pthread_spin_destroy(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_spin_init(pthread_spinlock_t* _Nonnull, int) __INTRODUCED_IN(24);
-int pthread_spin_lock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_spin_trylock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
-int pthread_spin_unlock(pthread_spinlock_t* _Nonnull) __INTRODUCED_IN(24);
+int pthread_spin_destroy(pthread_spinlock_t*) __INTRODUCED_IN(24);
+int pthread_spin_init(pthread_spinlock_t*, int) __INTRODUCED_IN(24);
+int pthread_spin_lock(pthread_spinlock_t*) __INTRODUCED_IN(24);
+int pthread_spin_trylock(pthread_spinlock_t*) __INTRODUCED_IN(24);
+int pthread_spin_unlock(pthread_spinlock_t*) __INTRODUCED_IN(24);
 #endif
 
 pthread_t pthread_self(void) __attribute_const__;
 
 #if defined(__USE_GNU)
-int pthread_getname_np(pthread_t, char* _Nonnull, size_t) __INTRODUCED_IN(26);
+int pthread_getname_np(pthread_t, char*, size_t) __INTRODUCED_IN(26);
 #endif
 /* TODO: this should be __USE_GNU too. */
-int pthread_setname_np(pthread_t, const char* _Nonnull);
+int pthread_setname_np(pthread_t, const char*);
 
-int pthread_setschedparam(pthread_t, int, const struct sched_param* _Nonnull);
+int pthread_setschedparam(pthread_t, int, const struct sched_param*);
 
 int pthread_setspecific(pthread_key_t, const void*);
 
@@ -262,10 +254,6 @@
         __pthread_cleanup_pop( &__cleanup, (execute)); \
     } while (0);                                       \
 
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
 __END_DECLS
 
 #endif /* _PTHREAD_H_ */
diff --git a/libc/include/sched.h b/libc/include/sched.h
index d407202..b8ef44b 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -25,6 +25,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
 #ifndef _SCHED_H_
 #define _SCHED_H_
 
@@ -41,22 +42,22 @@
   int sched_priority;
 };
 
-int sched_setscheduler(pid_t, int, const struct sched_param*);
-int sched_getscheduler(pid_t);
+int sched_setscheduler(pid_t pid, int policy, const struct sched_param* param);
+int sched_getscheduler(pid_t pid);
 int sched_yield(void);
-int sched_get_priority_max(int);
-int sched_get_priority_min(int);
-int sched_setparam(pid_t, const struct sched_param*);
-int sched_getparam(pid_t, struct sched_param*);
-int sched_rr_get_interval(pid_t, struct timespec*);
+int sched_get_priority_max(int policy);
+int sched_get_priority_min(int policy);
+int sched_setparam(pid_t pid, const struct sched_param* param);
+int sched_getparam(pid_t pid, struct sched_param* param);
+int sched_rr_get_interval(pid_t pid, struct timespec* quantum);
 
 #if defined(__USE_GNU)
 
-int clone(int (*)(void*), void*, int, void*, ...) __INTRODUCED_IN_ARM(9)
-    __INTRODUCED_IN_MIPS(12) __INTRODUCED_IN_X86(17);
-int unshare(int) __INTRODUCED_IN(17);
+int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...)
+    __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_MIPS(12) __INTRODUCED_IN_X86(17);
+int unshare(int flags) __INTRODUCED_IN(17);
 int sched_getcpu(void) __INTRODUCED_IN(12);
-int setns(int, int) __INTRODUCED_IN(21);
+int setns(int fd, int ns_type) __INTRODUCED_IN(21);
 
 #ifdef __LP64__
 #define CPU_SETSIZE 1024
diff --git a/libc/include/search.h b/libc/include/search.h
index dc160e9..46998d9 100644
--- a/libc/include/search.h
+++ b/libc/include/search.h
@@ -37,7 +37,7 @@
 void* lsearch(const void*, void*, size_t*, size_t, int (*)(const void*, const void*))
   __INTRODUCED_IN(21);
 
-void* tdelete(const void* __restrict, void** __restrict, int (*)(const void*, const void*))
+void* tdelete(const void*, void**, int (*)(const void*, const void*))
   __INTRODUCED_IN(16);
 void tdestroy(void*, void (*)(void*)) __INTRODUCED_IN(16);
 void* tfind(const void*, void* const*, int (*)(const void*, const void*)) __INTRODUCED_IN(16);
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 1400328..89d85fc 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -54,11 +54,6 @@
 
 __BEGIN_DECLS
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
 typedef int sig_atomic_t;
 
 /* The arm and x86 kernel header files don't define _NSIG. */
@@ -129,10 +124,10 @@
 // Implemented as static inlines before 21.
 #endif
 
-int sigpending(sigset_t* _Nonnull);
+int sigpending(sigset_t*);
 int sigprocmask(int, const sigset_t*, sigset_t*);
-int sigsuspend(const sigset_t* _Nonnull);
-int sigwait(const sigset_t* _Nonnull, int* _Nonnull);
+int sigsuspend(const sigset_t*);
+int sigwait(const sigset_t*, int*);
 
 int sighold(int)
   __attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead")))
@@ -161,12 +156,8 @@
 int pthread_sigmask(int, const sigset_t*, sigset_t*);
 
 int sigqueue(pid_t, int, const union sigval) __INTRODUCED_IN(23);
-int sigtimedwait(const sigset_t* _Nonnull, siginfo_t*, const struct timespec*) __INTRODUCED_IN(23);
-int sigwaitinfo(const sigset_t* _Nonnull, siginfo_t*) __INTRODUCED_IN(23);
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
+int sigtimedwait(const sigset_t*, siginfo_t*, const struct timespec*) __INTRODUCED_IN(23);
+int sigwaitinfo(const sigset_t*, siginfo_t*) __INTRODUCED_IN(23);
 
 __END_DECLS
 
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index ca56437..7e5a976 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -44,9 +44,6 @@
 #include <stdarg.h>
 #include <stddef.h>
 
-#define __need_NULL
-#include <stddef.h>
-
 #include <bits/seek_constants.h>
 
 #if __ANDROID_API__ < __ANDROID_API_N__
@@ -55,11 +52,6 @@
 
 __BEGIN_DECLS
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
 typedef off_t fpos_t;
 typedef off64_t fpos64_t;
 
@@ -105,12 +97,11 @@
  * stdio can provide without attempting to allocate further resources
  * (which could fail).  Do not use this for anything.
  */
+#define FOPEN_MAX 20
+#define FILENAME_MAX 4096
 
-#define	FOPEN_MAX	20	/* must be <= OPEN_MAX <sys/syslimits.h> */
-#define	FILENAME_MAX	1024	/* must be <= PATH_MAX <sys/syslimits.h> */
-
-#define	L_tmpnam	1024	/* XXX must be == PATH_MAX */
-#define	TMP_MAX		308915776
+#define L_tmpnam 4096
+#define TMP_MAX 308915776
 
 /*
  * Functions defined in ANSI C standard.
@@ -121,47 +112,59 @@
 int	 ferror(FILE *);
 int	 fflush(FILE *);
 int	 fgetc(FILE *);
-char	*fgets(char * __restrict, int, FILE * __restrict) __overloadable
+char	*fgets(char *, int, FILE *) __overloadable
   __RENAME_CLANG(fgets);
-int	 fprintf(FILE * __restrict , const char * __restrict _Nonnull, ...) __printflike(2, 3);
+int	 fprintf(FILE * , const char *, ...) __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)
+int	 fputs(const char *, FILE *);
+size_t	 fread(void *, size_t, size_t, FILE *)
       __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)
+int	 fscanf(FILE *, const char *, ...) __scanflike(2, 3);
+size_t	 fwrite(const void *, size_t, size_t, FILE *)
     __overloadable __RENAME_CLANG(fwrite);
 int	 getc(FILE *);
 int	 getchar(void);
-ssize_t getdelim(char** __restrict, size_t* __restrict, int, FILE* __restrict) __INTRODUCED_IN(18);
-ssize_t getline(char** __restrict, size_t* __restrict, FILE* __restrict) __INTRODUCED_IN(18);
+ssize_t getdelim(char**, size_t*, int, FILE*) __INTRODUCED_IN(18);
+ssize_t getline(char**, size_t*, FILE*) __INTRODUCED_IN(18);
 
 void	 perror(const char *);
-int	 printf(const char * __restrict _Nonnull, ...) __printflike(1, 2);
+int	 printf(const char *, ...) __printflike(1, 2);
 int	 putc(int, FILE *);
 int	 putchar(int);
 int	 puts(const char *);
 int	 remove(const char *);
 void	 rewind(FILE *);
-int	 scanf(const char * __restrict _Nonnull, ...) __scanflike(1, 2);
-void	 setbuf(FILE * __restrict, char * __restrict);
-int	 setvbuf(FILE * __restrict, char * __restrict, int, size_t);
-int	 sscanf(const char * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3);
+int	 scanf(const char *, ...) __scanflike(1, 2);
+void	 setbuf(FILE *, char *);
+int	 setvbuf(FILE *, char *, int, size_t);
+int	 sscanf(const char *, const char *, ...) __scanflike(2, 3);
 int	 ungetc(int, FILE *);
-int	 vfprintf(FILE * __restrict, const char * __restrict _Nonnull, __va_list) __printflike(2, 0);
-int	 vprintf(const char * __restrict _Nonnull, __va_list) __printflike(1, 0);
+int	 vfprintf(FILE *, const char *, va_list) __printflike(2, 0);
+int	 vprintf(const char *, va_list) __printflike(1, 0);
 
-int dprintf(int, const char* __restrict _Nonnull, ...) __printflike(2, 3) __INTRODUCED_IN(21);
-int vdprintf(int, const char* __restrict _Nonnull, __va_list) __printflike(2, 0) __INTRODUCED_IN(21);
+#if __ANDROID_API__ >= 21
+int dprintf(int, const char*, ...) __printflike(2, 3) __INTRODUCED_IN(21);
+int vdprintf(int, const char*, va_list) __printflike(2, 0) __INTRODUCED_IN(21);
+#else
+/*
+ * Old versions of Android called these fdprintf and vfdprintf out of fears that the glibc names
+ * would collide with user debug printfs.
+ *
+ * Allow users to just use dprintf and vfdprintf on any version by renaming those calls to their
+ * legacy equivalents if needed.
+ */
+int dprintf(int, const char*, ...) __printflike(2, 3) __RENAME(fdprintf);
+int vdprintf(int, const char*, va_list) __printflike(2, 0) __RENAME(vfdprintf);
+#endif
 
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L) || \
     (defined(__cplusplus) && __cplusplus <= 201103L)
 char* gets(char*) __attribute__((deprecated("gets is unsafe, use fgets instead")));
 #endif
-int sprintf(char* __restrict, const char* __restrict _Nonnull, ...)
+int sprintf(char*, const char*, ...)
     __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)
+int vsprintf(char*, const char*, va_list)
     __overloadable __printflike(2, 0) __RENAME_CLANG(vsprintf)
     __warnattr_strict("vsprintf is often misused; please use vsnprintf");
 char* tmpnam(char*)
@@ -210,21 +213,21 @@
                 fpos64_t (*)(void*, fpos64_t, int), int (*)(void*)) __INTRODUCED_IN(24);
 #endif
 
-FILE* fopen(const char* __restrict, const char* __restrict);
-FILE* fopen64(const char* __restrict, const char* __restrict) __INTRODUCED_IN(24);
-FILE* freopen(const char* __restrict, const char* __restrict, FILE* __restrict);
-FILE* freopen64(const char* __restrict, const char* __restrict, FILE* __restrict)
+FILE* fopen(const char*, const char*);
+FILE* fopen64(const char*, const char*) __INTRODUCED_IN(24);
+FILE* freopen(const char*, const char*, FILE*);
+FILE* freopen64(const char*, const char*, FILE*)
   __INTRODUCED_IN(24);
 FILE* tmpfile(void);
 FILE* tmpfile64(void) __INTRODUCED_IN(24);
 
-int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...)
+int snprintf(char*, size_t, const char*, ...)
     __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)
+int vfscanf(FILE*, const char*, va_list) __scanflike(2, 0);
+int vscanf(const char* , va_list) __scanflike(1, 0);
+int vsnprintf(char*, size_t, const char*, va_list)
     __printflike(3, 0) __overloadable __RENAME_CLANG(vsnprintf);
-int vsscanf(const char* __restrict _Nonnull, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0);
+int vsscanf(const char*, const char*, va_list) __scanflike(2, 0);
 
 #define L_ctermid 1024 /* size for ctermid() */
 char* ctermid(char*) __INTRODUCED_IN(26);
@@ -245,12 +248,12 @@
 FILE* open_memstream(char**, size_t*) __INTRODUCED_IN(23);
 
 #if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
-int  asprintf(char** __restrict, const char* __restrict _Nonnull, ...) __printflike(2, 3);
-char* fgetln(FILE* __restrict, size_t* __restrict);
+int  asprintf(char**, const char*, ...) __printflike(2, 3);
+char* fgetln(FILE*, size_t*);
 int fpurge(FILE*);
 void setbuffer(FILE*, char*, int);
 int setlinebuf(FILE*);
-int vasprintf(char** __restrict, const char* __restrict _Nonnull, __va_list) __printflike(2, 0);
+int vasprintf(char**, const char*, va_list) __printflike(2, 0);
 void clearerr_unlocked(FILE*) __INTRODUCED_IN(23);
 int feof_unlocked(FILE*) __INTRODUCED_IN(23);
 int ferror_unlocked(FILE*) __INTRODUCED_IN(23);
@@ -259,268 +262,8 @@
 #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
 #endif /* __USE_BSD */
 
-char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
-size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
-    __INTRODUCED_IN(24);
-size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
-    __INTRODUCED_IN(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");
-
-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 __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__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, 3)
-int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
-    return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
-                                   __builtin_va_arg_pack());
-}
-#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 bos = __bos0(buf);
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __fread_real(buf, size, count, stream);
-    }
-
-    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
-        size_t total;
-        if (__size_mul_overflow(size, count, &total)) {
-            __fread_overflow();
-        }
-
-        if (total > bos) {
-            __fread_too_big_error();
-        }
-
-        return __fread_real(buf, size, count, stream);
-    }
-
-    return __fread_chk(buf, size, count, stream, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
-    size_t bos = __bos0(buf);
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __fwrite_real(buf, size, count, stream);
-    }
-
-    if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
-        size_t total;
-        if (__size_mul_overflow(size, count, &total)) {
-            __fwrite_overflow();
-        }
-
-        if (total > bos) {
-            __fwrite_too_big_error();
-        }
-
-        return __fwrite_real(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_FORTIFY_INLINE
-char *fgets(char* dest, int size, FILE* stream) {
-    size_t bos = __bos(dest);
-
-    // Compiler can prove, at compile time, that the passed in size
-    // is always negative. Force a compiler error.
-    if (__builtin_constant_p(size) && (size < 0)) {
-        __fgets_too_small_error();
-    }
-
-    // Compiler doesn't know destination size. Don't call __fgets_chk
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __fgets_real(dest, size, stream);
-    }
-
-    // Compiler can prove, at compile time, that the passed in size
-    // is always <= the actual object size. Don't call __fgets_chk
-    if (__builtin_constant_p(size) && (size <= (int) bos)) {
-        return __fgets_real(dest, size, stream);
-    }
-
-    // Compiler can prove, at compile time, that the passed in size
-    // is always > the actual object size. Force a compiler error.
-    if (__builtin_constant_p(size) && (size > (int) bos)) {
-        __fgets_too_big_error();
-    }
-
-    return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdio.h>
 #endif
 
 __END_DECLS
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index fdf6772..3c5abc3 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -40,7 +40,9 @@
 
 size_t __fbufsize(FILE*) __INTRODUCED_IN(23);
 int __freadable(FILE*) __INTRODUCED_IN(23);
+int __freading(FILE*) __INTRODUCED_IN_FUTURE;
 int __fwritable(FILE*) __INTRODUCED_IN(23);
+int __fwriting(FILE*) __INTRODUCED_IN_FUTURE;
 int __flbf(FILE*) __INTRODUCED_IN(23);
 void __fpurge(FILE*) __INTRODUCED_IN(23);
 size_t __fpending(FILE*) __INTRODUCED_IN(23);
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 24ddd99..13c9d37 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -83,8 +83,7 @@
 long atol(const char*) __attribute_pure__;
 long long atoll(const char*) __attribute_pure__;
 
-char * realpath(const char *path, char *resolved) __overloadable
-        __RENAME_CLANG(realpath);
+char* realpath(const char* path, char* resolved);
 int system(const char *string);
 
 void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
@@ -165,46 +164,9 @@
 #define MB_CUR_MAX 1
 #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_buf_too_small_str);
-
-__BIONIC_FORTIFY_INLINE
-char* realpath(const char* path, char* resolved) {
-    size_t bos = __bos(resolved);
-
-    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
-        __realpath_size_error();
-    }
-
-    return __realpath_real(path, resolved);
-}
-
-#endif /* defined(__clang__) */
-
-#undef __PATH_MAX
-#undef __realpath_buf_too_small_str
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdlib.h>
+#endif
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
 float strtof(const char*, char**) __INTRODUCED_IN(21);
diff --git a/libc/include/string.h b/libc/include/string.h
index c15fe4a..631b3dd 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -37,64 +37,52 @@
 
 __BEGIN_DECLS
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
 #if defined(__USE_BSD)
 #include <strings.h>
 #endif
 
-void* memccpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, int, size_t);
-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* memccpy(void*, const void*, int, size_t);
+void* memchr(const void*, int, size_t) __attribute_pure__ __overloadable __RENAME_CLANG(memchr);
+void* memrchr(const void*, int, size_t) __attribute_pure__ __overloadable __RENAME_CLANG(memrchr);
+int memcmp(const void*, const void*, size_t) __attribute_pure__;
+void* memcpy(void*, const void*, size_t)
         __overloadable __RENAME_CLANG(memcpy);
 #if defined(__USE_GNU)
-void* mempcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t) __INTRODUCED_IN(23);
+void* mempcpy(void*, const void*, size_t) __INTRODUCED_IN(23);
 #endif
-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__;
+void* memmove(void*, const void*, size_t) __overloadable __RENAME_CLANG(memmove);
+void* memset(void*, int, size_t) __overloadable __RENAME_CLANG(memset);
+void* memmem(const void*, size_t, const void*, size_t) __attribute_pure__;
 
-char* strchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
-        __RENAME_CLANG(strchr);
-char* __strchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
+char* strchr(const char*, int) __attribute_pure__ __overloadable __RENAME_CLANG(strchr);
+char* __strchr_chk(const char*, int, size_t) __INTRODUCED_IN(18);
 #if defined(__USE_GNU)
 #if defined(__cplusplus)
-extern "C++" char* strchrnul(char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
-extern "C++" const char* strchrnul(const char* _Nonnull, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+extern "C++" char* strchrnul(char*, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
 #else
-char* strchrnul(const char* _Nonnull, int) __attribute_pure__ __INTRODUCED_IN(24);
+char* strchrnul(const char*, int) __attribute_pure__ __INTRODUCED_IN(24);
 #endif
 #endif
 
-char* strrchr(const char* _Nonnull, int) __attribute_pure__ __overloadable
-        __RENAME_CLANG(strrchr);
-char* __strrchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18);
+char* strrchr(const char*, int) __attribute_pure__ __overloadable __RENAME_CLANG(strrchr);
+char* __strrchr_chk(const char*, int, size_t) __INTRODUCED_IN(18);
 
-size_t strlen(const char* _Nonnull) __attribute_pure__ __overloadable
+size_t strlen(const char*) __attribute_pure__ __overloadable
         __RENAME_CLANG(strlen);
-size_t __strlen_chk(const char* _Nonnull, size_t) __INTRODUCED_IN(17);
+size_t __strlen_chk(const char*, size_t) __INTRODUCED_IN(17);
 
-int strcmp(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
-        __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
-char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict)
+int strcmp(const char*, const char*) __attribute_pure__;
+char* stpcpy(char*, const char*) __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21);
+char* strcpy(char*, const char*)
         __overloadable __RENAME_CLANG(strcpy);
-char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict)
-        __overloadable __RENAME_CLANG(strcat);
-char* strdup(const char* _Nonnull);
+char* strcat(char*, const char*) __overloadable __RENAME_CLANG(strcat);
+char* strdup(const char*);
 
-char* strstr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* strcasestr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-char* strtok(char* __restrict, const char* _Nonnull __restrict);
-char* strtok_r(char* __restrict, const char* _Nonnull __restrict, char** _Nonnull __restrict);
+char* strstr(const char*, const char*) __attribute_pure__;
+char* strcasestr(const char*, const char*) __attribute_pure__;
+char* strtok(char*, const char*);
+char* strtok_r(char*, const char*, char**);
 
 char* strerror(int);
 char* strerror_l(int, locale_t) __INTRODUCED_IN(23);
@@ -104,34 +92,29 @@
 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)
-        __overloadable __RENAME_CLANG(strncat);
-char* strndup(const char* _Nonnull, size_t);
-int strncmp(const char* _Nonnull, const char* _Nonnull, size_t) __attribute_pure__;
-char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
-        __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
-char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t)
-        __overloadable __RENAME_CLANG(strncpy);
+size_t strnlen(const char*, size_t) __attribute_pure__;
+char* strncat(char*, const char*, size_t) __overloadable __RENAME_CLANG(strncat);
+char* strndup(const char*, size_t);
+int strncmp(const char*, const char*, size_t) __attribute_pure__;
+char* stpncpy(char*, const char*, size_t) __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21);
+char* strncpy(char*, const char*, size_t) __overloadable __RENAME_CLANG(strncpy);
 
-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 strlcat(char*, const char*, size_t) __overloadable __RENAME_CLANG(strlcat);
+size_t strlcpy(char*, const char*, 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__;
-char* strsep(char** _Nonnull __restrict, const char* _Nonnull __restrict);
-size_t strspn(const char* _Nonnull, const char* _Nonnull);
+size_t strcspn(const char*, const char*) __attribute_pure__;
+char* strpbrk(const char*, const char*) __attribute_pure__;
+char* strsep(char**, const char*);
+size_t strspn(const char*, const char*);
 
 char* strsignal(int);
 
-int strcoll(const char* _Nonnull, const char* _Nonnull) __attribute_pure__;
-size_t strxfrm(char* __restrict, const char* _Nonnull __restrict, size_t);
+int strcoll(const char*, const char*) __attribute_pure__;
+size_t strxfrm(char*, const char*, size_t);
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
-int strcoll_l(const char* _Nonnull, const char* _Nonnull, locale_t) __attribute_pure__ __INTRODUCED_IN(21);
-size_t strxfrm_l(char* __restrict, const char* _Nonnull __restrict, size_t, locale_t) __INTRODUCED_IN(21);
+int strcoll_l(const char*, const char*, locale_t) __attribute_pure__ __INTRODUCED_IN(21);
+size_t strxfrm_l(char*, const char*, size_t, locale_t) __INTRODUCED_IN(21);
 #else
 // Implemented as static inlines before 21.
 #endif
@@ -142,462 +125,16 @@
  * It doesn't modify its argument, and in C++ it's const-correct.
  */
 #if defined(__cplusplus)
-extern "C++" char* basename(char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
-extern "C++" const char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+extern "C++" char* basename(char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
 #else
-char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
 #endif
 #endif
 
-void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
-  __INTRODUCED_IN(21);
-char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
-  __INTRODUCED_IN(21);
-size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
-size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(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* const _Nonnull s __pass_object_size, int c, size_t n)
-        __overloadable {
-    size_t bos = __bos(s);
-
-    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_size, int c)
-        __overloadable {
-    size_t bos = __bos(s);
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        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(strncpy);
-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);
-    }
-
-    if (__builtin_constant_p(n) && (n > bos)) {
-        __memchr_buf_size_error();
-    }
-
-    if (__builtin_constant_p(n) && (n <= bos)) {
-        return __builtin_memchr(s, c, n);
-    }
-
-    return __memchr_chk(s, c, n, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* s, int c, size_t n) {
-    size_t bos = __bos(s);
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __memrchr_real(s, c, n);
-    }
-
-    if (__builtin_constant_p(n) && (n > bos)) {
-        __memrchr_buf_size_error();
-    }
-
-    if (__builtin_constant_p(n) && (n <= bos)) {
-        return __memrchr_real(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* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
-    size_t bos_dst = __bos(dst);
-    size_t bos_src = __bos(src);
-
-    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin___stpncpy_chk(dst, src, n, bos_dst);
-    }
-
-    if (__builtin_constant_p(n) && (n <= bos_src)) {
-        return __builtin___stpncpy_chk(dst, src, n, bos_dst);
-    }
-
-    size_t slen = __builtin_strlen(src);
-    if (__builtin_constant_p(slen)) {
-        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* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
-    size_t bos_dst = __bos(dst);
-    size_t bos_src = __bos(src);
-
-    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __strncpy_real(dst, src, n);
-    }
-
-    if (__builtin_constant_p(n) && (n <= bos_src)) {
-        return __builtin___strncpy_chk(dst, src, n, bos_dst);
-    }
-
-    size_t slen = __builtin_strlen(src);
-    if (__builtin_constant_p(slen)) {
-        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* _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size) {
-    size_t bos = __bos(dst);
-
-    // Compiler doesn't know destination size. Don't call __strlcpy_chk
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __strlcpy_real(dst, src, size);
-    }
-
-    // Compiler can prove, at compile time, that the passed in size
-    // is always <= the actual object size. Don't call __strlcpy_chk
-    if (__builtin_constant_p(size) && (size <= bos)) {
-        return __strlcpy_real(dst, src, size);
-    }
-
-    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);
-
-    // Compiler doesn't know destination size. Don't call __strlcat_chk
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __strlcat_real(dst, src, size);
-    }
-
-    // Compiler can prove, at compile time, that the passed in size
-    // is always <= the actual object size. Don't call __strlcat_chk
-    if (__builtin_constant_p(size) && (size <= bos)) {
-        return __strlcat_real(dst, src, size);
-    }
-
-    return __strlcat_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* _Nonnull s) __overloadable {
-    size_t bos = __bos(s);
-
-    // Compiler doesn't know destination size. Don't call __strlen_chk
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin_strlen(s);
-    }
-
-    size_t slen = __builtin_strlen(s);
-    if (__builtin_constant_p(slen)) {
-        return slen;
-    }
-
-    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* _Nonnull s, int c) {
-    size_t bos = __bos(s);
-
-    // Compiler doesn't know destination size. Don't call __strchr_chk
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin_strchr(s, c);
-    }
-
-    size_t slen = __builtin_strlen(s);
-    if (__builtin_constant_p(slen) && (slen < bos)) {
-        return __builtin_strchr(s, c);
-    }
-
-    return __strchr_chk(s, c, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* _Nonnull s, int c) {
-    size_t bos = __bos(s);
-
-    // Compiler doesn't know destination size. Don't call __strrchr_chk
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin_strrchr(s, c);
-    }
-
-    size_t slen = __builtin_strlen(s);
-    if (__builtin_constant_p(slen) && (slen < bos)) {
-        return __builtin_strrchr(s, c);
-    }
-
-    return __strrchr_chk(s, c, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/string.h>
+#endif
 
 /* Const-correct overloads. Placed after FORTIFY so we call those functions, if possible. */
 #if defined(__cplusplus) && defined(__clang__)
@@ -608,87 +145,83 @@
 #define __prefer_this_overload __enable_if(true, "preferred overload") __enable_if(true, "")
 extern "C++" {
 inline __always_inline
-void* __bionic_memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) {
+void* __bionic_memchr(const void* const s __pass_object_size, int c, size_t n) {
     return memchr(s, c, n);
 }
 
 inline __always_inline
-const void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
+const void* memchr(const void* const s __pass_object_size, int c, size_t n)
         __prefer_this_overload {
     return __bionic_memchr(s, c, n);
 }
 
 inline __always_inline
-void* memchr(void* const _Nonnull s __pass_object_size, int c, size_t n) __prefer_this_overload {
+void* memchr(void* const s __pass_object_size, int c, size_t n) __prefer_this_overload {
     return __bionic_memchr(s, c, n);
 }
 
 inline __always_inline
-char* __bionic_strchr(const char* const _Nonnull s __pass_object_size, int c) {
+char* __bionic_strchr(const char* const s __pass_object_size, int c) {
     return strchr(s, c);
 }
 
 inline __always_inline
-const char* strchr(const char* const _Nonnull s __pass_object_size, int c)
+const char* strchr(const char* const s __pass_object_size, int c)
         __prefer_this_overload {
     return __bionic_strchr(s, c);
 }
 
 inline __always_inline
-char* strchr(char* const _Nonnull s __pass_object_size, int c)
+char* strchr(char* const s __pass_object_size, int c)
         __prefer_this_overload {
     return __bionic_strchr(s, c);
 }
 
 inline __always_inline
-char* __bionic_strrchr(const char* const _Nonnull s __pass_object_size, int c) {
+char* __bionic_strrchr(const char* const s __pass_object_size, int c) {
     return strrchr(s, c);
 }
 
 inline __always_inline
-const char* strrchr(const char* const _Nonnull s __pass_object_size, int c) __prefer_this_overload {
+const char* strrchr(const char* const s __pass_object_size, int c) __prefer_this_overload {
     return __bionic_strrchr(s, c);
 }
 
 inline __always_inline
-char* strrchr(char* const _Nonnull s __pass_object_size, int c) __prefer_this_overload {
+char* strrchr(char* const s __pass_object_size, int c) __prefer_this_overload {
     return __bionic_strrchr(s, c);
 }
 
 /* Functions with no FORTIFY counterpart. */
 inline __always_inline
-char* __bionic_strstr(const char* _Nonnull h, const char* _Nonnull n) { return strstr(h, n); }
+char* __bionic_strstr(const char* h, const char* n) { return strstr(h, n); }
 
 inline __always_inline
-const char* strstr(const char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+const char* strstr(const char* h, const char* n) __prefer_this_overload {
     return __bionic_strstr(h, n);
 }
 
 inline __always_inline
-char* strstr(char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+char* strstr(char* h, const char* n) __prefer_this_overload {
     return __bionic_strstr(h, n);
 }
 
 inline __always_inline
-char* __bionic_strpbrk(const char* _Nonnull h, const char* _Nonnull n) { return strpbrk(h, n); }
+char* __bionic_strpbrk(const char* h, const char* n) { return strpbrk(h, n); }
 
 inline __always_inline
-char* strpbrk(char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+char* strpbrk(char* h, const char* n) __prefer_this_overload {
     return __bionic_strpbrk(h, n);
 }
 
 inline __always_inline
-const char* strpbrk(const char* _Nonnull h, const char* _Nonnull n) __prefer_this_overload {
+const char* strpbrk(const char* h, const char* n) __prefer_this_overload {
     return __bionic_strpbrk(h, n);
 }
 }
 #undef __prefer_this_overload
 #endif
 
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
 __END_DECLS
 
 #endif /* _STRING_H */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index dd5b345..9541520 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -111,39 +111,6 @@
 #define __unused __attribute__((__unused__))
 #define __used __attribute__((__used__))
 
-/*
- * _Nonnull is similar to the nonnull attribute in that it will instruct
- * compilers to warn the user if it can prove that a null argument is being
- * passed. Unlike the nonnull attribute, this annotation indicated that a value
- * *should not* be null, not that it *cannot* be null, or even that the behavior
- * is undefined. The important distinction is that the optimizer will perform
- * surprising optimizations like the following:
- *
- *     void foo(void*) __attribute__(nonnull, 1);
- *
- *     int bar(int* p) {
- *       foo(p);
- *
- *       // The following null check will be elided because nonnull attribute
- *       // means that, since we call foo with p, p can be assumed to not be
- *       // null. Thus this will crash if we are called with a null pointer.
- *       if (p != NULL) {
- *         return *p;
- *       }
- *       return 0;
- *     }
- *
- *     int main() {
- *       return bar(NULL);
- *     }
- *
- * http://clang.llvm.org/docs/AttributeReference.html#nonnull
- */
-#if !(defined(__clang__) && __has_feature(nullability))
-#define _Nonnull
-#define _Nullable
-#endif
-
 #define __printflike(x, y) __attribute__((__format__(printf, x, y)))
 #define __scanflike(x, y) __attribute__((__format__(scanf, x, y)))
 
@@ -185,11 +152,16 @@
 #  define __warnattr(msg) __attribute__((deprecated(msg)))
 #  define __warnattr_real(msg) __attribute__((deprecated(msg)))
 #  define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
+#  define __clang_error_if(cond, msg) __attribute__((diagnose_if(cond, msg, "error")))
+#  define __clang_warning_if(cond, msg) __attribute__((diagnose_if(cond, msg, "warning")))
 #else
 #  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. */
+/* diagnose_if doesn't exist either, but it's often tagged on non-clang-specific functions */
+#  define __clang_error_if(cond, msg)
+#  define __clang_warning_if(cond, msg)
 
 /* errordecls really don't work as well in clang as they do in GCC. */
 #  define __errordecl(name, msg) extern void name(void) __errorattr(msg)
@@ -309,6 +281,11 @@
 #define __pass_object_size __pass_object_size_n(__bos_level)
 #define __pass_object_size0 __pass_object_size_n(0)
 
+/* FIXME: This should be __BIONIC_FORTIFY, but we don't enable FORTIFY in -O0. */
+#if (defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
+#  define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
+#endif
+
 /*
  * Used to support clangisms with FORTIFY. Because these change how symbols are
  * emitted, we need to ensure that bionic itself is built fortified. But lots
diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h
index 79f9490..1e4d464 100644
--- a/libc/include/sys/signalfd.h
+++ b/libc/include/sys/signalfd.h
@@ -36,7 +36,7 @@
 
 __BEGIN_DECLS
 
-int signalfd(int fd, const sigset_t* _Nonnull mask, int flags) __INTRODUCED_IN(18);
+int signalfd(int fd, const sigset_t* mask, int flags) __INTRODUCED_IN(18);
 
 __END_DECLS
 
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 2dc54aa..6875d7f 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -325,140 +325,9 @@
 __socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*,
         socklen_t*) __overloadable __RENAME_CLANG(recvfrom);
 
-extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
-        socklen_t) __INTRODUCED_IN(26);
-ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
-        socklen_t*) __INTRODUCED_IN(21);
-
-#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* 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 (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);
-  }
-
-  if (__builtin_constant_p(len) && (len <= bos)) {
-    return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
-  }
-
-  if (__builtin_constant_p(len) && (len > bos)) {
-    __recvfrom_error();
-  }
-
-  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 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 */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/socket.h>
+#endif
 
 #undef __socketcall
 
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 47ff5c4..b8e3cb1 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -167,51 +167,9 @@
 int mknod(const char*, mode_t, dev_t);
 mode_t umask(mode_t) __overloadable __RENAME_CLANG(umask);
 
-mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
-
-#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 (__builtin_constant_p(mode)) {
-    if ((mode & 0777) != mode) {
-      __umask_invalid_mode();
-    }
-    return __umask_real(mode);
-  }
-  return __umask_chk(mode);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#endif /* defined(__clang__) */
-#undef __umask_invalid_mode_str
-
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stat.h>
+#endif
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
 int mkfifo(const char*, mode_t) __INTRODUCED_IN(21);
diff --git a/libc/include/sys/statvfs.h b/libc/include/sys/statvfs.h
index af1b9c0..0f421a4 100644
--- a/libc/include/sys/statvfs.h
+++ b/libc/include/sys/statvfs.h
@@ -59,12 +59,10 @@
 #define ST_NODIRATIME  0x0800
 #define ST_RELATIME    0x1000
 
-int statvfs(const char* __restrict _Nonnull, struct statvfs* __restrict _Nonnull)
-  __INTRODUCED_IN(19);
-int statvfs64(const char* __restrict _Nonnull, struct statvfs64* __restrict _Nonnull)
-  __INTRODUCED_IN(21);
-int fstatvfs(int, struct statvfs* _Nonnull) __INTRODUCED_IN(19);
-int fstatvfs64(int, struct statvfs64* _Nonnull) __INTRODUCED_IN(21);
+int statvfs(const char*, struct statvfs*) __INTRODUCED_IN(19);
+int statvfs64(const char*, struct statvfs64*) __INTRODUCED_IN(21);
+int fstatvfs(int, struct statvfs*) __INTRODUCED_IN(19);
+int fstatvfs64(int, struct statvfs64*) __INTRODUCED_IN(21);
 
 __END_DECLS
 
diff --git a/libc/include/sys/swap.h b/libc/include/sys/swap.h
index 3444736..e79af97 100644
--- a/libc/include/sys/swap.h
+++ b/libc/include/sys/swap.h
@@ -38,8 +38,8 @@
 #define SWAP_FLAG_PRIO_MASK 0x7fff
 #define SWAP_FLAG_PRIO_SHIFT 0
 
-int swapon(const char* _Nonnull, int) __INTRODUCED_IN(19);
-int swapoff(const char* _Nonnull) __INTRODUCED_IN(19);
+int swapon(const char*, int) __INTRODUCED_IN(19);
+int swapoff(const char*) __INTRODUCED_IN(19);
 
 __END_DECLS
 
diff --git a/libc/include/sys/vfs.h b/libc/include/sys/vfs.h
index 1231eb1..3078683 100644
--- a/libc/include/sys/vfs.h
+++ b/libc/include/sys/vfs.h
@@ -137,10 +137,10 @@
 #define XENIX_SUPER_MAGIC     0x012FF7B4
 #define XFS_SUPER_MAGIC       0x58465342
 
-int statfs(const char* _Nonnull, struct statfs* _Nonnull);
-int statfs64(const char* _Nonnull, struct statfs64* _Nonnull) __INTRODUCED_IN(21);
-int fstatfs(int, struct statfs* _Nonnull);
-int fstatfs64(int, struct statfs64* _Nonnull) __INTRODUCED_IN(21);
+int statfs(const char*, struct statfs*);
+int statfs64(const char*, struct statfs64*) __INTRODUCED_IN(21);
+int fstatfs(int, struct statfs*);
+int fstatfs64(int, struct statfs64*) __INTRODUCED_IN(21);
 
 __END_DECLS
 
diff --git a/libc/include/syslog.h b/libc/include/syslog.h
index 4b7eecb..8000f03 100644
--- a/libc/include/syslog.h
+++ b/libc/include/syslog.h
@@ -86,14 +86,10 @@
 #define LOG_PERROR 0x20
 
 void closelog(void);
-void openlog(const char* _Nullable, int, int);
+void openlog(const char*, int, int);
 int setlogmask(int);
-void syslog(int, const char* _Nonnull, ...) __printflike(2, 3);
-#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__)
-void vsyslog(int, const char* _Nonnull, va_list) __printflike(2, 0);
-#else /* defined(__mips__) || defined(__i386__) */
-void vsyslog(int, const char* _Nonnull, va_list _Nonnull) __printflike(2, 0);
-#endif
+void syslog(int, const char*, ...) __printflike(2, 3);
+void vsyslog(int, const char*, va_list) __printflike(2, 0);
 
 __END_DECLS
 
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index 818acb1..ac0cf1d 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -43,12 +43,10 @@
 #define __STD_UTF_16__ 1
 #define __STD_UTF_32__ 1
 
-size_t c16rtomb(char* __restrict, char16_t, mbstate_t* __restrict) __INTRODUCED_IN(21);
-size_t c32rtomb(char* __restrict, char32_t, mbstate_t* __restrict) __INTRODUCED_IN(21);
-size_t mbrtoc16(char16_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict)
-  __INTRODUCED_IN(21);
-size_t mbrtoc32(char32_t* __restrict, const char* __restrict, size_t, mbstate_t* __restrict)
-  __INTRODUCED_IN(21);
+size_t c16rtomb(char*, char16_t, mbstate_t*) __INTRODUCED_IN(21);
+size_t c32rtomb(char*, char32_t, mbstate_t*) __INTRODUCED_IN(21);
+size_t mbrtoc16(char16_t*, const char*, size_t, mbstate_t*) __INTRODUCED_IN(21);
+size_t mbrtoc32(char32_t*, const char*, size_t, mbstate_t*) __INTRODUCED_IN(21);
 
 __END_DECLS
 
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 8336976..ff77421 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -242,505 +242,13 @@
     } while (_rc == -1 && errno == EINTR); \
     _rc; })
 
-/* TODO(unified-headers): Factor out all the FORTIFY features. */
-char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
-
-ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
-
-ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
-
-ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
-
-ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
-  __INTRODUCED_IN(12);
-
-ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
-ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
-ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-
 int getdomainname(char*, size_t) __INTRODUCED_IN(26);
 int setdomainname(const char*, size_t) __INTRODUCED_IN(26);
 
-#if defined(__BIONIC_FORTIFY)
-
-#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
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/unistd.h>
 #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);
-
-    /*
-     * 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 (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE || buf == NULL) {
-        return __call_bypassing_fortify(getcwd)(buf, size);
-    }
-
-    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);
-    }
-
-    if (__builtin_constant_p(size) && (size > bos)) {
-        __getcwd_dest_size_error();
-    }
-
-    if (__builtin_constant_p(size) && (size <= bos)) {
-        return __getcwd_real(buf, size);
-    }
-
-    return __getcwd_chk(buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#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 (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
-        __PREAD_PREFIX(count_toobig_error)();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __PREAD_PREFIX(real)(fd, buf, count, offset);
-    }
-
-    if (__builtin_constant_p(count) && (count > bos)) {
-        __PREAD_PREFIX(dest_size_error)();
-    }
-
-    if (__builtin_constant_p(count) && (count <= bos)) {
-        return __PREAD_PREFIX(real)(fd, buf, count, offset);
-    }
-
-    return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
-    size_t bos = __bos0(buf);
-
-    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
-        __pread64_count_toobig_error();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __pread64_real(fd, buf, count, offset);
-    }
-
-    if (__builtin_constant_p(count) && (count > bos)) {
-        __pread64_dest_size_error();
-    }
-
-    if (__builtin_constant_p(count) && (count <= bos)) {
-        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_FORTIFY_INLINE
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
-    size_t bos = __bos0(buf);
-
-    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
-        __PWRITE_PREFIX(count_toobig_error)();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
-    }
-
-    if (__builtin_constant_p(count) && (count > bos)) {
-        __PWRITE_PREFIX(dest_size_error)();
-    }
-
-    if (__builtin_constant_p(count) && (count <= bos)) {
-        return __PWRITE_PREFIX(real)(fd, buf, count, offset);
-    }
-
-    return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
-    size_t bos = __bos0(buf);
-
-    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
-        __pwrite64_count_toobig_error();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __pwrite64_real(fd, buf, count, offset);
-    }
-
-    if (__builtin_constant_p(count) && (count > bos)) {
-        __pwrite64_dest_size_error();
-    }
-
-    if (__builtin_constant_p(count) && (count <= bos)) {
-        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_FORTIFY_INLINE
-ssize_t read(int fd, void* buf, size_t count) {
-    size_t bos = __bos0(buf);
-
-    if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
-        __read_count_toobig_error();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __read_real(fd, buf, count);
-    }
-
-    if (__builtin_constant_p(count) && (count > bos)) {
-        __read_dest_size_error();
-    }
-
-    if (__builtin_constant_p(count) && (count <= bos)) {
-        return __read_real(fd, buf, count);
-    }
-
-    return __read_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-ssize_t write(int fd, const void* buf, size_t count) {
-    size_t bos = __bos0(buf);
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __write_real(fd, buf, count);
-    }
-
-    if (__builtin_constant_p(count) && (count > bos)) {
-        __write_dest_size_error();
-    }
-
-    if (__builtin_constant_p(count) && (count <= bos)) {
-        return __write_real(fd, buf, count);
-    }
-
-    return __write_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-ssize_t readlink(const char* path, char* buf, size_t size) {
-    size_t bos = __bos(buf);
-
-    if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
-        __readlink_size_toobig_error();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __readlink_real(path, buf, size);
-    }
-
-    if (__builtin_constant_p(size) && (size > bos)) {
-        __readlink_dest_size_error();
-    }
-
-    if (__builtin_constant_p(size) && (size <= bos)) {
-        return __readlink_real(path, buf, size);
-    }
-
-    return __readlink_chk(path, buf, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
-    size_t bos = __bos(buf);
-
-    if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
-        __readlinkat_size_toobig_error();
-    }
-
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __readlinkat_real(dirfd, path, buf, size);
-    }
-
-    if (__builtin_constant_p(size) && (size > bos)) {
-        __readlinkat_dest_size_error();
-    }
-
-    if (__builtin_constant_p(size) && (size <= bos)) {
-        return __readlinkat_real(dirfd, path, buf, size);
-    }
-
-    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
 
 #endif /* _UNISTD_H_ */
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index a86c8a9..4494cb0 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -42,11 +42,6 @@
 
 __BEGIN_DECLS
 
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wnullability-completeness"
-#endif
-
 wint_t            btowc(int);
 int               fwprintf(FILE *, const wchar_t *, ...);
 int               fwscanf(FILE *, const wchar_t *, ...);
@@ -125,9 +120,9 @@
 unsigned long long wcstoull_l(const wchar_t*, wchar_t**, int, locale_t) __INTRODUCED_IN(21);
 long double wcstold_l(const wchar_t*, wchar_t**, locale_t) __INTRODUCED_IN(21);
 
-int wcscoll_l(const wchar_t* _Nonnull, const wchar_t* _Nonnull, locale_t) __attribute_pure__
+int wcscoll_l(const wchar_t*, const wchar_t*, locale_t) __attribute_pure__
     __INTRODUCED_IN(21);
-size_t wcsxfrm_l(wchar_t*, const wchar_t* _Nonnull, size_t, locale_t) __INTRODUCED_IN(21);
+size_t wcsxfrm_l(wchar_t*, const wchar_t*, size_t, locale_t) __INTRODUCED_IN(21);
 #else
 // Implemented as static inlines before 21.
 #endif
@@ -139,10 +134,6 @@
 wchar_t* wcsdup(const wchar_t*);
 size_t wcsnlen(const wchar_t*, size_t);
 
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
 __END_DECLS
 
 #endif /* _WCHAR_H_ */
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 45ca9eb..06856c8 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -343,6 +343,7 @@
     fdatasync;
     fdopen;
     fdopendir;
+    fdprintf; # arm x86 mips versioned=28
     feof;
     feof_unlocked; # introduced=23
     ferror;
@@ -1105,6 +1106,7 @@
     vdprintf; # introduced=21
     verr;
     verrx;
+    vfdprintf; # arm x86 mips versioned=28
     vfork;
     vfprintf;
     vfscanf;
@@ -1318,6 +1320,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
@@ -1512,7 +1516,6 @@
     dlmalloc_inspect_all; # arm x86 mips
     dlmalloc_trim; # arm x86 mips
     dlmalloc_usable_size; # arm x86 mips
-    fdprintf; # arm x86 mips
     free_malloc_leak_info;
     ftime; # arm x86 mips
     get_malloc_leak_info;
@@ -1534,7 +1537,6 @@
     strtotimeval; # arm x86 mips
     sysv_signal; # arm x86 mips
     tkill; # arm x86 mips
-    vfdprintf; # arm x86 mips
     wait3; # arm x86 mips
     wcswcs; # arm x86 mips
 } LIBC_P;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index ed1e82c..50e4390 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1240,6 +1240,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 8b1d6de..3e4d36e 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -345,6 +345,7 @@
     fdatasync;
     fdopen;
     fdopendir;
+    fdprintf; # arm x86 mips versioned=28
     feof;
     feof_unlocked; # introduced=23
     ferror;
@@ -1130,6 +1131,7 @@
     vdprintf; # introduced=21
     verr;
     verrx;
+    vfdprintf; # arm x86 mips versioned=28
     vfork;
     vfprintf;
     vfscanf;
@@ -1343,6 +1345,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
@@ -1538,7 +1542,6 @@
     dlmalloc_inspect_all; # arm x86 mips
     dlmalloc_trim; # arm x86 mips
     dlmalloc_usable_size; # arm x86 mips
-    fdprintf; # arm x86 mips
     free_malloc_leak_info;
     ftime; # arm x86 mips
     get_malloc_leak_info;
@@ -1560,7 +1563,6 @@
     strtotimeval; # arm x86 mips
     sysv_signal; # arm x86 mips
     tkill; # arm x86 mips
-    vfdprintf; # arm x86 mips
     wait3; # arm x86 mips
     wcswcs; # arm x86 mips
 } LIBC_P;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 256ca9e..3fa7c9d 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -341,6 +341,7 @@
     fdatasync;
     fdopen;
     fdopendir;
+    fdprintf; # arm x86 mips versioned=28
     feof;
     feof_unlocked; # introduced=23
     ferror;
@@ -1103,6 +1104,7 @@
     vdprintf; # introduced=21
     verr;
     verrx;
+    vfdprintf; # arm x86 mips versioned=28
     vfork;
     vfprintf;
     vfscanf;
@@ -1302,6 +1304,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
@@ -1354,7 +1358,6 @@
     dlmalloc_inspect_all; # arm x86 mips
     dlmalloc_trim; # arm x86 mips
     dlmalloc_usable_size; # arm x86 mips
-    fdprintf; # arm x86 mips
     free_malloc_leak_info;
     ftime; # arm x86 mips
     get_malloc_leak_info;
@@ -1375,7 +1378,6 @@
     strtotimeval; # arm x86 mips
     sysv_signal; # arm x86 mips
     tkill; # arm x86 mips
-    vfdprintf; # arm x86 mips
     wait3; # arm x86 mips
     wcswcs; # arm x86 mips
 } LIBC_P;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index ed1e82c..50e4390 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1240,6 +1240,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 2ebc86c..bd74fbe 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -339,6 +339,7 @@
     fdatasync;
     fdopen;
     fdopendir;
+    fdprintf; # arm x86 mips versioned=28
     feof;
     feof_unlocked; # introduced=23
     ferror;
@@ -1101,6 +1102,7 @@
     vdprintf; # introduced=21
     verr;
     verrx;
+    vfdprintf; # arm x86 mips versioned=28
     vfork;
     vfprintf;
     vfscanf;
@@ -1300,6 +1302,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
@@ -1353,7 +1357,6 @@
     dlmalloc_inspect_all; # arm x86 mips
     dlmalloc_trim; # arm x86 mips
     dlmalloc_usable_size; # arm x86 mips
-    fdprintf; # arm x86 mips
     free_malloc_leak_info;
     ftime; # arm x86 mips
     get_malloc_leak_info;
@@ -1374,7 +1377,6 @@
     strtotimeval; # arm x86 mips
     sysv_signal; # arm x86 mips
     tkill; # arm x86 mips
-    vfdprintf; # arm x86 mips
     wait3; # arm x86 mips
     wcswcs; # arm x86 mips
 } LIBC_P;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index ed1e82c..50e4390 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1240,6 +1240,8 @@
 
 LIBC_P {
   global:
+    __freading; # future
+    __fwriting; # future
     getlogin_r; # future
 } LIBC_O;
 
diff --git a/libc/libstdc++.arm.map b/libc/libstdc++.arm.map
index b6b269d..8ee5863 100644
--- a/libc/libstdc++.arm.map
+++ b/libc/libstdc++.arm.map
@@ -2,14 +2,14 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znaj; # arm x86 mips
-    _ZnajRKSt9nothrow_t; # arm x86 mips
-    _Znwj; # arm x86 mips
-    _ZnwjRKSt9nothrow_t; # arm x86 mips
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znaj; # arm x86 mips weak
+    _ZnajRKSt9nothrow_t; # arm x86 mips weak
+    _Znwj; # arm x86 mips weak
+    _ZnwjRKSt9nothrow_t; # arm x86 mips weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/libstdc++.arm64.map b/libc/libstdc++.arm64.map
index d0433c9..cd4f3c3 100644
--- a/libc/libstdc++.arm64.map
+++ b/libc/libstdc++.arm64.map
@@ -2,14 +2,14 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znam; # arm64 x86_64 mips64
-    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
-    _Znwm; # arm64 x86_64 mips64
-    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znam; # arm64 x86_64 mips64 weak
+    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+    _Znwm; # arm64 x86_64 mips64 weak
+    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/libstdc++.map.txt b/libc/libstdc++.map.txt
index 32d5d49..0a242d5 100644
--- a/libc/libstdc++.map.txt
+++ b/libc/libstdc++.map.txt
@@ -1,18 +1,18 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znaj; # arm x86 mips
-    _ZnajRKSt9nothrow_t; # arm x86 mips
-    _Znam; # arm64 x86_64 mips64
-    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
-    _Znwj; # arm x86 mips
-    _ZnwjRKSt9nothrow_t; # arm x86 mips
-    _Znwm; # arm64 x86_64 mips64
-    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znaj; # arm x86 mips weak
+    _ZnajRKSt9nothrow_t; # arm x86 mips weak
+    _Znam; # arm64 x86_64 mips64 weak
+    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+    _Znwj; # arm x86 mips weak
+    _ZnwjRKSt9nothrow_t; # arm x86 mips weak
+    _Znwm; # arm64 x86_64 mips64 weak
+    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/libstdc++.mips.map b/libc/libstdc++.mips.map
index b6b269d..8ee5863 100644
--- a/libc/libstdc++.mips.map
+++ b/libc/libstdc++.mips.map
@@ -2,14 +2,14 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znaj; # arm x86 mips
-    _ZnajRKSt9nothrow_t; # arm x86 mips
-    _Znwj; # arm x86 mips
-    _ZnwjRKSt9nothrow_t; # arm x86 mips
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znaj; # arm x86 mips weak
+    _ZnajRKSt9nothrow_t; # arm x86 mips weak
+    _Znwj; # arm x86 mips weak
+    _ZnwjRKSt9nothrow_t; # arm x86 mips weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/libstdc++.mips64.map b/libc/libstdc++.mips64.map
index d0433c9..cd4f3c3 100644
--- a/libc/libstdc++.mips64.map
+++ b/libc/libstdc++.mips64.map
@@ -2,14 +2,14 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znam; # arm64 x86_64 mips64
-    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
-    _Znwm; # arm64 x86_64 mips64
-    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znam; # arm64 x86_64 mips64 weak
+    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+    _Znwm; # arm64 x86_64 mips64 weak
+    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/libstdc++.x86.map b/libc/libstdc++.x86.map
index b6b269d..8ee5863 100644
--- a/libc/libstdc++.x86.map
+++ b/libc/libstdc++.x86.map
@@ -2,14 +2,14 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znaj; # arm x86 mips
-    _ZnajRKSt9nothrow_t; # arm x86 mips
-    _Znwj; # arm x86 mips
-    _ZnwjRKSt9nothrow_t; # arm x86 mips
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znaj; # arm x86 mips weak
+    _ZnajRKSt9nothrow_t; # arm x86 mips weak
+    _Znwj; # arm x86 mips weak
+    _ZnwjRKSt9nothrow_t; # arm x86 mips weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/libstdc++.x86_64.map b/libc/libstdc++.x86_64.map
index d0433c9..cd4f3c3 100644
--- a/libc/libstdc++.x86_64.map
+++ b/libc/libstdc++.x86_64.map
@@ -2,14 +2,14 @@
 LIBC_O {
   global:
     _ZSt7nothrow; # var
-    _ZdaPv;
-    _ZdaPvRKSt9nothrow_t;
-    _ZdlPv;
-    _ZdlPvRKSt9nothrow_t;
-    _Znam; # arm64 x86_64 mips64
-    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64
-    _Znwm; # arm64 x86_64 mips64
-    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64
+    _ZdaPv; # weak
+    _ZdaPvRKSt9nothrow_t; # weak
+    _ZdlPv; # weak
+    _ZdlPvRKSt9nothrow_t; # weak
+    _Znam; # arm64 x86_64 mips64 weak
+    _ZnamRKSt9nothrow_t; # arm64 x86_64 mips64 weak
+    _Znwm; # arm64 x86_64 mips64 weak
+    _ZnwmRKSt9nothrow_t; # arm64 x86_64 mips64 weak
     __cxa_guard_abort;
     __cxa_guard_acquire;
     __cxa_guard_release;
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index afb02ca..bf6a8f8 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -127,10 +127,11 @@
 // Values for `__sFILE::_flags`.
 #define __SLBF 0x0001  // Line buffered.
 #define __SNBF 0x0002  // Unbuffered.
-// RD and WR are never simultaneously asserted: use _SRW instead.
-#define __SRD  0x0004  // OK to read.
-#define __SWR  0x0008  // OK to write.
-#define __SRW  0x0010  // Open for reading & writing.
+// __SRD and __SWR are mutually exclusive because they indicate what we did last.
+// If you want to know whether we were opened read-write, check __SRW instead.
+#define __SRD  0x0004  // Last operation was read.
+#define __SWR  0x0008  // Last operation was write.
+#define __SRW  0x0010  // Was opened for reading & writing.
 #define __SEOF 0x0020  // Found EOF.
 #define __SERR 0x0040  // Found error.
 #define __SMBF 0x0080  // `_buf` is from malloc.
@@ -201,10 +202,10 @@
 int	__swhatbuf(FILE *, size_t *, int *);
 wint_t __fgetwc_unlock(FILE *);
 wint_t	__ungetwc(wint_t, FILE *);
-int	__vfprintf(FILE *, const char *, __va_list);
-int	__svfscanf(FILE * __restrict, const char * __restrict, __va_list);
-int	__vfwprintf(FILE * __restrict, const wchar_t * __restrict, __va_list);
-int	__vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list);
+int	__vfprintf(FILE *, const char *, va_list);
+int	__svfscanf(FILE *, const char *, va_list);
+int	__vfwprintf(FILE *, const wchar_t *, va_list);
+int	__vfwscanf(FILE *, const wchar_t *, va_list);
 
 /*
  * Return true if the given FILE cannot be written now.
diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp
index ebc705c..8cf4f4b 100644
--- a/libc/stdio/stdio_ext.cpp
+++ b/libc/stdio/stdio_ext.cpp
@@ -39,17 +39,13 @@
   return fp->_bf._size;
 }
 
-/* For a _SRW stream, we don't know whether we last read or wrote.
 int __freading(FILE* fp) {
-  return (fp->_flags & _SRD) != 0 || ...;
+  return (fp->_flags & __SRD) != 0;
 }
-*/
 
-/* For a _SRW stream, we don't know whether we last read or wrote.
-int __fwriting(FILE*) {
-  return (fp->_flags & _SWR) != 0 || ...;
+int __fwriting(FILE* fp) {
+  return (fp->_flags & __SWR) != 0;
 }
-*/
 
 int __freadable(FILE* fp) {
   return (fp->_flags & (__SRD|__SRW)) != 0;
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/realpath.c b/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
index 914ecc9..c4bd953 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
@@ -48,7 +48,7 @@
  * in which case the path which caused trouble is left in (resolved).
  */
 char *
-realpath(const char * __restrict path, char * __restrict resolved) __overloadable
+realpath(const char * __restrict path, char * __restrict resolved)
 {
 	struct stat sb;
 	char *p, *q, *s;
diff --git a/linker/Android.bp b/linker/Android.bp
index efd91ac..fda7eb5 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -101,6 +101,12 @@
         "-Werror",
     ],
 
+    product_variables: {
+        debuggable: {
+            cppflags: ["-DUSE_LD_CONFIG_FILE"],
+        },
+    },
+
     cppflags: ["-Wold-style-cast"],
 
     // we are going to link libc++_static manually because
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8e7a141..a212624 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -558,9 +558,10 @@
 
   static LoadTask* create(const char* name,
                           soinfo* needed_by,
+                          android_namespace_t* start_from,
                           std::unordered_map<const soinfo*, ElfReader>* readers_map) {
     LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
-    return new (ptr) LoadTask(name, needed_by, readers_map);
+    return new (ptr) LoadTask(name, needed_by, start_from, readers_map);
   }
 
   const char* get_name() const {
@@ -612,6 +613,11 @@
     is_dt_needed_ = is_dt_needed;
   }
 
+  // returns the namespace from where we need to start loading this.
+  const android_namespace_t* get_start_from() const {
+    return start_from_;
+  }
+
   const ElfReader& get_elf_reader() const {
     CHECK(si_ != nullptr);
     return (*elf_readers_map_)[si_];
@@ -650,10 +656,11 @@
  private:
   LoadTask(const char* name,
            soinfo* needed_by,
+           android_namespace_t* start_from,
            std::unordered_map<const soinfo*, ElfReader>* readers_map)
     : name_(name), needed_by_(needed_by), si_(nullptr),
       fd_(-1), close_fd_(false), file_offset_(0), elf_readers_map_(readers_map),
-      is_dt_needed_(false) {}
+      is_dt_needed_(false), start_from_(start_from) {}
 
   ~LoadTask() {
     if (fd_ != -1 && close_fd_) {
@@ -672,6 +679,7 @@
   // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
   bool is_dt_needed_;
   // END OF WORKAROUND
+  const android_namespace_t* const start_from_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
 };
@@ -1041,7 +1049,7 @@
                         ZipArchiveCache* zip_archive_cache,
                         const char* name, soinfo *needed_by,
                         off64_t* file_offset, std::string* realpath) {
-  TRACE("[ opening %s ]", name);
+  TRACE("[ opening %s at namespace %s]", name, ns->get_name());
 
   // If the name contains a slash, we should attempt to open it directly and not search the paths.
   if (strchr(name, '/') != nullptr) {
@@ -1273,7 +1281,7 @@
   }
 
   for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
-    load_tasks->push_back(LoadTask::create(name, si, task->get_readers_map()));
+    load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
   });
 
   return true;
@@ -1368,8 +1376,7 @@
 }
 
 static bool find_library_in_linked_namespace(const android_namespace_link_t& namespace_link,
-                                             LoadTask* task,
-                                             int rtld_flags) {
+                                             LoadTask* task) {
   android_namespace_t* ns = namespace_link.linked_namespace();
 
   soinfo* candidate;
@@ -1394,29 +1401,10 @@
     return true;
   }
 
-  // try to load the library - once namespace boundary is crossed
-  // we need to load a library within separate load_group
-  // to avoid using symbols from foreign namespace while.
-  //
-  // All symbols during relocation should be resolved within a
-  // namespace to preserve library locality to a namespace.
-  const char* name = task->get_name();
-  if (find_libraries(ns,
-                     task->get_needed_by(),
-                     &name,
-                     1,
-                     &candidate,
-                     nullptr /* ld_preloads */,
-                     0 /* ld_preload_count*/,
-                     rtld_flags,
-                     nullptr /* extinfo*/,
-                     false /* add_as_children */,
-                     false /* search_linked_namespaces */)) {
-    task->set_soinfo(candidate);
-    return true;
-  }
-
-  return false;
+  // returning true with empty soinfo means that the library is okay to be
+  // loaded in the namespace buy has not yet been loaded there before.
+  task->set_soinfo(nullptr);
+  return true;
 }
 
 static bool find_library_internal(android_namespace_t* ns,
@@ -1445,9 +1433,24 @@
     // if a library was not found - look into linked namespaces
     for (auto& linked_namespace : ns->linked_namespaces()) {
       if (find_library_in_linked_namespace(linked_namespace,
-                                           task,
-                                           rtld_flags)) {
-        return true;
+                                           task)) {
+        if (task->get_soinfo() == nullptr) {
+          // try to load the library - once namespace boundary is crossed
+          // we need to load a library within separate load_group
+          // to avoid using symbols from foreign namespace while.
+          //
+          // However, actual linking is deferred until when the global group
+          // is fully identified and is applied to all namespaces.
+          // Otherwise, the libs in the linked namespace won't get symbols from
+          // the global group.
+          if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) {
+            return true;
+          }
+          // lib was not found in the namespace. Try next linked namespace.
+        } else {
+          // lib is already loaded
+          return true;
+        }
       }
     }
   }
@@ -1458,44 +1461,6 @@
 static void soinfo_unload(soinfo* si);
 static void soinfo_unload(soinfo* soinfos[], size_t count);
 
-// TODO: this is slightly unusual way to construct
-// the global group for relocation. Not every RTLD_GLOBAL
-// library is included in this group for backwards-compatibility
-// reasons.
-//
-// This group consists of the main executable, LD_PRELOADs
-// and libraries with the DF_1_GLOBAL flag set.
-static soinfo_list_t make_global_group(android_namespace_t* ns) {
-  soinfo_list_t global_group;
-  ns->soinfo_list().for_each([&](soinfo* si) {
-    if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
-      global_group.push_back(si);
-    }
-  });
-
-  return global_group;
-}
-
-// This function provides a list of libraries to be shared
-// by the namespace. For the default namespace this is the global
-// group (see make_global_group). For all others this is a group
-// of RTLD_GLOBAL libraries (which includes the global group from
-// the default namespace).
-static soinfo_list_t get_shared_group(android_namespace_t* ns) {
-  if (ns == &g_default_namespace) {
-    return make_global_group(ns);
-  }
-
-  soinfo_list_t shared_group;
-  ns->soinfo_list().for_each([&](soinfo* si) {
-    if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
-      shared_group.push_back(si);
-    }
-  });
-
-  return shared_group;
-}
-
 static void shuffle(std::vector<LoadTask*>* v) {
   for (size_t i = 0, size = v->size(); i < size; ++i) {
     size_t n = size - i;
@@ -1518,19 +1483,17 @@
                     int rtld_flags,
                     const android_dlextinfo* extinfo,
                     bool add_as_children,
-                    bool search_linked_namespaces) {
+                    bool search_linked_namespaces,
+                    std::unordered_map<const soinfo*, ElfReader>& readers_map,
+                    std::vector<android_namespace_t*>* namespaces) {
   // Step 0: prepare.
   LoadTaskList load_tasks;
-  std::unordered_map<const soinfo*, ElfReader> readers_map;
 
   for (size_t i = 0; i < library_names_count; ++i) {
     const char* name = library_names[i];
-    load_tasks.push_back(LoadTask::create(name, start_with, &readers_map));
+    load_tasks.push_back(LoadTask::create(name, start_with, ns, &readers_map));
   }
 
-  // Construct global_group.
-  soinfo_list_t global_group = make_global_group(ns);
-
   // If soinfos array is null allocate one on stack.
   // The array is needed in case of failure; for example
   // when library_names[] = {libone.so, libtwo.so} and libone.so
@@ -1570,7 +1533,12 @@
     task->set_extinfo(is_dt_needed ? nullptr : extinfo);
     task->set_dt_needed(is_dt_needed);
 
-    if (!find_library_internal(ns,
+    // try to find the load.
+    // Note: start from the namespace that is stored in the LoadTask. This namespace
+    // is different from the current namespace when the LoadTask is for a transitive
+    // dependency and the lib that created the LoadTask is not found in the
+    // current namespace but in one of the linked namespace.
+    if (!find_library_internal(const_cast<android_namespace_t*>(task->get_start_from()),
                                task,
                                &zip_archive_cache,
                                &load_tasks,
@@ -1629,18 +1597,61 @@
     }
   }
 
-  // Step 4: Add LD_PRELOADed libraries to the global group for
-  // future runs. There is no need to explicitly add them to
-  // the global group for this run because they are going to
-  // appear in the local group in the correct order.
+  // Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is
+  // determined at step 3.
+
+  // Step 4-1: DF_1_GLOBAL bit is force set for LD_PRELOADed libs because they
+  // must be added to the global group
   if (ld_preloads != nullptr) {
     for (auto&& si : *ld_preloads) {
       si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
     }
   }
 
+  // Step 4-2: Gather all DF_1_GLOBAL libs which were newly loaded during this
+  // run. These will be the new member of the global group
+  soinfo_list_t new_global_group_members;
+  for (auto&& task : load_tasks) {
+    soinfo* si = task->get_soinfo();
+    if (!si->is_linked() && (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+      new_global_group_members.push_back(si);
+    }
+  }
 
-  // Step 5: link libraries.
+  // Step 4-3: Add the new global group members to all the linked namespaces
+  for (auto si : new_global_group_members) {
+    for (auto linked_ns : *namespaces) {
+      if (si->get_primary_namespace() != linked_ns) {
+        linked_ns->add_soinfo(si);
+        si->add_secondary_namespace(linked_ns);
+      }
+    }
+  }
+
+  // Step 5: link libraries that are not destined to this namespace.
+  // Do this by recursively calling find_libraries on the namespace where the lib
+  // was found during Step 1.
+  for (auto&& task : load_tasks) {
+    soinfo* si = task->get_soinfo();
+    if (si->get_primary_namespace() != ns) {
+      const char* name = task->get_name();
+      if (find_libraries(si->get_primary_namespace(), task->get_needed_by(), &name, 1,
+                         nullptr /* soinfos */, nullptr /* ld_preloads */, 0 /* ld_preload_count */,
+                         rtld_flags, nullptr /* extinfo */, false /* add_as_children */,
+                         false /* search_linked_namespaces */, readers_map, namespaces)) {
+        // If this lib is directly needed by one of the libs in this namespace,
+        // then increment the count
+        soinfo* needed_by = task->get_needed_by();
+        if (needed_by != nullptr && needed_by->get_primary_namespace() == ns && si->is_linked()) {
+          si->increment_ref_count();
+        }
+      } else {
+        return false;
+      }
+    }
+  }
+
+  // Step 6: link libraries in this namespace
   soinfo_list_t local_group;
   walk_dependencies_tree(
       (start_with != nullptr && add_as_children) ? &start_with : soinfos,
@@ -1654,6 +1665,7 @@
     }
   });
 
+  soinfo_list_t global_group = ns->get_global_group();
   bool linked = local_group.visit([&](soinfo* si) {
     if (!si->is_linked()) {
       if (!si->link_image(global_group, local_group, extinfo) ||
@@ -1684,6 +1696,9 @@
                             soinfo* needed_by) {
   soinfo* si;
 
+  // readers_map is shared across recursive calls to find_libraries.
+  // However, the map is not shared across different threads.
+  std::unordered_map<const soinfo*, ElfReader> readers_map;
   if (name == nullptr) {
     si = solist_get_somain();
   } else if (!find_libraries(ns,
@@ -1696,7 +1711,8 @@
                              rtld_flags,
                              extinfo,
                              false /* add_as_children */,
-                             true /* search_linked_namespaces */)) {
+                             true /* search_linked_namespaces */,
+                             readers_map)) {
     return nullptr;
   }
 
@@ -2208,7 +2224,7 @@
     }
   } else {
     // If not shared - copy only the shared group
-    add_soinfos_to_namespace(get_shared_group(parent_namespace), ns);
+    add_soinfos_to_namespace(parent_namespace->get_shared_group(), ns);
   }
 
   ns->set_ld_library_paths(std::move(ld_library_paths));
@@ -3413,7 +3429,7 @@
   return true;
 }
 
-static void init_default_namespace_no_config(bool is_asan) {
+static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
   g_default_namespace.set_isolated(false);
   auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
 
@@ -3428,9 +3444,13 @@
   }
 
   g_default_namespace.set_default_library_paths(std::move(ld_default_paths));
+
+  std::vector<android_namespace_t*> namespaces;
+  namespaces.push_back(&g_default_namespace);
+  return namespaces;
 }
 
-void init_default_namespace(const char* executable_path) {
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
   g_default_namespace.set_name("(default)");
 
   soinfo* somain = solist_get_somain();
@@ -3447,14 +3467,24 @@
 
   std::string error_msg;
 
-  if (!Config::read_binary_config(kLdConfigFilePath,
+  const char* config_file = kLdConfigFilePath;
+#ifdef USE_LD_CONFIG_FILE
+  // This is a debugging/testing only feature. Must not be available on
+  // production builds.
+  const char* ld_config_file = getenv("LD_CONFIG_FILE");
+  if (ld_config_file != nullptr && file_exists(ld_config_file)) {
+    config_file = ld_config_file;
+  }
+#endif
+
+  if (!Config::read_binary_config(config_file,
                                   executable_path,
                                   g_is_asan,
                                   &config,
                                   &error_msg)) {
     if (!error_msg.empty()) {
       DL_WARN("error reading config file \"%s\" for \"%s\" (will use default configuration): %s",
-              kLdConfigFilePath,
+              config_file,
               executable_path,
               error_msg.c_str());
     }
@@ -3462,8 +3492,7 @@
   }
 
   if (config == nullptr) {
-    init_default_namespace_no_config(g_is_asan);
-    return;
+    return init_default_namespace_no_config(g_is_asan);
   }
 
   const auto& namespace_configs = config->namespace_configs();
@@ -3514,10 +3543,17 @@
   soinfo* ld_android_so = solist_get_head();
   for (auto it : namespaces) {
     it.second->add_soinfo(ld_android_so);
-    // TODO (dimitry): somain and ld_preloads should probably be added to all of these namespaces too?
+    // somain and ld_preloads are added to these namespaces after LD_PRELOAD libs are linked
   }
 
   set_application_target_sdk_version(config->target_sdk_version());
+
+  std::vector<android_namespace_t*> created_namespaces;
+  created_namespaces.reserve(namespaces.size());
+  for (auto kv : namespaces) {
+    created_namespaces.push_back(kv.second);
+  }
+  return created_namespaces;
 }
 
 // This function finds a namespace exported in ld.config.txt by its name.
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 3f7795b..54593e4 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -203,6 +203,10 @@
 static char kLinkerPath[] = "/system/bin/linker";
 #endif
 
+static void __linker_cannot_link(const char* argv0) {
+  async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
+}
+
 /*
  * This code is called after the linker has linked itself and
  * fixed it's own GOT. It is safe to make references to externs
@@ -317,17 +321,17 @@
 
   // We haven't supported non-PIE since Lollipop for security reasons.
   if (elf_hdr->e_type != ET_DYN) {
-    // We don't use __libc_fatal here because we don't want a tombstone: it's
-    // been several years now but we still find ourselves on app compatibility
+    // We don't use async_safe_fatal here because we don't want a tombstone:
+    // even after several years we still find ourselves on app compatibility
     // investigations because some app's trying to launch an executable that
     // hasn't worked in at least three years, and we've "helpfully" dropped a
     // tombstone for them. The tombstone never provided any detail relevant to
     // fixing the problem anyway, and the utility of drawing extra attention
     // to the problem is non-existent at this late date.
     async_safe_format_fd(STDERR_FILENO,
-                     "\"%s\": error: Android 5.0 and later only support "
-                     "position-independent executables (-fPIE).\n",
-                     g_argv[0]);
+                         "\"%s\": error: Android 5.0 and later only support "
+                         "position-independent executables (-fPIE).\n",
+                         g_argv[0]);
     exit(EXIT_FAILURE);
   }
 
@@ -337,14 +341,19 @@
 
   somain = si;
 
-  init_default_namespace(executable_path);
+  std::vector<android_namespace_t*> namespaces = init_default_namespaces(executable_path);
 
-  if (!si->prelink_image()) {
-    async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
-  }
+  if (!si->prelink_image()) __linker_cannot_link(g_argv[0]);
 
   // add somain to global group
   si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+  // ... and add it to all other linked namespaces
+  for (auto linked_ns : namespaces) {
+    if (linked_ns != &g_default_namespace) {
+      linked_ns->add_soinfo(somain);
+      somain->add_secondary_namespace(linked_ns);
+    }
+  }
 
   // Load ld_preloads and dependencies.
   std::vector<const char*> needed_library_name_list;
@@ -362,6 +371,9 @@
   const char** needed_library_names = &needed_library_name_list[0];
   size_t needed_libraries_count = needed_library_name_list.size();
 
+  // readers_map is shared across recursive calls to find_libraries so that we
+  // don't need to re-load elf headers.
+  std::unordered_map<const soinfo*, ElfReader> readers_map;
   if (needed_libraries_count > 0 &&
       !find_libraries(&g_default_namespace,
                       si,
@@ -373,20 +385,20 @@
                       RTLD_GLOBAL,
                       nullptr,
                       true /* add_as_children */,
-                      true /* search_linked_namespaces */)) {
-    async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+                      true /* search_linked_namespaces */,
+                      readers_map,
+                      &namespaces)) {
+    __linker_cannot_link(g_argv[0]);
   } else if (needed_libraries_count == 0) {
     if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {
-      async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
+      __linker_cannot_link(g_argv[0]);
     }
     si->increment_ref_count();
   }
 
   add_vdso(args);
 
-  if (!get_cfi_shadow()->InitialLinkDone(solist)) {
-    async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer());
-  }
+  if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
 
   si->call_pre_init_constructors();
 
@@ -468,10 +480,6 @@
   return 0;
 }
 
-static void __linker_cannot_link(const char* argv0) {
-  async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer());
-}
-
 /*
  * This is the entry point for the linker, called from begin.S. This
  * method is responsible for fixing the linker's own relocations, and
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 8f3f07c..2cf30c2 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -31,6 +31,9 @@
 
 #include <android/dlext.h>
 
+#include <unordered_map>
+#include <vector>
+
 #include "linker_namespaces.h"
 #include "linker_soinfo.h"
 
@@ -44,7 +47,9 @@
   static size_t ref_count_;
 };
 
-void init_default_namespace(const char* executable_path);
+class ElfReader;
+
+std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path);
 soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
                      struct stat* file_stat, off64_t file_offset,
                      uint32_t rtld_flags);
@@ -59,7 +64,9 @@
                     int rtld_flags,
                     const android_dlextinfo* extinfo,
                     bool add_as_children,
-                    bool search_linked_namespaces);
+                    bool search_linked_namespaces,
+                    std::unordered_map<const soinfo*, ElfReader>& readers_map,
+                    std::vector<android_namespace_t*>* namespaces = nullptr);
 
 void solist_add_soinfo(soinfo* si);
 bool solist_remove_soinfo(soinfo* si);
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index 3c86f99..9fdf0b5 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -31,6 +31,8 @@
 #include "linker_soinfo.h"
 #include "linker_utils.h"
 
+#include <dlfcn.h>
+
 bool android_namespace_t::is_accessible(const std::string& file) {
   if (!is_isolated_) {
     return true;
@@ -86,3 +88,41 @@
     return !is_accessible_ftor(si);
   });
 }
+
+// TODO: this is slightly unusual way to construct
+// the global group for relocation. Not every RTLD_GLOBAL
+// library is included in this group for backwards-compatibility
+// reasons.
+//
+// This group consists of the main executable, LD_PRELOADs
+// and libraries with the DF_1_GLOBAL flag set.
+soinfo_list_t android_namespace_t::get_global_group() {
+  soinfo_list_t global_group;
+  soinfo_list().for_each([&](soinfo* si) {
+    if ((si->get_dt_flags_1() & DF_1_GLOBAL) != 0) {
+      global_group.push_back(si);
+    }
+  });
+
+  return global_group;
+}
+
+// This function provides a list of libraries to be shared
+// by the namespace. For the default namespace this is the global
+// group (see get_global_group). For all others this is a group
+// of RTLD_GLOBAL libraries (which includes the global group from
+// the default namespace).
+soinfo_list_t android_namespace_t::get_shared_group() {
+  if (this == &g_default_namespace) {
+    return get_global_group();
+  }
+
+  soinfo_list_t shared_group;
+  soinfo_list().for_each([&](soinfo* si) {
+    if ((si->get_rtld_flags() & RTLD_GLOBAL) != 0) {
+      shared_group.push_back(si);
+    }
+  });
+
+  return shared_group;
+}
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 1099b6b..16906d6 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -136,6 +136,9 @@
   // or one of it's parent soinfos belongs to this namespace.
   bool is_accessible(soinfo* si);
 
+  soinfo_list_t get_global_group();
+  soinfo_list_t get_shared_group();
+
  private:
   const char* name_;
   bool is_isolated_;
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 42c29c8..a9873c4 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -147,8 +147,9 @@
 }
 
 bool ElfReader::Read(const char* name, int fd, off64_t file_offset, off64_t file_size) {
-  CHECK(!did_read_);
-  CHECK(!did_load_);
+  if (did_read_) {
+    return true;
+  }
   name_ = name;
   fd_ = fd;
   file_offset_ = file_offset;
@@ -167,7 +168,9 @@
 
 bool ElfReader::Load(const android_dlextinfo* extinfo) {
   CHECK(did_read_);
-  CHECK(!did_load_);
+  if (did_load_) {
+    return true;
+  }
   if (ReserveAddressSpace(extinfo) &&
       LoadSegments() &&
       FindPhdr()) {
diff --git a/tests/Android.bp b/tests/Android.bp
index 8f1c11f..084d393 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -298,7 +298,13 @@
                 "libLLVMSupport",
             ],
         }
-    }
+    },
+
+    product_variables: {
+        debuggable: {
+            cppflags: ["-DUSE_LD_CONFIG_FILE"],
+        },
+    },
 }
 
 // -----------------------------------------------------------------------------
@@ -592,6 +598,12 @@
     sanitize: {
         never: false,
     },
+
+    product_variables: {
+        debuggable: {
+            cppflags: ["-DUSE_LD_CONFIG_FILE"],
+        },
+    },
 }
 
 subdirs = ["libs"]
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index aa8bd57..857640a 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -23,6 +23,8 @@
 #include <stdint.h>
 
 #include <string>
+#include <iostream>
+#include <fstream>
 
 #include "gtest_globals.h"
 #include "utils.h"
@@ -109,4 +111,131 @@
 #endif
 }
 
-// TODO: Add tests for LD_PRELOADs
+
+TEST(dl, exec_without_ld_preload) {
+#if defined(__BIONIC__)
+  std::string helper = get_testlib_root() +
+      "/ld_preload_test_helper/ld_preload_test_helper";
+  chmod(helper.c_str(), 0755);
+  ExecTestHelper eth;
+  eth.SetArgs({ helper.c_str(), nullptr });
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
+#endif
+}
+
+TEST(dl, exec_with_ld_preload) {
+#if defined(__BIONIC__)
+  std::string helper = get_testlib_root() +
+      "/ld_preload_test_helper/ld_preload_test_helper";
+  std::string env = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_preload_test_helper_lib2.so";
+  chmod(helper.c_str(), 0755);
+  ExecTestHelper eth;
+  eth.SetArgs({ helper.c_str(), nullptr });
+  eth.SetEnv({ env.c_str(), nullptr });
+  // ld_preload_test_helper calls get_value_from_lib() and returns the value.
+  // The symbol is defined by two libs: ld_preload_test_helper_lib.so and
+  // ld_preloaded_lib.so. The former is DT_NEEDED and the latter is LD_PRELOADED
+  // via this execution. The main executable is linked to the LD_PRELOADED lib
+  // and the value given from the lib is returned.
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
+#endif
+}
+
+
+// ld_config_test_helper must fail because it is depending on a lib which is not
+// in the search path
+//
+// Call sequence is...
+// _helper -- (get_value_from_lib()) -->
+//     _lib1.so -- (get_value_from_another_lib()) -->
+//       _lib2.so (returns 12345)
+// The two libs are in ns2/ subdir.
+TEST(dl, exec_without_ld_config_file) {
+#if defined(__BIONIC__)
+  std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
+  std::string helper = get_testlib_root() +
+      "/ld_config_test_helper/ld_config_test_helper";
+  chmod(helper.c_str(), 0755);
+  ExecTestHelper eth;
+  eth.SetArgs({ helper.c_str(), nullptr });
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+#endif
+}
+
+#if defined(__BIONIC__)
+static void create_ld_config_file(std::string& config_file) {
+  std::ofstream fout(config_file.c_str(), std::ios::out);
+  fout << "dir.test = " << get_testlib_root() << "/ld_config_test_helper/" << std::endl
+       << "[test]" << std::endl
+       << "additional.namespaces = ns2" << std::endl
+       << "namespace.default.search.paths = " << get_testlib_root() << std::endl
+       << "namespace.default.links = ns2" << std::endl
+       << "namespace.default.link.ns2.shared_libs = libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so" << std::endl
+       << "namespace.ns2.search.paths = /system/${LIB}:" << get_testlib_root() << "/ns2" << std::endl;
+  fout.close();
+}
+#endif
+
+#ifdef USE_LD_CONFIG_FILE
+
+// _lib1.so and _lib2.so are now searchable by having another namespace 'ns2'
+// whose search paths include the 'ns2/' subdir.
+TEST(dl, exec_with_ld_config_file) {
+#if defined(__BIONIC__)
+  std::string helper = get_testlib_root() +
+      "/ld_config_test_helper/ld_config_test_helper";
+  std::string config_file = get_testlib_root() + "/ld.config.txt";
+  create_ld_config_file(config_file);
+  std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+  chmod(helper.c_str(), 0755);
+  ExecTestHelper eth;
+  eth.SetArgs({ helper.c_str(), nullptr });
+  eth.SetEnv({ env.c_str(), nullptr });
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "12345");
+#endif
+}
+
+// _lib3.so has same symbol as lib2.so but returns 54321. _lib3.so is
+// LD_PRELOADed. This test is to ensure LD_PRELOADed libs are available to
+// additional namespaces other than the default namespace.
+TEST(dl, exec_with_ld_config_file_with_ld_preload) {
+#if defined(__BIONIC__)
+  std::string helper = get_testlib_root() +
+      "/ld_config_test_helper/ld_config_test_helper";
+  std::string config_file = get_testlib_root() + "/ld.config.txt";
+  create_ld_config_file(config_file);
+  std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+  std::string env2 = std::string("LD_PRELOAD=") + get_testlib_root() + "/ld_config_test_helper_lib3.so";
+  chmod(helper.c_str(), 0755);
+  ExecTestHelper eth;
+  eth.SetArgs({ helper.c_str(), nullptr });
+  eth.SetEnv({ env.c_str(), env2.c_str(), nullptr });
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, "54321");
+#endif
+}
+
+#endif // USE_LD_CONFIG_FILE
+
+// ensures that LD_CONFIG_FILE env var does not work for production builds.
+// The test input is the same as exec_with_ld_config_file, but it must fail in
+// this case.
+TEST(dl, disable_ld_config_file) {
+#if defined(__BIONIC__)
+  if (getuid() == 0) {
+    // when executed from the shell (e.g. not as part of CTS), skip the test.
+    // This test is only for CTS.
+    return;
+  }
+  std::string error_message = "CANNOT LINK EXECUTABLE \"" + get_testlib_root() + "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" not found\n";
+  std::string helper = get_testlib_root() +
+      "/ld_config_test_helper/ld_config_test_helper";
+  std::string config_file = get_testlib_root() + "/ld.config.txt";
+  create_ld_config_file(config_file);
+  std::string env = std::string("LD_CONFIG_FILE=") + config_file;
+  chmod(helper.c_str(), 0755);
+  ExecTestHelper eth;
+  eth.SetArgs({ helper.c_str(), nullptr });
+  eth.SetEnv({ env.c_str(), nullptr });
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, -6, error_message.c_str());
+#endif
+}
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp
index 51074b2..db800a2 100644
--- a/tests/fortify_compilation_test.cpp
+++ b/tests/fortify_compilation_test.cpp
@@ -71,7 +71,7 @@
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: warning: call to void* __builtin___memcpy_chk(void*, const void*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
-  // CLANG: error: call to unavailable function 'memcpy': memcpy called with size bigger than buffer
+  // CLANG: error: 'memcpy' called with size bigger than buffer
   memcpy(buf, "foobar", sizeof("foobar") + 100);
 }
 
@@ -80,7 +80,7 @@
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: warning: call to void* __builtin___memmove_chk(void*, const void*, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
-  // CLANG: error: call to unavailable function 'memmove': memmove called with size bigger than buffer
+  // CLANG: error: 'memmove' called with size bigger than buffer
   memmove(buf, "foobar", sizeof("foobar"));
 }
 
@@ -89,7 +89,7 @@
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: warning: call to void* __builtin___memset_chk(void*, int, {{(long )?}}unsigned int, {{(long )?}}unsigned int) will always overflow destination buffer
-  // CLANG: error: call to unavailable function 'memset': memset called with size bigger than buffer
+  // CLANG: error: 'memset' called with size bigger than buffer
   memset(buf, 0, 6);
 }
 
@@ -98,8 +98,13 @@
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: warning: call to {{(char\* __builtin___strcpy_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
-  // CLANG: error: call to unavailable function 'strcpy': strcpy called with string bigger than buffer
+  // CLANG: error: 'strcpy' called with string bigger than buffer
   strcpy(buf, "foobar");  // NOLINT(runtime/printf)
+
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: warning: call to {{(char\* __builtin___strcpy_chk\(char\*, const char\*, unsigned int\))|(void\* __builtin___memcpy_chk\(void\*, const void\*, (long )?unsigned int, (long )?unsigned int\))}} will always overflow destination buffer
+  // CLANG: error: 'strcpy' called with string bigger than buffer
+  strcpy(buf, "quux");
 }
 
 void test_stpcpy() {
@@ -107,8 +112,13 @@
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: warning: call to char* __builtin___stpcpy_chk(char*, const char*, {{(long )?}}unsigned int) will always overflow destination buffer
-  // CLANG: error: call to unavailable function 'stpcpy': stpcpy called with string bigger than buffer
+  // CLANG: error: 'stpcpy' called with string bigger than buffer
   stpcpy(buf, "foobar");
+
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: warning: call to char* __builtin___stpcpy_chk(char*, const char*, {{(long )?}}unsigned int) will always overflow destination buffer
+  // CLANG: error: 'stpcpy' called with string bigger than buffer
+  stpcpy(buf, "quux");
 }
 
 void test_strncpy() {
@@ -169,12 +179,12 @@
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__fgets_too_small_error' declared with attribute error: fgets called with size less than zero
-  // CLANG: error: call to unavailable function 'fgets': size is negative
+  // CLANG: error: in call to 'fgets', size should not be negative
   fgets(buf, -1, stdin);
 
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__fgets_too_big_error' declared with attribute error: fgets called with size bigger than buffer
-  // CLANG: error: call to unavailable function 'fgets': size is larger than the destination buffer
+  // CLANG: error: in call to 'fgets', size is larger than the destination buffer
   fgets(buf, 6, stdin);
 }
 
@@ -183,15 +193,24 @@
   sockaddr_in addr;
 
   // NOLINTNEXTLINE(whitespace/line_length)
-  // GCC: error: call to '__recvfrom_error' declared with attribute error: recvfrom called with size bigger than buffer
-  // CLANG: error: call to unavailable function 'recvfrom': recvfrom called with size bigger than buffer
+  // GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
+  // CLANG: error: 'recvfrom' called with size bigger than buffer
   recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), NULL);
 }
 
+void test_recv() {
+  char buf[4] = {0};
+
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
+  // CLANG: error: 'recv' called with size bigger than buffer
+  recv(0, buf, 6, 0);
+}
+
 void test_umask() {
   // NOLINTNEXTLINE(whitespace/line_length)
-  // GCC: error: call to '__umask_invalid_mode' declared with attribute error: umask called with invalid mode
-  // CLANG: error: call to unavailable function 'umask': umask called with invalid mode
+  // GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode
+  // CLANG: error: 'umask' called with invalid mode
   umask(01777);
 }
 
@@ -199,14 +218,14 @@
   char buf[4];
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__read_dest_size_error' declared with attribute error: read called with size bigger than destination
-  // CLANG: error: call to unavailable function 'read': 'count' bytes overflows the given object
+  // CLANG: error: in call to 'read', 'count' bytes overflows the given object
   read(0, buf, 6);
 }
 
 void test_open() {
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__creat_missing_mode' declared with attribute error: called with O_CREAT, but missing mode
-  // CLANG: error: call to unavailable function 'open': called with O_CREAT, but missing mode
+  // CLANG: error: 'open' called with O_CREAT, but missing mode
   open("/dev/null", O_CREAT);
 
   // NOLINTNEXTLINE(whitespace/line_length)
@@ -219,7 +238,7 @@
   pollfd fds[1];
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__poll_too_small_error' declared with attribute error: poll: pollfd array smaller than fd count
-  // CLANG: error: call to unavailable function 'poll': too many fds specified
+  // CLANG: error: in call to 'poll', fd_count is larger than the given buffer
   poll(fds, 2, 0);
 }
 
@@ -228,7 +247,7 @@
   timespec timeout;
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__ppoll_too_small_error' declared with attribute error: ppoll: pollfd array smaller than fd count
-  // CLANG: error: call to unavailable function 'ppoll': too many fds specified
+  // CLANG: error: in call to 'ppoll', fd_count is larger than the given buffer
   ppoll(fds, 2, &timeout, NULL);
 }
 
@@ -236,7 +255,7 @@
   char buf[4];
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__fread_overflow' declared with attribute error: fread called with overflowing size * count
-  // CLANG: error: call to unavailable function 'fread': size * count overflows
+  // CLANG: error: in call to 'fread', size * count overflows
   fread(buf, 2, (size_t)-1, stdin);
 }
 
@@ -244,7 +263,8 @@
   char buf[4];
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__fread_too_big_error' declared with attribute error: fread called with size * count bigger than buffer
-  // CLANG: error: call to unavailable function 'fread': size * count is too large
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // CLANG: error: in call to 'fread', size * count is too large for the given buffer
   fread(buf, 1, 5, stdin);
 }
 
@@ -252,7 +272,7 @@
   char buf[4] = {0};
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__fwrite_overflow' declared with attribute error: fwrite called with overflowing size * count
-  // CLANG: error: call to unavailable function 'fwrite': size * count overflows
+  // CLANG: error: in call to 'fwrite', size * count overflows
   fwrite(buf, 2, (size_t)-1, stdout);
 }
 
@@ -260,7 +280,8 @@
   char buf[4] = {0};
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__fwrite_too_big_error' declared with attribute error: fwrite called with size * count bigger than buffer
-  // CLANG: error: call to unavailable function 'fwrite': size * count is too large
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // CLANG: error: in call to 'fwrite', size * count is too large for the given buffer
   fwrite(buf, 1, 5, stdout);
 }
 
@@ -268,7 +289,7 @@
   char buf[4];
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__getcwd_dest_size_error' declared with attribute error: getcwd called with size bigger than destination
-  // CLANG: error: call to unavailable function 'getcwd': 'size' bytes overflows the given object
+  // CLANG: error: in call to 'getcwd', 'size' bytes overflows the given object
   getcwd(buf, 5);
 }
 
@@ -276,7 +297,7 @@
   char buf[4] = {0};
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__pwrite64_dest_size_error' declared with attribute error: pwrite64 called with size bigger than destination
-  // CLANG: error: call to unavailable function 'pwrite64': 'count' bytes overflows the given object
+  // CLANG: error: in call to 'pwrite64', 'count' bytes overflows the given object
   pwrite64(STDOUT_FILENO, buf, 5, 0);
 }
 
@@ -292,7 +313,7 @@
   char buf[4] = {0};
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__pwrite64_count_toobig_error' declared with attribute error: pwrite64 called with count > SSIZE_MAX
-  // CLANG: error: call to unavailable function 'pwrite64': count must be <= SSIZE_MAX
+  // CLANG: error: in call to 'pwrite64', 'count' must be <= SSIZE_MAX
   pwrite64(STDOUT_FILENO, buf, SIZE_MAX, 0);
 }
 
@@ -300,14 +321,14 @@
   char buf[4] = {0};
   // NOLINTNEXTLINE(whitespace/line_length)
   // GCC: error: call to '__write_dest_size_error' declared with attribute error: write called with size bigger than destination
-  // CLANG: error: call to unavailable function 'write': 'count' bytes overflows the given object
+  // CLANG: error: in call to 'write', 'count' bytes overflows the given object
   write(STDOUT_FILENO, buf, 5);
 }
 
 void test_memset_args_flipped() {
   char from[4] = {0};
   // NOLINTNEXTLINE(whitespace/line_length)
-  // CLANG: 'memset' is deprecated: will set 0 bytes; maybe the arguments got flipped? (Add __bionic_zero_size_is_okay as a fourth argument to silence this.)
+  // CLANG: 'memset' will set 0 bytes; maybe the arguments got flipped?
   memset(from, sizeof(from), 0);
 }
 
@@ -316,8 +337,8 @@
   sockaddr_in addr;
 
   // NOLINTNEXTLINE(whitespace/line_length)
-  // GCC: error: call to '__sendto_error' declared with attribute error: sendto called with size bigger than buffer
-  // CLANG: error: call to unavailable function 'sendto': sendto called with size bigger than buffer
+  // GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
+  // CLANG: error: 'sendto' called with size bigger than buffer
   sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
 }
 
@@ -325,7 +346,22 @@
   char buf[4] = {0};
 
   // NOLINTNEXTLINE(whitespace/line_length)
-  // GCC: error: call to '__sendto_error' declared with attribute error: sendto called with size bigger than buffer
-  // CLANG: error: call to unavailable function 'send': send called with size bigger than buffer
+  // GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
+  // CLANG: error: 'send' called with size bigger than buffer
   send(0, buf, 6, 0);
 }
+
+void test_realpath() {
+  char buf[4] = {0};
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // GCC: error: call to '__realpath_size_error' declared with attribute error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
+  // NOLINTNEXTLINE(whitespace/line_length)
+  // CLANG: error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
+  realpath(".", buf);
+
+  // This is fine.
+  realpath(".", NULL);
+
+  // FIXME: But we should warn on this.
+  realpath(NULL, buf);
+}
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 973a8d2..c1600cc 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -617,3 +617,59 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["preinit_syscall_test_helper.cpp"],
 }
+
+cc_test {
+    name: "ld_preload_test_helper",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_preload_test_helper.cpp"],
+    shared_libs: ["ld_preload_test_helper_lib1"],
+    ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
+cc_test_library {
+    name: "ld_preload_test_helper_lib1",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_preload_test_helper_lib1.cpp"],
+}
+
+cc_test_library {
+    name: "ld_preload_test_helper_lib2",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_preload_test_helper_lib2.cpp"],
+}
+
+cc_test {
+    name: "ld_config_test_helper",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_config_test_helper.cpp"],
+    shared_libs: ["ld_config_test_helper_lib1"],
+    ldflags: ["-Wl,--rpath,${ORIGIN}/.."],
+}
+
+cc_test_library {
+    name: "ld_config_test_helper_lib1",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_config_test_helper_lib1.cpp"],
+    shared_libs: ["ld_config_test_helper_lib2"],
+    relative_install_path: "/ns2",
+}
+
+cc_test_library {
+    name: "ld_config_test_helper_lib2",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_config_test_helper_lib2.cpp"],
+    relative_install_path: "/ns2",
+}
+
+cc_test_library {
+    name: "ld_config_test_helper_lib3",
+    host_supported: false,
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["ld_config_test_helper_lib3.cpp"],
+}
diff --git a/tests/libs/ld_config_test_helper.cpp b/tests/libs/ld_config_test_helper.cpp
new file mode 100644
index 0000000..592e8c0
--- /dev/null
+++ b/tests/libs/ld_config_test_helper.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern int get_value_from_lib();
+
+int main() {
+  printf("%d", get_value_from_lib());
+  return 0;
+}
diff --git a/tests/libs/ld_config_test_helper_lib1.cpp b/tests/libs/ld_config_test_helper_lib1.cpp
new file mode 100644
index 0000000..fc5401a
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib1.cpp
@@ -0,0 +1,4 @@
+extern int get_value_from_another_lib();
+int get_value_from_lib() {
+  return get_value_from_another_lib();
+}
diff --git a/tests/libs/ld_config_test_helper_lib2.cpp b/tests/libs/ld_config_test_helper_lib2.cpp
new file mode 100644
index 0000000..a620a6c
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib2.cpp
@@ -0,0 +1,3 @@
+int get_value_from_another_lib() {
+  return 12345;
+}
diff --git a/tests/libs/ld_config_test_helper_lib3.cpp b/tests/libs/ld_config_test_helper_lib3.cpp
new file mode 100644
index 0000000..93d1cd8
--- /dev/null
+++ b/tests/libs/ld_config_test_helper_lib3.cpp
@@ -0,0 +1,3 @@
+int get_value_from_another_lib() {
+  return 54321;
+}
diff --git a/tests/libs/ld_preload_test_helper.cpp b/tests/libs/ld_preload_test_helper.cpp
new file mode 100644
index 0000000..592e8c0
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+extern int get_value_from_lib();
+
+int main() {
+  printf("%d", get_value_from_lib());
+  return 0;
+}
diff --git a/tests/libs/ld_preload_test_helper_lib1.cpp b/tests/libs/ld_preload_test_helper_lib1.cpp
new file mode 100644
index 0000000..74e89db
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper_lib1.cpp
@@ -0,0 +1,3 @@
+int get_value_from_lib() {
+  return 12345;
+}
diff --git a/tests/libs/ld_preload_test_helper_lib2.cpp b/tests/libs/ld_preload_test_helper_lib2.cpp
new file mode 100644
index 0000000..9239891
--- /dev/null
+++ b/tests/libs/ld_preload_test_helper_lib2.cpp
@@ -0,0 +1,3 @@
+int get_value_from_lib() {
+  return 54321;
+}
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index a4cffc0..e70528e 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -270,3 +270,34 @@
   CPU_FREE(set1);
   CPU_FREE(set2);
 }
+
+TEST(sched, sched_get_priority_min_sched_get_priority_max) {
+  EXPECT_LE(sched_get_priority_min(SCHED_BATCH), sched_get_priority_max(SCHED_BATCH));
+  EXPECT_LE(sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO));
+  EXPECT_LE(sched_get_priority_min(SCHED_IDLE), sched_get_priority_max(SCHED_IDLE));
+  EXPECT_LE(sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER));
+  EXPECT_LE(sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR));
+}
+
+TEST(sched, sched_getscheduler_sched_setscheduler) {
+  // POSIX: "If pid is zero, the scheduling policy shall be returned for the
+  // calling process".
+  ASSERT_EQ(sched_getscheduler(getpid()), sched_getscheduler(0));
+
+  const int original_policy = sched_getscheduler(getpid());
+  sched_param p = {};
+  p.sched_priority = sched_get_priority_min(original_policy);
+  errno = 0;
+  ASSERT_EQ(-1, sched_setscheduler(getpid(), INT_MAX, &p));
+  ASSERT_EQ(EINVAL, errno);
+
+  ASSERT_EQ(0, sched_getparam(getpid(), &p));
+  ASSERT_EQ(original_policy, sched_setscheduler(getpid(), SCHED_BATCH, &p));
+  // POSIX says this should return the previous policy (here SCHED_BATCH),
+  // but the Linux system call doesn't, and the glibc wrapper doesn't correct
+  // this (the "returns 0" behavior is even documented on the man page in
+  // the BUGS section). This was our historical behavior too, so in the
+  // absence of reasons to break compatibility with ourselves and glibc, we
+  // don't behave as POSIX specifies. http://b/26203902.
+  ASSERT_EQ(0, sched_setscheduler(getpid(), original_policy, &p));
+}
diff --git a/tests/stdio_ext_test.cpp b/tests/stdio_ext_test.cpp
index 7872567..128e255 100644
--- a/tests/stdio_ext_test.cpp
+++ b/tests/stdio_ext_test.cpp
@@ -116,20 +116,78 @@
 }
 
 TEST(stdio_ext, __freadable__fwritable) {
-  FILE* fp = fopen("/dev/null", "r");
+  FILE* fp;
+
+  // Read-only.
+  fp = fopen("/dev/null", "r");
   ASSERT_TRUE(__freadable(fp));
   ASSERT_FALSE(__fwritable(fp));
   fclose(fp);
 
+  // Write-only.
   fp = fopen("/dev/null", "w");
   ASSERT_FALSE(__freadable(fp));
   ASSERT_TRUE(__fwritable(fp));
   fclose(fp);
 
-  fp = fopen("/dev/null", "w+");
-  ASSERT_TRUE(__freadable(fp));
+  // Append (aka write-only).
+  fp = fopen("/dev/null", "a");
+  ASSERT_FALSE(__freadable(fp));
   ASSERT_TRUE(__fwritable(fp));
   fclose(fp);
+
+  // The three read-write modes.
+  for (auto read_write_mode : {"r+", "w+", "a+"}) {
+    fp = fopen("/dev/null", read_write_mode);
+    ASSERT_TRUE(__freadable(fp));
+    ASSERT_TRUE(__fwritable(fp));
+    fclose(fp);
+  }
+}
+
+TEST(stdio_ext, __freading__fwriting) {
+  FILE* fp;
+
+  // Append (aka write-only). Never reading. Always writing.
+  fp = fopen("/dev/zero", "a");
+  ASSERT_FALSE(__freading(fp)); // Not reading initially.
+  ASSERT_TRUE(__fwriting(fp)); // Writing initially.
+  ASSERT_TRUE(fputc('x', fp) != EOF);
+  ASSERT_FALSE(__freading(fp)); // Not reading after write.
+  ASSERT_TRUE(__fwriting(fp)); // Still writing after write.
+  fclose(fp);
+
+  // Write-only. Never reading. Always writing.
+  fp = fopen("/dev/zero", "w");
+  ASSERT_FALSE(__freading(fp)); // Not reading initially.
+  ASSERT_TRUE(__fwriting(fp)); // Writing initially.
+  ASSERT_TRUE(fputc('x', fp) != EOF);
+  ASSERT_FALSE(__freading(fp)); // Not reading after write.
+  ASSERT_TRUE(__fwriting(fp)); // Still writing after write.
+  fclose(fp);
+
+  // Read-only. Always reading. Never writing.
+  fp = fopen("/dev/zero", "r");
+  ASSERT_TRUE(__freading(fp)); // Reading initially.
+  ASSERT_FALSE(__fwriting(fp)); // Not writing initially.
+  ASSERT_TRUE(fgetc(fp) == 0);
+  ASSERT_TRUE(__freading(fp)); // Still reading after read.
+  ASSERT_FALSE(__fwriting(fp)); // Still not writing after read.
+  fclose(fp);
+
+  // The three read-write modes.
+  for (auto read_write_mode : {"r+", "w+", "a+"}) {
+    fp = fopen("/dev/zero", read_write_mode);
+    ASSERT_FALSE(__freading(fp)); // Not reading initially.
+    ASSERT_FALSE(__fwriting(fp)); // Not writing initially.
+    ASSERT_TRUE(fgetc(fp) == 0);
+    ASSERT_TRUE(__freading(fp)); // Reading after read.
+    ASSERT_FALSE(__fwriting(fp)); // Not writing after read.
+    ASSERT_TRUE(fputc('x', fp) != EOF);
+    ASSERT_FALSE(__freading(fp)); // Not reading after write.
+    ASSERT_TRUE(__fwriting(fp)); // Writing after write.
+    fclose(fp);
+  }
 }
 
 TEST(stdio_ext, __fsetlocking) {
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index dac7056..1bb97a3 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -1918,3 +1918,8 @@
   ASSERT_EQ(0, fclose(fp));
   AssertFileIs(tf.filename, "0123456789xxx");
 }
+
+TEST(STDIO_TEST, constants) {
+  ASSERT_LE(FILENAME_MAX, PATH_MAX);
+  ASSERT_EQ(L_tmpnam, PATH_MAX);
+}
diff --git a/tools/versioner/src/Utils.cpp b/tools/versioner/src/Utils.cpp
index ef7facc..ca186a4 100644
--- a/tools/versioner/src/Utils.cpp
+++ b/tools/versioner/src/Utils.cpp
@@ -37,7 +37,8 @@
   return buf;
 }
 
-std::vector<std::string> collectHeaders(const std::string& directory) {
+std::vector<std::string> collectHeaders(const std::string& directory,
+                                        const std::unordered_set<std::string>& ignored_directories) {
   std::vector<std::string> headers;
 
   char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr };
@@ -48,16 +49,34 @@
     err(1, "failed to open directory '%s'", directory.c_str());
   }
 
+  FTSENT* skipping = nullptr;
   while (FTSENT* ent = fts_read(fts.get())) {
-    if (ent->fts_info & (FTS_D | FTS_DP)) {
+    if (ent->fts_info & FTS_DP) {
+      if (ent == skipping) {
+        skipping = nullptr;
+      }
       continue;
     }
 
-    if (!android::base::EndsWith(ent->fts_path, ".h")) {
+    if (skipping != nullptr) {
       continue;
     }
 
-    headers.push_back(ent->fts_path);
+    if (ent->fts_info & FTS_D) {
+      if (ignored_directories.count(ent->fts_path) != 0) {
+        // fts_read guarantees that `ent` is valid and sane to hold on to until
+        // after it's returned with FTS_DP set.
+        skipping = ent;
+      }
+      continue;
+    }
+
+    std::string path = ent->fts_path;
+    if (!android::base::EndsWith(path, ".h")) {
+      continue;
+    }
+
+    headers.push_back(std::move(path));
   }
 
   return headers;
diff --git a/tools/versioner/src/Utils.h b/tools/versioner/src/Utils.h
index 44a34f8..9b45dcd 100644
--- a/tools/versioner/src/Utils.h
+++ b/tools/versioner/src/Utils.h
@@ -22,12 +22,14 @@
 #include <unistd.h>
 
 #include <string>
+#include <unordered_set>
 #include <vector>
 
 #include <llvm/ADT/StringRef.h>
 
 std::string getWorkingDir();
-std::vector<std::string> collectHeaders(const std::string& directory);
+std::vector<std::string> collectHeaders(const std::string& directory,
+                                        const std::unordered_set<std::string>& ignored_directories);
 
 static inline std::string dirname(const std::string& path) {
   std::unique_ptr<char, decltype(&free)> path_copy(strdup(path.c_str()), free);
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 747c767..8db75d7 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -45,6 +45,7 @@
 #include <android-base/file.h>
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
+#include <android-base/strings.h>
 
 #include "Arch.h"
 #include "DeclarationDatabase.h"
@@ -79,11 +80,21 @@
 #endif
 }
 
-static CompilationRequirements collectRequirements(const Arch& arch, const std::string& header_dir,
-                                                   const std::string& dependency_dir) {
-  std::vector<std::string> headers = collectHeaders(header_dir);
-  std::vector<std::string> dependencies = { header_dir };
-  if (!dependency_dir.empty()) {
+namespace {
+struct HeaderLocationInformation {
+  std::string header_dir;
+  std::string dependency_dir;
+  // Absolute paths to ignore all children -- including subdirectories -- of.
+  std::unordered_set<std::string> ignored_directories;
+};
+}
+
+static CompilationRequirements collectRequirements(const Arch& arch,
+                                                   const HeaderLocationInformation& location) {
+  std::vector<std::string> headers =
+      collectHeaders(location.header_dir, location.ignored_directories);
+  std::vector<std::string> dependencies = { location.header_dir };
+  if (!location.dependency_dir.empty()) {
     auto collect_children = [&dependencies](const std::string& dir_path) {
       DIR* dir = opendir(dir_path.c_str());
       if (!dir) {
@@ -114,8 +125,8 @@
       closedir(dir);
     };
 
-    collect_children(dependency_dir + "/common");
-    collect_children(dependency_dir + "/" + to_string(arch));
+    collect_children(location.dependency_dir + "/common");
+    collect_children(location.dependency_dir + "/" + to_string(arch));
   }
 
   auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
@@ -159,13 +170,12 @@
 }
 
 static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<CompilationType>& types,
-                                                      const std::string& header_dir,
-                                                      const std::string& dependency_dir) {
+                                                      const HeaderLocationInformation& location) {
   if (types.empty()) {
     errx(1, "compileHeaders received no CompilationTypes");
   }
 
-  auto vfs = createCommonVFS(header_dir, dependency_dir, add_include);
+  auto vfs = createCommonVFS(location.header_dir, location.dependency_dir, add_include);
 
   size_t thread_count = max_thread_count;
   std::vector<std::thread> threads;
@@ -176,7 +186,7 @@
   auto result = std::make_unique<HeaderDatabase>();
   for (const auto& type : types) {
     if (requirements.count(type.arch) == 0) {
-      requirements[type.arch] = collectRequirements(type.arch, header_dir, dependency_dir);
+      requirements[type.arch] = collectRequirements(type.arch, location);
     }
   }
 
@@ -454,6 +464,7 @@
     fprintf(stderr, "  -f\t\tpreprocess header files even if validation fails\n");
     fprintf(stderr, "\n");
     fprintf(stderr, "Miscellaneous:\n");
+    fprintf(stderr, "  -F\t\tdo not ignore FORTIFY headers by default\n");
     fprintf(stderr, "  -d\t\tdump function availability\n");
     fprintf(stderr, "  -j THREADS\tmaximum number of threads to use\n");
     fprintf(stderr, "  -v\t\tenable verbose logging\n");
@@ -477,9 +488,10 @@
   std::string preprocessor_output_path;
   bool force = false;
   bool dump = false;
+  bool ignore_fortify_headers = true;
 
   int c;
-  while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhi")) != -1) {
+  while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
     default_args = false;
     switch (c) {
       case 'a': {
@@ -565,6 +577,10 @@
         add_include = true;
         break;
 
+      case 'F':
+        ignore_fortify_headers = false;
+        break;
+
       default:
         usage();
         break;
@@ -575,8 +591,7 @@
     usage();
   }
 
-  std::string header_dir;
-  std::string dependency_dir;
+  HeaderLocationInformation location;
 
   const char* top = getenv("ANDROID_BUILD_TOP");
   if (!top && (optind == argc || add_include)) {
@@ -587,21 +602,32 @@
   if (optind == argc) {
     // Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out.
     std::string versioner_dir = to_string(top) + "/bionic/tools/versioner";
-    header_dir = versioner_dir + "/current";
-    dependency_dir = versioner_dir + "/dependencies";
+    location.header_dir = versioner_dir + "/current";
+    location.dependency_dir = versioner_dir + "/dependencies";
     if (platform_dir.empty()) {
       platform_dir = versioner_dir + "/platforms";
     }
   } else {
-    if (!android::base::Realpath(argv[optind], &header_dir)) {
+    if (!android::base::Realpath(argv[optind], &location.header_dir)) {
       err(1, "failed to get realpath for path '%s'", argv[optind]);
     }
 
     if (argc - optind == 2) {
-      dependency_dir = argv[optind + 1];
+      location.dependency_dir = argv[optind + 1];
     }
   }
 
+  // Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify.
+  // This makes the files there impossible to build on their own.
+  if (ignore_fortify_headers) {
+    std::string fortify_path = location.header_dir;
+    if (!android::base::EndsWith(location.header_dir, "/")) {
+      fortify_path += '/';
+    }
+    fortify_path += "bits/fortify";
+    location.ignored_directories.insert(std::move(fortify_path));
+  }
+
   if (selected_levels.empty()) {
     selected_levels = supported_levels;
   }
@@ -612,10 +638,10 @@
 
 
   struct stat st;
-  if (stat(header_dir.c_str(), &st) != 0) {
-    err(1, "failed to stat '%s'", header_dir.c_str());
+  if (const char *dir = location.header_dir.c_str(); stat(dir, &st) != 0) {
+    err(1, "failed to stat '%s'", dir);
   } else if (!S_ISDIR(st.st_mode)) {
-    errx(1, "'%s' is not a directory", header_dir.c_str());
+    errx(1, "'%s' is not a directory", dir);
   }
 
   std::set<CompilationType> compilation_types;
@@ -631,7 +657,7 @@
 
   auto start = std::chrono::high_resolution_clock::now();
   std::unique_ptr<HeaderDatabase> declaration_database =
-      compileHeaders(compilation_types, header_dir, dependency_dir);
+      compileHeaders(compilation_types, location);
   auto end = std::chrono::high_resolution_clock::now();
 
   if (verbose) {
@@ -641,7 +667,7 @@
 
   bool failed = false;
   if (dump) {
-    declaration_database->dump(header_dir + "/");
+    declaration_database->dump(location.header_dir + "/");
   } else {
     if (!sanityCheck(declaration_database.get())) {
       printf("versioner: sanity check failed\n");
@@ -657,7 +683,7 @@
   }
 
   if (!preprocessor_output_path.empty() && (force || !failed)) {
-    failed = !preprocessHeaders(preprocessor_output_path, header_dir, declaration_database.get());
+    failed = !preprocessHeaders(preprocessor_output_path, location.header_dir, declaration_database.get());
   }
   return failed;
 }