Merge "Overalign the TLS segment using crtbegin"
diff --git a/libc/Android.bp b/libc/Android.bp
index 57d4039..570e785 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -2523,6 +2523,9 @@
     // Mark this library as global so it overrides all the allocation
     // definitions properly.
     ldflags: ["-Wl,-z,global"],
+
+    // Like libc, disable native coverage for libc_scudo.
+    native_coverage: false,
 }
 
 subdirs = [
diff --git a/libc/bionic/scudo/Android.bp b/libc/bionic/scudo/Android.bp
index 8b518bb..9b77c06 100644
--- a/libc/bionic/scudo/Android.bp
+++ b/libc/bionic/scudo/Android.bp
@@ -57,4 +57,7 @@
             version_script: "exported64.map",
         },
     },
+
+    // Like libc, disable native coverage for libscudo_wrapper.
+    native_coverage: false,
 }
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
index 718ee96..660dfca 100644
--- a/libc/include/bits/fortify/poll.h
+++ b/libc/include/bits/fortify/poll.h
@@ -37,15 +37,18 @@
 #if defined(__BIONIC_FORTIFY)
 #if __ANDROID_API__ >= __ANDROID_API_M__
 
+#define __bos_fd_count_trivially_safe(bos_val, fds, fd_count)              \
+  __bos_dynamic_check_impl_and((bos_val), >=, (sizeof(*fds) * (fd_count)), \
+                               (fd_count) <= __BIONIC_CAST(static_cast, nfds_t, -1) / sizeof(*fds))
+
 __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,
+    __clang_error_if(__bos_unevaluated_lt(__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) {
+  if (__bos_fd_count_trivially_safe(bos_fds, fds, fd_count)) {
     return __call_bypassing_fortify(poll)(fds, fd_count, timeout);
   }
   return __poll_chk(fds, fd_count, timeout, bos_fds);
@@ -54,12 +57,11 @@
 __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,
+    __clang_error_if(__bos_unevaluated_lt(__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) {
+  if (__bos_fd_count_trivially_safe(bos_fds, fds, fd_count)) {
     return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask);
   }
   return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds);
@@ -69,17 +71,18 @@
 __BIONIC_FORTIFY_INLINE
 int ppoll64(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset64_t* mask)
     __overloadable
-    __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
-                       __bos(fds) < sizeof(*fds) * fd_count,
+    __clang_error_if(__bos_unevaluated_lt(__bos(fds), sizeof(*fds) * fd_count),
                      "in call to 'ppoll64', fd_count is larger than the given buffer") {
   size_t bos_fds = __bos(fds);
 
-  if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+  if (__bos_fd_count_trivially_safe(bos_fds, fds, fd_count)) {
     return __call_bypassing_fortify(ppoll64)(fds, fd_count, timeout, mask);
   }
   return __ppoll64_chk(fds, fd_count, timeout, mask, bos_fds);
 }
 #endif
 
+#undef __bos_fd_count_trivially_safe
+
 #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
index 3d070c5..35fad3d 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -37,18 +37,15 @@
 
 #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 __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) {
+    __clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
+                     "'recvfrom' called with size bigger than buffer") {
   size_t bos = __bos0(buf);
 
-  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+  if (__bos_trivially_not_lt(bos, len)) {
     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);
@@ -59,11 +56,11 @@
 __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) {
+    __clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
+                     "'sendto' called with size bigger than buffer") {
   size_t bos = __bos0(buf);
 
-  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+  if (__bos_trivially_not_lt(bos, len)) {
     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);
@@ -73,7 +70,7 @@
 __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,
+    __clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
                      "'recv' called with size bigger than buffer") {
   return recvfrom(socket, buf, len, flags, NULL, 0);
 }
@@ -81,11 +78,9 @@
 __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,
+    __clang_error_if(__bos_unevaluated_lt(__bos0(buf), len),
                      "'send' called with size bigger than buffer") {
   return sendto(socket, buf, len, flags, NULL, 0);
 }
 
-#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
index b248aca..30c8362 100644
--- a/libc/include/bits/fortify/stat.h
+++ b/libc/include/bits/fortify/stat.h
@@ -33,7 +33,6 @@
 mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
 
 #if defined(__BIONIC_FORTIFY)
-#define __umask_invalid_mode_str "'umask' called with invalid mode"
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
 /* Abuse enable_if to make this an overload of umask. */
@@ -41,11 +40,9 @@
 mode_t umask(mode_t mode)
     __overloadable
     __enable_if(1, "")
-    __clang_error_if(mode & ~0777, __umask_invalid_mode_str) {
+    __clang_error_if(mode & ~0777, "'umask' called with invalid mode") {
   return __umask_chk(mode);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
 
-#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
index 0b5700a..6e47daf 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -57,8 +57,7 @@
 __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),
+    __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)),
                 "format string will always overflow destination buffer")
     __errorattr("format string will always overflow destination buffer");
 
@@ -75,8 +74,7 @@
 __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),
+    __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)),
                 "format string will always overflow destination buffer")
     __errorattr("format string will always overflow destination buffer");
 
@@ -91,16 +89,20 @@
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
 #if __ANDROID_API__ >= __ANDROID_API_N__
+#define __bos_trivially_not_lt_mul(bos_val, size, count) \
+  __bos_dynamic_check_impl_and(bos_val, >=, (size) * (count), \
+                               !__unsafe_check_mul_overflow(size, count))
+
 __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),
+        __clang_error_if(__bos_unevaluated_lt(__bos0(buf), size * count),
                          "in call to 'fread', size * count is too large for the given buffer") {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_mul(bos, size, count)) {
         return __call_bypassing_fortify(fread)(buf, size, count, stream);
     }
     return __fread_chk(buf, size, count, stream, bos);
@@ -111,16 +113,17 @@
         __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),
+        __clang_error_if(__bos_unevaluated_lt(__bos0(buf), size * count),
                          "in call to 'fwrite', size * count is too large for the given buffer") {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_mul(bos, size, count)) {
         return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
     }
 
     return __fwrite_chk(buf, size, count, stream, bos);
 }
+#undef __bos_trivially_not_lt_mul
 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
@@ -128,11 +131,11 @@
 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),
+        __clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
                          "in call to 'fgets', size is larger than the destination buffer") {
     size_t bos = __bos(dest);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_dynamic_check_impl_and(bos, >=, (size_t)size, size >= 0)) {
         return __call_bypassing_fortify(fgets)(dest, size, stream);
     }
 
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
index d47c0b0..0bb3d0d 100644
--- a/libc/include/bits/fortify/stdlib.h
+++ b/libc/include/bits/fortify/stdlib.h
@@ -31,18 +31,16 @@
 #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
 
 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)
+        __clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX),
+                         "'realpath' output parameter must be NULL or a pointer to a buffer "
+                         "with >= PATH_MAX bytes")
         __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?");
 /* No need for a definition; the only issues we can catch are at compile-time. */
 
 #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
index 14bb133..1e12986 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -44,17 +44,25 @@
 __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,
+        __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
                          "'memcpy' called with size bigger than buffer") {
-    return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+    size_t bos_dst = __bos0(dst);
+    if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
+        return __builtin_memcpy(dst, src, copy_amount);
+    }
+    return __builtin___memcpy_chk(dst, src, copy_amount, bos_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,
+        __clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
                          "'memmove' called with size bigger than buffer") {
-    return __builtin___memmove_chk(dst, src, len, __bos0(dst));
+    size_t bos_dst = __bos0(dst);
+    if (__bos_trivially_not_lt(bos_dst, len)) {
+        return __builtin_memmove(dst, src, len);
+    }
+    return __builtin___memmove_chk(dst, src, len, bos_dst);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
@@ -62,10 +70,13 @@
 __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),
+        __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'stpcpy' called with string bigger than buffer") {
-    return __builtin___stpcpy_chk(dst, src, __bos(dst));
+    size_t bos_dst = __bos(dst);
+    if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
+        return __builtin_stpcpy(dst, src);
+    }
+    return __builtin___stpcpy_chk(dst, src, bos_dst);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
 
@@ -73,10 +84,13 @@
 __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),
+        __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'strcpy' called with string bigger than buffer") {
-    return __builtin___strcpy_chk(dst, src, __bos(dst));
+    size_t bos_dst = __bos(dst);
+    if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
+        return __builtin_strcpy(dst, src);
+    }
+    return __builtin___strcpy_chk(dst, src, bos_dst);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -92,11 +106,15 @@
 __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,
+        __clang_error_if(__bos_unevaluated_lt(__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));
+    size_t bos = __bos0(s);
+    if (__bos_trivially_not_lt(bos, n)) {
+        return __builtin_memset(s, c, n);
+    }
+    return __builtin___memset_chk(s, c, n, bos);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
@@ -105,7 +123,7 @@
 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) {
+    if (__bos_trivially_ge(bos, n)) {
         return __builtin_memchr(s, c, n);
     }
 
@@ -116,7 +134,7 @@
 void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
     size_t bos = __bos(s);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_ge(bos, n)) {
         return __memrchr_real(s, c, n);
     }
 
@@ -177,24 +195,11 @@
     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) {
+    if (__bos_trivially_gt(bos, __builtin_strlen(s))) {
         return __builtin_strlen(s);
     }
 
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
index a07907b..543c3c7 100644
--- a/libc/include/bits/fortify/unistd.h
+++ b/libc/include/bits/fortify/unistd.h
@@ -63,9 +63,12 @@
     __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), \
+    __clang_error_if(__bos_unevaluated_lt((objsize), (what)), \
                      "in call to '" #fn "', '" #what "' bytes overflows the given object")
 
+#define __bos_trivially_not_lt_no_overflow(bos_val, index)  \
+      __bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX)
+
 #if __ANDROID_API__ >= __ANDROID_API_N__
 __BIONIC_FORTIFY_INLINE
 char* getcwd(char* const __pass_object_size buf, size_t size)
@@ -73,7 +76,7 @@
         __error_if_overflows_objectsize(size, __bos(buf), getcwd) {
     size_t bos = __bos(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt(bos, size)) {
         return __call_bypassing_fortify(getcwd)(buf, size);
     }
 
@@ -89,7 +92,7 @@
         __error_if_overflows_objectsize(count, __bos0(buf), pread) {
     size_t bos = __bos0(buf);
 
-    if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, count)) {
         return __PREAD_PREFIX(real)(fd, buf, count, offset);
     }
 
@@ -103,7 +106,7 @@
         __error_if_overflows_objectsize(count, __bos0(buf), pread64) {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, count)) {
         return __pread64_real(fd, buf, count, offset);
     }
 
@@ -119,7 +122,7 @@
         __error_if_overflows_objectsize(count, __bos0(buf), pwrite) {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, count)) {
         return __PWRITE_PREFIX(real)(fd, buf, count, offset);
     }
 
@@ -133,7 +136,7 @@
         __error_if_overflows_objectsize(count, __bos0(buf), pwrite64) {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, count)) {
         return __pwrite64_real(fd, buf, count, offset);
     }
 
@@ -149,7 +152,7 @@
         __error_if_overflows_objectsize(count, __bos0(buf), read) {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, count)) {
         return __call_bypassing_fortify(read)(fd, buf, count);
     }
 
@@ -165,7 +168,7 @@
         __error_if_overflows_objectsize(count, __bos0(buf), write) {
     size_t bos = __bos0(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, count)) {
         return __call_bypassing_fortify(write)(fd, buf, count);
     }
 
@@ -181,7 +184,7 @@
         __error_if_overflows_objectsize(size, __bos(buf), readlink) {
     size_t bos = __bos(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, size)) {
         return __call_bypassing_fortify(readlink)(path, buf, size);
     }
 
@@ -195,7 +198,7 @@
         __error_if_overflows_objectsize(size, __bos(buf), readlinkat) {
     size_t bos = __bos(buf);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    if (__bos_trivially_not_lt_no_overflow(bos, size)) {
         return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
     }
 
@@ -203,6 +206,7 @@
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
 
+#undef __bos_trivially_not_lt_no_overflow
 #undef __enable_if_no_overflow_ssizet
 #undef __error_if_overflows_objectsize
 #undef __error_if_overflows_ssizet
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index ca9374e..dceb116 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -289,6 +289,30 @@
 #define __pass_object_size __pass_object_size_n(__bos_level)
 #define __pass_object_size0 __pass_object_size_n(0)
 
+/* Intended for use in unevaluated contexts, e.g. diagnose_if conditions. */
+#define __bos_unevaluated_lt(bos_val, val) \
+  ((bos_val) != __BIONIC_FORTIFY_UNKNOWN_SIZE && (bos_val) < (val))
+
+#define __bos_unevaluated_le(bos_val, val) \
+  ((bos_val) != __BIONIC_FORTIFY_UNKNOWN_SIZE && (bos_val) <= (val))
+
+/* Intended for use in evaluated contexts. */
+#define __bos_dynamic_check_impl_and(bos_val, op, index, cond) \
+  (bos_val == __BIONIC_FORTIFY_UNKNOWN_SIZE ||                 \
+   (__builtin_constant_p(index) && bos_val op index && (cond)))
+
+#define __bos_dynamic_check_impl(bos_val, op, index) \
+  __bos_dynamic_check_impl_and(bos_val, op, index, 1)
+
+#define __bos_trivially_ge(bos_val, index) __bos_dynamic_check_impl((bos_val), >=, (index))
+
+#define __bos_trivially_gt(bos_val, index) __bos_dynamic_check_impl((bos_val), >, (index))
+
+/* The names here are meant to match nicely with the __bos_unevaluated macros above. */
+#define __bos_trivially_not_lt __bos_trivially_ge
+#define __bos_trivially_not_le __bos_trivially_gt
+
+
 #if defined(__BIONIC_FORTIFY) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
 #  define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
 #endif
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 53fcead..c030d54 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -252,12 +252,19 @@
   return g_debug->GetPointer(header);
 }
 
+extern "C" void __asan_init() __attribute__((weak));
+
 bool debug_initialize(const MallocDispatch* malloc_dispatch, bool* zygote_child,
                       const char* options) {
   if (zygote_child == nullptr || options == nullptr) {
     return false;
   }
 
+  if (__asan_init != 0) {
+    error_log("malloc debug cannot be enabled alongside ASAN");
+    return false;
+  }
+
   InitAtfork();
 
   g_zygote_child = zygote_child;
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index f4428eb..215ad05 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -72,9 +72,9 @@
 
 struct android_namespace_t {
  public:
-  android_namespace_t() : name_(nullptr), is_isolated_(false), is_greylist_enabled_(false) {}
+  android_namespace_t() : is_isolated_(false), is_greylist_enabled_(false) {}
 
-  const char* get_name() const { return name_; }
+  const char* get_name() const { return name_.c_str(); }
   void set_name(const char* name) { name_ = name; }
 
   bool is_isolated() const { return is_isolated_; }
@@ -161,7 +161,7 @@
   soinfo_list_t get_shared_group();
 
  private:
-  const char* name_;
+  std::string name_;
   bool is_isolated_;
   bool is_greylist_enabled_;
   std::vector<std::string> ld_library_paths_;
diff --git a/tests/libs/bionic_tests_zipalign.cpp b/tests/libs/bionic_tests_zipalign.cpp
index ec500d4..adb731f 100644
--- a/tests/libs/bionic_tests_zipalign.cpp
+++ b/tests/libs/bionic_tests_zipalign.cpp
@@ -37,7 +37,7 @@
   fprintf(stderr, "    The output zip file that will be created from the input file.\n");
 }
 
-using ZipData = std::pair<std::unique_ptr<ZipEntry>, std::unique_ptr<ZipString>>;
+using ZipData = std::pair<std::unique_ptr<ZipEntry>, std::string>;
 
 static bool GetEntries(ZipArchiveHandle handle, std::vector<ZipData>* entries) {
   void* cookie;
@@ -48,10 +48,9 @@
   }
 
   ZipEntry entry;
-  ZipString name;
+  std::string name;
   while ((return_value = Next(cookie, &entry, &name)) == 0) {
-    entries->emplace_back(std::make_pair(std::make_unique<ZipEntry>(entry),
-                                         std::make_unique<ZipString>(name)));
+    entries->emplace_back(std::make_pair(std::make_unique<ZipEntry>(entry), name));
   }
   if (return_value != -1) {
     fprintf(stderr, "Error while iterating over zip entries: %s\n", ErrorCodeString(return_value));
@@ -78,13 +77,12 @@
   int32_t error;
   for (auto& entry : entries) {
     ZipEntry* zip_entry = entry.first.get();
-    ZipString* zip_str = entry.second.get();
+    std::string& zip_name = entry.second;
 
     size_t flags = 0;
     if ((zip_entry->method & kCompressDeflated) != 0) {
       flags |= ZipWriter::kCompress;
     }
-    std::string zip_name(reinterpret_cast<const char*>(zip_str->name), zip_str->name_length);
     error = writer.StartAlignedEntry(zip_name.c_str(), flags, alignment);
     if (error != 0) {
       fprintf(stderr, "StartAlignedEntry failed: %s\n", ZipWriter::ErrorCodeString(error));