Merge "libc_malloc_[debug|hooks] are not available for platform"
diff --git a/benchmarks/ctype_benchmark.cpp b/benchmarks/ctype_benchmark.cpp
index 3c7f48d..eab0133 100644
--- a/benchmarks/ctype_benchmark.cpp
+++ b/benchmarks/ctype_benchmark.cpp
@@ -19,6 +19,63 @@
 #include <benchmark/benchmark.h>
 #include "util.h"
 
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalnum_y1, isalnum('A'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalnum_y2, isalnum('a'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalnum_y3, isalnum('0'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalnum_n, isalnum('_'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalpha_y1, isalpha('A'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalpha_y2, isalpha('a'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isalpha_n, isalpha('_'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isascii_y, isascii('x'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isascii_n, isascii(0x88));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isblank_y1, isblank(' '));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isblank_y2, isblank('\t'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isblank_n, isblank('_'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_iscntrl_y1, iscntrl('\b'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_iscntrl_y2, iscntrl('\x7f'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_iscntrl_n, iscntrl('_'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isdigit_y, iscntrl('0'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isdigit_n, iscntrl('_'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isgraph_y1, isgraph('A'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isgraph_y2, isgraph('a'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isgraph_y3, isgraph('0'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isgraph_y4, isgraph('_'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isgraph_n, isgraph(' '));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_islower_y, islower('x'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_islower_n, islower('X'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isprint_y1, isprint('A'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isprint_y2, isprint('a'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isprint_y3, isprint('0'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isprint_y4, isprint('_'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isprint_y5, isprint(' '));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isprint_n, isprint('\b'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_ispunct_y, ispunct('_'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_ispunct_n, ispunct('A'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isspace_y1, isspace(' '));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isspace_y2, isspace('\t'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isspace_n, isspace('A'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isupper_y, isupper('X'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isupper_n, isupper('x'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isxdigit_y1, isxdigit('0'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isxdigit_y2, isxdigit('a'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isxdigit_y3, isxdigit('A'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_isxdigit_n, isxdigit('_'));
+
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_toascii_y, isascii('x'));
+BIONIC_TRIVIAL_BENCHMARK(BM_ctype_toascii_n, isascii(0x88));
+
 BIONIC_TRIVIAL_BENCHMARK(BM_ctype_tolower_y, tolower('X'));
 BIONIC_TRIVIAL_BENCHMARK(BM_ctype_tolower_n, tolower('x'));
 
diff --git a/libc/Android.bp b/libc/Android.bp
index 3653f45..3e2ee1d 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -438,7 +438,6 @@
         "upstream-openbsd/lib/libc/gen/fnmatch.c",
         "upstream-openbsd/lib/libc/gen/ftok.c",
         "upstream-openbsd/lib/libc/gen/getprogname.c",
-        "upstream-openbsd/lib/libc/gen/isctype.c",
         "upstream-openbsd/lib/libc/gen/setprogname.c",
         "upstream-openbsd/lib/libc/gen/verr.c",
         "upstream-openbsd/lib/libc/gen/verrx.c",
@@ -1526,6 +1525,22 @@
     ],
 }
 
+// Versions of dl_iterate_phdr and similar APIs used to lookup unwinding information in a static
+// executable.
+cc_library_static {
+    name: "libc_unwind_static",
+    defaults: ["libc_defaults"],
+    cflags: ["-DLIBC_STATIC"],
+
+    srcs: ["bionic/dl_iterate_phdr_static.cpp"],
+    arch: {
+        // arm32-specific dl_unwind_find_exidx and __gnu_Unwind_Find_exidx APIs
+        arm: {
+            srcs: ["arch-arm/bionic/exidx_static.c"],
+        },
+    },
+}
+
 // ========================================================
 // libc_nomalloc.a
 // ========================================================
@@ -1538,20 +1553,13 @@
 
 cc_library_static {
     name: "libc_nomalloc",
-
     defaults: ["libc_defaults"],
-
-    arch: {
-        arm: {
-            srcs: ["arch-arm/bionic/exidx_static.c"],
-        },
-    },
-
     cflags: ["-DLIBC_STATIC"],
 
     whole_static_libs: [
         "libc_common_static",
         "libc_init_static",
+        "libc_unwind_static",
     ],
 }
 
@@ -1573,7 +1581,6 @@
 filegroup {
     name: "libc_sources_static",
     srcs: [
-        "bionic/dl_iterate_phdr_static.cpp",
         "bionic/malloc_common.cpp",
         "bionic/malloc_limit.cpp",
     ],
@@ -1587,11 +1594,6 @@
     ],
 }
 
-filegroup {
-    name: "libc_sources_static_arm",
-    srcs: [ "arch-arm/bionic/exidx_static.c" ],
-}
-
 // ========================================================
 // libc.a + libc.so
 // ========================================================
@@ -1614,6 +1616,7 @@
         whole_static_libs: [
             "libc_init_static",
             "libc_common_static",
+            "libc_unwind_static",
         ],
     },
     shared: {
@@ -1663,9 +1666,6 @@
                 // special for arm
                 cflags: ["-DCRT_LEGACY_WORKAROUND"],
             },
-            static: {
-                srcs: [":libc_sources_static_arm"],
-            },
 
             // Arm 32 bit does not produce complete exidx unwind information
             // so keep the .debug_frame which is relatively small and does
diff --git a/libc/arch-arm/bionic/exidx_static.c b/libc/arch-arm/bionic/exidx_static.c
index ef3745f..9830c54 100644
--- a/libc/arch-arm/bionic/exidx_static.c
+++ b/libc/arch-arm/bionic/exidx_static.c
@@ -43,7 +43,11 @@
 extern struct exidx_entry __exidx_end;
 extern struct exidx_entry __exidx_start;
 
-_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc __attribute__((unused)), int* pcount) {
+_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc __attribute__((unused)), int* pcount) {
   *pcount = (&__exidx_end - &__exidx_start);
   return (_Unwind_Ptr)&__exidx_start;
 }
+
+_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int *pcount) {
+  return dl_unwind_find_exidx(pc, pcount);
+}
diff --git a/libc/bionic/ctype.cpp b/libc/bionic/ctype.cpp
index b72935b..ba8afca 100644
--- a/libc/bionic/ctype.cpp
+++ b/libc/bionic/ctype.cpp
@@ -28,70 +28,146 @@
 
 #include <ctype.h>
 
+static inline int __in_range(int c, char lo, char hi) {
+  return c >= lo && c <= hi;
+}
+
+int isalnum(int c) {
+  // `isalnum(c)` is `isalpha(c) || isdigit(c)`, but there's no obvious way
+  // to simplify that, and the table lookup is just slightly faster...
+  // Note that this is unsafe for inputs less than -1 (EOF) or greater than
+  // 0xff. This is true of other C libraries too.
+  return (_ctype_[c + 1] & (_CTYPE_U|_CTYPE_L|_CTYPE_N));
+}
+
 int isalnum_l(int c, locale_t) {
   return isalnum(c);
 }
 
+int isalpha(int c) {
+  return __in_range(c, 'A', 'Z') || __in_range(c, 'a', 'z');
+}
+
 int isalpha_l(int c, locale_t) {
   return isalpha(c);
 }
 
+int isascii(int c) {
+  return static_cast<unsigned>(c) < 0x80;
+}
+
+int isblank(int c) {
+  return c == ' ' || c == '\t';
+}
+
 int isblank_l(int c, locale_t) {
   return isblank(c);
 }
 
+int iscntrl(int c) {
+  return (static_cast<unsigned>(c) < ' ') || c == 0x7f;
+}
+
 int iscntrl_l(int c, locale_t) {
   return iscntrl(c);
 }
 
+int isdigit(int c) {
+  return __in_range(c, '0', '9');
+}
+
 int isdigit_l(int c, locale_t) {
   return isdigit(c);
 }
 
+int isgraph(int c) {
+  return __in_range(c, '!', '~');
+}
+
 int isgraph_l(int c, locale_t) {
   return isgraph(c);
 }
 
+int islower(int c) {
+  return __in_range(c, 'a', 'z');
+}
+
 int islower_l(int c, locale_t) {
   return islower(c);
 }
 
+int isprint(int c) {
+  return __in_range(c, ' ', '~');
+}
+
 int isprint_l(int c, locale_t) {
   return isprint(c);
 }
 
+int ispunct(int c) {
+  // `ispunct(c)` is `isgraph(c) && !isalnum(c)`, but there's no obvious way
+  // to simplify that, and the table lookup is just slightly faster...
+  // Note that this is unsafe for inputs less than -1 (EOF) or greater than
+  // 0xff. This is true of other C libraries too.
+  return (_ctype_[c + 1] & _CTYPE_P);
+}
+
 int ispunct_l(int c, locale_t) {
   return ispunct(c);
 }
 
+int isspace(int c) {
+  return c == ' ' || __in_range(c, '\t', '\r');
+}
+
 int isspace_l(int c, locale_t) {
   return isspace(c);
 }
 
+int isupper(int c) {
+  return __in_range(c, 'A', 'Z');
+}
+
 int isupper_l(int c, locale_t) {
   return isupper(c);
 }
 
+int isxdigit(int c) {
+  return __in_range(c, '0', '9') || __in_range(c, 'a', 'f') || __in_range(c, 'A', 'F');
+}
+
 int isxdigit_l(int c, locale_t) {
   return isxdigit(c);
 }
 
+int toascii(int c) {
+  return c & 0x7f;
+}
+
+int _toupper(int c) {
+  // Using EOR rather than AND makes no difference on arm, but saves an
+  // instruction on arm64.
+  return c ^ 0x20;
+}
+
+int toupper(int c) {
+  if (c >= 'a' && c <= 'z') return _toupper(c);
+  return c;
+}
+
 int toupper_l(int c, locale_t) {
   return toupper(c);
 }
 
-int tolower_l(int c, locale_t) {
-  return tolower(c);
+int _tolower(int c) {
+  return c | 0x20;
 }
 
 int tolower(int c) {
-  if (c >= 'A' && c <= 'Z') return c | 0x20;
+  if (c >= 'A' && c <= 'Z') return _tolower(c);
   return c;
 }
 
-int toupper(int c) {
-  // Using EOR rather than AND makes no difference on arm, but saves an
-  // instruction on arm64.
-  if (c >= 'a' && c <= 'z') return c ^ 0x20;
-  return c;
+int tolower_l(int c, locale_t) {
+  return tolower(c);
 }
diff --git a/libc/bionic/open.cpp b/libc/bionic/open.cpp
index df5ab21..222e5d3 100644
--- a/libc/bionic/open.cpp
+++ b/libc/bionic/open.cpp
@@ -70,7 +70,6 @@
   if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode");
   return __openat(AT_FDCWD, pathname, force_O_LARGEFILE(flags), 0);
 }
-__strong_alias(__open64_2, __open_2);
 
 int openat(int fd, const char *pathname, int flags, ...) {
   mode_t mode = 0;
@@ -90,4 +89,3 @@
   if (needs_mode(flags)) __fortify_fatal("open: called with O_CREAT/O_TMPFILE but no mode");
   return __openat(fd, pathname, force_O_LARGEFILE(flags), 0);
 }
-__strong_alias(__openat64_2, __openat_2);
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 0dbf539..1dc1066 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -344,6 +344,8 @@
         name);
 }
 
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
+
 __attribute__((no_sanitize("hwaddress")))
 static int __pthread_start(void* arg) {
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
@@ -358,6 +360,7 @@
 
   __set_stack_and_tls_vma_name(false);
   __init_additional_stacks(thread);
+  __rt_sigprocmask(SIG_SETMASK, &thread->start_mask, nullptr, sizeof(thread->start_mask));
 
   void* result = thread->start_routine(thread->start_routine_arg);
   pthread_exit(result);
@@ -420,7 +423,12 @@
   __init_user_desc(&tls_descriptor, false, tls);
   tls = &tls_descriptor;
 #endif
+
+  sigset64_t block_all_mask;
+  sigfillset64(&block_all_mask);
+  __rt_sigprocmask(SIG_SETMASK, &block_all_mask, &thread->start_mask, sizeof(thread->start_mask));
   int rc = clone(__pthread_start, child_stack, flags, thread, &(thread->tid), tls, &(thread->tid));
+  __rt_sigprocmask(SIG_SETMASK, &thread->start_mask, nullptr, sizeof(thread->start_mask));
   if (rc == -1) {
     int clone_errno = errno;
     // We don't have to unlock the mutex at all because clone(2) failed so there's no child waiting to
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 22cc400..22b0558 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -98,6 +98,7 @@
   void* (*start_routine)(void*);
   void* start_routine_arg;
   void* return_value;
+  sigset64_t start_mask;
 
   void* alternate_signal_stack;
 
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index af7cde1..4a3d052 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -37,70 +37,89 @@
 
 __BEGIN_DECLS
 
-#ifndef __ANDROID_API_FUTURE__
 /**
  * Magic version number for an Android OS build which has
  * not yet turned into an official release,
- * for comparisons against __ANDROID_API__.
+ * for comparison against `__ANDROID_API__`.
  */
 #define __ANDROID_API_FUTURE__ 10000
-#endif
 
+/* This #ifndef should never be true except when doxygen is generating docs. */
 #ifndef __ANDROID_API__
 /**
  * `__ANDROID_API__` is the API level being targeted. For the OS,
  * this is `__ANDROID_API_FUTURE__`. For the NDK, this is set by the
- * compiler/build system based on the API level you claimed to target.
+ * compiler system based on the API level you claimed to target.
  */
 #define __ANDROID_API__ __ANDROID_API_FUTURE__
 #endif
 
-/** Names the Gingerbread API level (9), for comparisons against __ANDROID_API__. */
+#if __ANDROID_API__ != __ANDROID_API_FUTURE__
+/**
+ * `__ANDROID_NDK__` is defined for code that's built by the NDK
+ * rather than as part of the OS. "Built by the NDK" is an ambiguous idea,
+ * so you might prefer to check `__ANDROID__`, `__BIONIC__`, `__linux__`,
+ * or `__NDK_MAJOR__` instead, depending on exactly what you're trying to say.
+ *
+ * `__ANDROID_NDK__` is intended to capture "this code is being built for
+ * Android, but targeting a specific API level". This is true for all code built
+ * by the NDK proper, but also for OS code that sets `sdk_version` in its build
+ * file. This distinction might matter to you if, for example, your code could
+ * be built as part of an app *or* as part of the OS.
+ */
+#define __ANDROID_NDK__ 1
+#endif
+
+/** Names the Gingerbread API level (9), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_G__ 9
 
-/** Names the Ice-Cream Sandwich API level (14), for comparisons against __ANDROID_API__. */
+/** Names the Ice-Cream Sandwich API level (14), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_I__ 14
 
-/** Names the Jellybean API level (16), for comparisons against __ANDROID_API__. */
+/** Names the Jellybean API level (16), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_J__ 16
 
-/** Names the Jellybean MR1 API level (17), for comparisons against __ANDROID_API__. */
+/** Names the Jellybean MR1 API level (17), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_J_MR1__ 17
 
-/** Names the Jellybean MR2 API level (18), for comparisons against __ANDROID_API__. */
+/** Names the Jellybean MR2 API level (18), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_J_MR2__ 18
 
-/** Names the KitKat API level (19), for comparisons against __ANDROID_API__. */
+/** Names the KitKat API level (19), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_K__ 19
 
-/** Names the Lollipop API level (21), for comparisons against __ANDROID_API__. */
+/** Names the Lollipop API level (21), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_L__ 21
 
-/** Names the Lollipop MR1 API level (22), for comparisons against __ANDROID_API__. */
+/** Names the Lollipop MR1 API level (22), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_L_MR1__ 22
 
-/** Names the Marshmallow API level (23), for comparisons against __ANDROID_API__. */
+/** Names the Marshmallow API level (23), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_M__ 23
 
-/** Names the Nougat API level (24), for comparisons against __ANDROID_API__. */
+/** Names the Nougat API level (24), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_N__ 24
 
-/** Names the Nougat MR1 API level (25), for comparisons against __ANDROID_API__. */
+/** Names the Nougat MR1 API level (25), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_N_MR1__ 25
 
-/** Names the Oreo API level (26), for comparisons against __ANDROID_API__. */
+/** Names the Oreo API level (26), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_O__ 26
 
-/** Names the Oreo MR1 API level (27), for comparisons against __ANDROID_API__. */
+/** Names the Oreo MR1 API level (27), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_O_MR1__ 27
 
-/** Names the Pie API level (28), for comparisons against __ANDROID_API__. */
+/** Names the Pie API level (28), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_P__ 28
 
-/** Names the "Q" API level (29), for comparisons against __ANDROID_API__. */
+/**
+ * Names the "Q" API level (29), for comparison against `__ANDROID_API__`.
+ * This release was called Android 10 publicly, not to be (but sure to be)
+ * confused with API level 10.
+ */
 #define __ANDROID_API_Q__ 29
 
-/** Names the "R" API level (30), for comparisons against __ANDROID_API__. */
+/** Names the "R" API level (30), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_R__ 30
 
 /**
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
index 4bb441e..ded62ee 100644
--- a/libc/include/bits/fortify/fcntl.h
+++ b/libc/include/bits/fortify/fcntl.h
@@ -45,7 +45,6 @@
 /* O_TMPFILE shares bits with O_DIRECTORY. */
 #define __open_modes_useful(flags) (((flags) & O_CREAT) || ((flags) & O_TMPFILE) == O_TMPFILE)
 
-#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);
@@ -60,7 +59,11 @@
 int open(const char* const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'open' " __open_too_few_args_error) {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     return __open_2(pathname, flags);
+#else
+    return __open_real(pathname, flags);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -80,7 +83,11 @@
 int openat(int dirfd, const char* const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'openat' " __open_too_few_args_error) {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     return __openat_2(dirfd, pathname, flags);
+#else
+    return __openat_real(dirfd, pathname, flags);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -90,13 +97,9 @@
                            "'openat' " __open_useless_modes_warning) {
     return __openat_real(dirfd, pathname, flags, modes);
 }
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
-#if __ANDROID_API__ >= __ANDROID_API_R__
-int __open64_2(const char*, int) __INTRODUCED_IN(30);
-int __openat64_2(int, const char*, int) __INTRODUCED_IN(30);
-int __open64_real(const char* __path, int __flags, ...) __RENAME(open64);
-int __openat64_real(int, const char*, int, ...) __RENAME(openat64);
+#if __ANDROID_API__ >= __ANDROID_API_L__
+/* Note that open == open64, so we reuse those bits in the open64 variants below.  */
 
 __BIONIC_ERROR_FUNCTION_VISIBILITY
 int open64(const char* pathname, int flags, mode_t modes, ...) __overloadable
@@ -106,7 +109,7 @@
 int open64(const char* const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'open64' " __open_too_few_args_error) {
-    return __open64_2(pathname, flags);
+    return __open_2(pathname, flags);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -114,7 +117,7 @@
         __overloadable
         __clang_warning_if(!__open_modes_useful(flags) && modes,
                            "'open64' " __open_useless_modes_warning) {
-    return __open64_real(pathname, flags, modes);
+    return __open_real(pathname, flags, modes);
 }
 
 __BIONIC_ERROR_FUNCTION_VISIBILITY
@@ -126,7 +129,7 @@
 int openat64(int dirfd, const char* const __pass_object_size pathname, int flags)
         __overloadable
         __clang_error_if(__open_modes_useful(flags), "'openat64' " __open_too_few_args_error) {
-    return __openat64_2(dirfd, pathname, flags);
+    return __openat_2(dirfd, pathname, flags);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -134,9 +137,9 @@
         __overloadable
         __clang_warning_if(!__open_modes_useful(flags) && modes,
                            "'openat64' " __open_useless_modes_warning) {
-    return __openat64_real(dirfd, pathname, flags, modes);
+    return __openat_real(dirfd, pathname, flags, modes);
 }
-#endif /* __ANDROID_API__ >= __ANDROID_API_R__ */
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
 
 #undef __open_too_many_args_error
 #undef __open_too_few_args_error
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index 9be2b1a..bd36483 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -46,7 +46,7 @@
 void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
         __overloadable {
     size_t bos_dst = __bos0(dst);
-    if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
+    if (__bos_trivially_ge(bos_dst, copy_amount)) {
         return __builtin_memcpy(dst, src, copy_amount);
     }
     return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
@@ -56,7 +56,7 @@
 __BIONIC_FORTIFY_INLINE
 void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) __overloadable {
     size_t bos_dst = __bos0(dst);
-    if (__bos_trivially_not_lt(bos_dst, len)) {
+    if (__bos_trivially_ge(bos_dst, len)) {
         return __builtin_memmove(dst, src, len);
     }
     return __builtin___memmove_chk(dst, src, len, bos_dst);
@@ -71,39 +71,40 @@
         __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
                          "'mempcpy' called with size bigger than buffer") {
     size_t bos_dst = __bos0(dst);
-    if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
+    if (__bos_trivially_ge(bos_dst, copy_amount)) {
         return __builtin_mempcpy(dst, src, copy_amount);
     }
     return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_R__ */
-#endif
+#endif /* __USE_GNU */
 
-#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_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'stpcpy' called with string bigger than buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_L__
     size_t bos_dst = __bos(dst);
-    if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
-        return __builtin_stpcpy(dst, src);
+    if (!__bos_trivially_gt(bos_dst, __builtin_strlen(src))) {
+        return __builtin___stpcpy_chk(dst, src, bos_dst);
     }
-    return __builtin___stpcpy_chk(dst, src, bos_dst);
-}
 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+    return __builtin_stpcpy(dst, src);
+}
 
-#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_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'strcpy' called with string bigger than buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     size_t bos_dst = __bos(dst);
-    if (__bos_trivially_not_le(bos_dst, __builtin_strlen(src))) {
-        return __builtin_strcpy(dst, src);
+    if (!__bos_trivially_gt(bos_dst, __builtin_strlen(src))) {
+        return __builtin___strcpy_chk(dst, src, bos_dst);
     }
-    return __builtin___strcpy_chk(dst, src, bos_dst);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+    return __builtin_strcpy(dst, src);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -111,27 +112,34 @@
         __overloadable
         __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'strcat' called with string bigger than buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     return __builtin___strcat_chk(dst, src, __bos(dst));
+#else
+    return __builtin_strcat(dst, src);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 }
 
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __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));
 }
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
 
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
         /* 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?") {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     size_t bos = __bos0(s);
-    if (__bos_trivially_not_lt(bos, n)) {
-        return __builtin_memset(s, c, n);
+    if (!__bos_trivially_ge(bos, n)) {
+        return __builtin___memset_chk(s, c, n, bos);
     }
-    return __builtin___memset_chk(s, c, n, bos);
-}
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+    return __builtin_memset(s, c, n);
+}
 
 #if __ANDROID_API__ >= __ANDROID_API_M__
 __BIONIC_FORTIFY_INLINE
@@ -189,19 +197,19 @@
 }
 #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
         __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
                          "'strlcpy' called with size bigger than buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     size_t bos = __bos(dst);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __call_bypassing_fortify(strlcpy)(dst, src, size);
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strlcpy_chk(dst, src, size, bos);
     }
-
-    return __strlcpy_chk(dst, src, size, bos);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+    return __call_bypassing_fortify(strlcpy)(dst, src, size);
 }
 
 __BIONIC_FORTIFY_INLINE
@@ -209,50 +217,51 @@
         __overloadable
         __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
                          "'strlcat' called with size bigger than buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     size_t bos = __bos(dst);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __call_bypassing_fortify(strlcat)(dst, src, size);
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strlcat_chk(dst, src, size, bos);
     }
-
-    return __strlcat_chk(dst, src, size, bos);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+    return __call_bypassing_fortify(strlcat)(dst, src, size);
 }
 
 __BIONIC_FORTIFY_INLINE
 size_t strlen(const char* const s __pass_object_size0) __overloadable {
     size_t bos = __bos0(s);
 
-    if (__bos_trivially_gt(bos, __builtin_strlen(s))) {
-        return __builtin_strlen(s);
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+    if (!__bos_trivially_gt(bos, __builtin_strlen(s))) {
+        return __strlen_chk(s, bos);
     }
-
-    return __strlen_chk(s, bos);
-}
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+    return __builtin_strlen(s);
+}
 
-#if  __ANDROID_API__ >= __ANDROID_API_J_MR2__
 __BIONIC_FORTIFY_INLINE
 char* strchr(const char* const s __pass_object_size, int c) __overloadable {
+#if  __ANDROID_API__ >= __ANDROID_API_J_MR2__
     size_t bos = __bos(s);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin_strchr(s, c);
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strchr_chk(s, c, bos);
     }
-
-    return __strchr_chk(s, c, bos);
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+    return __builtin_strchr(s, c);
 }
 
 __BIONIC_FORTIFY_INLINE
 char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
+#if  __ANDROID_API__ >= __ANDROID_API_J_MR2__
     size_t bos = __bos(s);
 
-    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
-        return __builtin_strrchr(s, c);
+    if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __strrchr_chk(s, c, bos);
     }
-
-    return __strrchr_chk(s, c, bos);
-}
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+    return __builtin_strrchr(s, c);
+}
 
 #if __ANDROID_API__ >= __ANDROID_API_M__
 #if defined(__cplusplus)
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
index dbc64c0..45ed2cf 100644
--- a/libc/include/bits/fortify/unistd.h
+++ b/libc/include/bits/fortify/unistd.h
@@ -76,7 +76,7 @@
 #if __ANDROID_API__ >= __ANDROID_API_N__
     size_t bos = __bos(buf);
 
-    if (!__bos_trivially_not_lt(bos, size)) {
+    if (!__bos_trivially_ge(bos, size)) {
         return __getcwd_chk(buf, size, bos);
     }
 #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
diff --git a/libc/include/ctype.h b/libc/include/ctype.h
index e91b0e2..e7df299 100644
--- a/libc/include/ctype.h
+++ b/libc/include/ctype.h
@@ -97,7 +97,7 @@
 int isspace(int __ch);
 /** Returns true if `ch` is in `[A-Z]`. */
 int isupper(int __ch);
-/** Returns true if `ch` is in `[0-9a-f]`. */
+/** Returns true if `ch` is in `[0-9A-Fa-f]`. */
 int isxdigit(int __ch);
 
 /** Returns the corresponding lower-case character if `ch` is upper-case, or `ch` otherwise. */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 689b650..b061c22 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -305,14 +305,8 @@
   __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/libc.map.txt b/libc/libc.map.txt
index 9b39bb8..a4ab600 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1483,8 +1483,6 @@
 LIBC_R { # introduced=R
   global:
     __mempcpy_chk;
-    __open64_2;
-    __openat64_2;
     __tls_get_addr; # arm64
     call_once;
     cnd_broadcast;
diff --git a/libc/upstream-openbsd/lib/libc/gen/isctype.c b/libc/upstream-openbsd/lib/libc/gen/isctype.c
deleted file mode 100644
index a4e944c..0000000
--- a/libc/upstream-openbsd/lib/libc/gen/isctype.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*	$OpenBSD: isctype.c,v 1.12 2015/09/13 11:38:08 guenther Exp $ */
-/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- */
-
-#define _ANSI_LIBRARY
-#include <ctype.h>
-#include <stdio.h>
-
-#undef isalnum
-int
-isalnum(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U|_L|_N)));
-}
-DEF_STRONG(isalnum);
-
-#undef isalpha
-int
-isalpha(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U|_L)));
-}
-DEF_STRONG(isalpha);
-
-#undef isblank
-int
-isblank(int c)
-{
-	return (c == ' ' || c == '\t');
-}
-DEF_STRONG(isblank);
-
-#undef iscntrl
-int
-iscntrl(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _C));
-}
-DEF_STRONG(iscntrl);
-
-#undef isdigit
-int
-isdigit(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _N));
-}
-DEF_STRONG(isdigit);
-
-#undef isgraph
-int
-isgraph(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_P|_U|_L|_N)));
-}
-DEF_STRONG(isgraph);
-
-#undef islower
-int
-islower(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _L));
-}
-DEF_STRONG(islower);
-
-#undef isprint
-int
-isprint(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_P|_U|_L|_N|_B)));
-}
-DEF_STRONG(isprint);
-
-#undef ispunct
-int
-ispunct(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _P));
-}
-DEF_STRONG(ispunct);
-
-#undef isspace
-int
-isspace(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _S));
-}
-DEF_STRONG(isspace);
-
-#undef isupper
-int
-isupper(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _U));
-}
-DEF_STRONG(isupper);
-
-#undef isxdigit
-int
-isxdigit(int c)
-{
-	return (c == EOF ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_N|_X)));
-}
-DEF_STRONG(isxdigit);
-
-#undef isascii
-int
-isascii(int c)
-{
-	return ((unsigned int)c <= 0177);
-}
-DEF_WEAK(isascii);
-
-#undef toascii
-int
-toascii(int c)
-{
-	return (c & 0177);
-}
-
-#undef _toupper
-int
-_toupper(int c)
-{
-	return (c - 'a' + 'A');
-}
-
-#undef _tolower
-int
-_tolower(int c)
-{
-	return (c - 'A' + 'a');
-}
diff --git a/libdl/libdl_static.cpp b/libdl/libdl_static.cpp
index 0a36e6f..3bbf963 100644
--- a/libdl/libdl_static.cpp
+++ b/libdl/libdl_static.cpp
@@ -41,9 +41,3 @@
 int dlclose(void* /*handle*/) {
   return -1;
 }
-
-#if defined(__arm__)
-_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr /*pc*/, int* /*pcount*/) {
-  return 0;
-}
-#endif
diff --git a/libm/Android.bp b/libm/Android.bp
index b7bae54..bf05b17 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -463,7 +463,6 @@
 
     cflags: [
         "-D__BIONIC_LP32_USE_LONG_DOUBLE",
-        "-D__BIONIC_NO_MATH_INLINES",
         "-D_BSD_SOURCE",
         "-DFLT_EVAL_METHOD=0",
         "-include freebsd-compat.h",
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 37a3189..cee9c3b 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -4208,7 +4208,7 @@
   if (insert_pos == std::string::npos) {
     insert_pos = ld_config_file_vndk.length();
   }
-  ld_config_file_vndk.insert(insert_pos, Config::get_vndk_version_string('.'));
+  ld_config_file_vndk.insert(insert_pos, Config::get_vndk_version_string("."));
   return ld_config_file_vndk;
 }
 
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 46c91a3..450d0e6 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -408,7 +408,7 @@
       params.push_back({ "SDK_VER", buf });
     }
 
-    static std::string vndk = Config::get_vndk_version_string('-');
+    static std::string vndk = Config::get_vndk_version_string("");
     params.push_back({ "VNDK_VER", vndk });
 
     for (auto& path : paths) {
@@ -596,11 +596,11 @@
   return true;
 }
 
-std::string Config::get_vndk_version_string(const char delimiter) {
+std::string Config::get_vndk_version_string(const std::string& prefix) {
   std::string version = android::base::GetProperty("ro.vndk.version", "");
   if (version != "" && version != "current") {
-    //add the delimiter char in front of the string and return it.
-    return version.insert(0, 1, delimiter);
+    //add the prefix in front of the string and return it.
+    return version.insert(0, prefix);
   }
   return "";
 }
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 75d9378..547c62e 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -164,7 +164,7 @@
                                  const Config** config,
                                  std::string* error_msg);
 
-  static std::string get_vndk_version_string(const char delimiter);
+  static std::string get_vndk_version_string(const std::string& prefix);
  private:
   void clear();
 
diff --git a/tests/ctype_test.cpp b/tests/ctype_test.cpp
index c12518b..826d39a 100644
--- a/tests/ctype_test.cpp
+++ b/tests/ctype_test.cpp
@@ -18,183 +18,278 @@
 
 #include <ctype.h>
 
+// We test from -1 (EOF) to 0xff, because that's the range for which behavior
+// is actually defined. (It's explicitly undefined below or above that.) Most
+// of our routines are no longer table-based and behave correctly for the
+// entire int range, but that's not true of other C libraries that we might
+// want to compare against, nor of our isalnum(3) and ispunt(3).
+static constexpr int kMin = -1;
+static constexpr int kMax = 256;
+
 TEST(ctype, isalnum) {
-  EXPECT_TRUE(isalnum('1'));
-  EXPECT_TRUE(isalnum('a'));
-  EXPECT_TRUE(isalnum('A'));
-  EXPECT_FALSE(isalnum('!'));
-  EXPECT_FALSE(isalnum(' '));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '0' && i <= '9') ||
+        (i >= 'A' && i <= 'Z') ||
+        (i >= 'a' && i <= 'z')) {
+      EXPECT_TRUE(isalnum(i)) << i;
+    } else {
+      EXPECT_FALSE(isalnum(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isalnum_l) {
-  EXPECT_TRUE(isalnum_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isalnum_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isalnum_l('A', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isalnum_l('!', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isalnum_l(' ', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '0' && i <= '9') ||
+        (i >= 'A' && i <= 'Z') ||
+        (i >= 'a' && i <= 'z')) {
+      EXPECT_TRUE(isalnum_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isalnum_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isalpha) {
-  EXPECT_FALSE(isalpha('1'));
-  EXPECT_TRUE(isalpha('a'));
-  EXPECT_TRUE(isalpha('A'));
-  EXPECT_FALSE(isalpha('!'));
-  EXPECT_FALSE(isalpha(' '));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= 'A' && i <= 'Z') ||
+        (i >= 'a' && i <= 'z')) {
+      EXPECT_TRUE(isalpha(i)) << i;
+    } else {
+      EXPECT_FALSE(isalpha(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isalpha_l) {
-  EXPECT_FALSE(isalpha_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isalpha_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isalpha_l('A', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isalpha_l('!', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isalpha_l(' ', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= 'A' && i <= 'Z') ||
+        (i >= 'a' && i <= 'z')) {
+      EXPECT_TRUE(isalpha_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isalpha_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isascii) {
-  EXPECT_TRUE(isascii('\x7f'));
-  EXPECT_FALSE(isascii('\x80'));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= 0 && i <= 0x7f) {
+      EXPECT_TRUE(isascii(i)) << i;
+    } else {
+      EXPECT_FALSE(isascii(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isblank) {
-  EXPECT_FALSE(isblank('1'));
-  EXPECT_TRUE(isblank(' '));
-  EXPECT_TRUE(isblank('\t'));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i == '\t' || i == ' ') {
+      EXPECT_TRUE(isblank(i)) << i;
+    } else {
+      EXPECT_FALSE(isblank(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isblank_l) {
-  EXPECT_FALSE(isblank_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isblank_l(' ', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isblank_l('\t', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i == '\t' || i == ' ') {
+      EXPECT_TRUE(isblank_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isblank_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, iscntrl) {
-  EXPECT_FALSE(iscntrl('1'));
-  EXPECT_TRUE(iscntrl('\b'));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= 0 && i < ' ') || i == 0x7f) {
+      EXPECT_TRUE(iscntrl(i)) << i;
+    } else {
+      EXPECT_FALSE(iscntrl(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, iscntrl_l) {
-  EXPECT_FALSE(iscntrl_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(iscntrl_l('\b', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= 0 && i < ' ') || i == 0x7f) {
+      EXPECT_TRUE(iscntrl_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(iscntrl_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isdigit) {
-  EXPECT_TRUE(isdigit('1'));
-  EXPECT_FALSE(isdigit('a'));
-  EXPECT_FALSE(isdigit('x'));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= '0' && i <= '9') {
+      EXPECT_TRUE(isdigit(i)) << i;
+    } else {
+      EXPECT_FALSE(isdigit(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isdigit_l) {
-  EXPECT_TRUE(isdigit_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isdigit_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isdigit_l('x', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= '0' && i <= '9') {
+      EXPECT_TRUE(isdigit_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isdigit_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isgraph) {
-  EXPECT_TRUE(isgraph('a'));
-  EXPECT_TRUE(isgraph('A'));
-  EXPECT_TRUE(isgraph('1'));
-  EXPECT_TRUE(isgraph('!'));
-  EXPECT_FALSE(isgraph(' '));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= '!' && i <= '~') {
+      EXPECT_TRUE(isgraph(i)) << i;
+    } else {
+      EXPECT_FALSE(isgraph(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isgraph_l) {
-  EXPECT_TRUE(isgraph_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isgraph_l('A', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isgraph_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isgraph_l('!', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isgraph_l(' ', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= '!' && i <= '~') {
+      EXPECT_TRUE(isgraph_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isgraph_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, islower) {
-  EXPECT_TRUE(islower('a'));
-  EXPECT_FALSE(islower('A'));
-  EXPECT_FALSE(islower('!'));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= 'a' && i <= 'z') {
+      EXPECT_TRUE(islower(i)) << i;
+    } else {
+      EXPECT_FALSE(islower(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, islower_l) {
-  EXPECT_TRUE(islower_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(islower_l('A', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(islower_l('!', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= 'a' && i <= 'z') {
+      EXPECT_TRUE(islower_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(islower_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isprint) {
-  EXPECT_TRUE(isprint('a'));
-  EXPECT_TRUE(isprint(' '));
-  EXPECT_FALSE(isprint('\b'));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= ' ' && i <= '~') {
+      EXPECT_TRUE(isprint(i)) << i;
+    } else {
+      EXPECT_FALSE(isprint(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isprint_l) {
-  EXPECT_TRUE(isprint_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isprint_l(' ', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isprint_l('\b', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= ' ' && i <= '~') {
+      EXPECT_TRUE(isprint_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isprint_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, ispunct) {
-  EXPECT_TRUE(ispunct('!'));
-  EXPECT_FALSE(ispunct('a'));
-  EXPECT_FALSE(ispunct(' '));
-  EXPECT_FALSE(ispunct('\b'));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '!' && i <= '/') ||
+        (i >= ':' && i <= '@') ||
+        (i >= '[' && i <= '`') ||
+        (i >= '{' && i <= '~')) {
+      EXPECT_TRUE(ispunct(i)) << i;
+    } else {
+      EXPECT_FALSE(ispunct(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, ispunct_l) {
-  EXPECT_TRUE(ispunct_l('!', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(ispunct_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(ispunct_l(' ', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(ispunct_l('\b', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '!' && i <= '/') ||
+        (i >= ':' && i <= '@') ||
+        (i >= '[' && i <= '`') ||
+        (i >= '{' && i <= '~')) {
+      EXPECT_TRUE(ispunct_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(ispunct_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isspace) {
-  EXPECT_TRUE(isspace(' '));
-  EXPECT_TRUE(isspace('\f'));
-  EXPECT_TRUE(isspace('\n'));
-  EXPECT_TRUE(isspace('\r'));
-  EXPECT_TRUE(isspace('\t'));
-  EXPECT_TRUE(isspace('\v'));
-  EXPECT_FALSE(isspace('a'));
-  EXPECT_FALSE(isspace('!'));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '\t' && i <= '\r') || i == ' ') {
+      EXPECT_TRUE(isspace(i)) << i;
+    } else {
+      EXPECT_FALSE(isspace(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isspace_l) {
-  EXPECT_TRUE(isspace_l(' ', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isspace_l('\f', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isspace_l('\n', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isspace_l('\r', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isspace_l('\t', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isspace_l('\v', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isspace_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isspace_l('!', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '\t' && i <= '\r') || i == ' ') {
+      EXPECT_TRUE(isspace_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isspace_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isupper) {
-  EXPECT_TRUE(isupper('A'));
-  EXPECT_FALSE(isupper('a'));
-  EXPECT_FALSE(isupper('!'));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= 'A' && i <= 'Z') {
+      EXPECT_TRUE(isupper(i)) << i;
+    } else {
+      EXPECT_FALSE(isupper(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isupper_l) {
-  EXPECT_TRUE(isupper_l('A', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isupper_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isupper_l('!', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if (i >= 'A' && i <= 'Z') {
+      EXPECT_TRUE(isupper_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isupper_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, isxdigit) {
-  EXPECT_TRUE(isxdigit('0'));
-  EXPECT_FALSE(isxdigit('x'));
-  EXPECT_TRUE(isxdigit('1'));
-  EXPECT_TRUE(isxdigit('a'));
-  EXPECT_TRUE(isxdigit('A'));
-  EXPECT_FALSE(isxdigit('g'));
-  EXPECT_FALSE(isxdigit(' '));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '0' && i <= '9') ||
+        (i >= 'A' && i <= 'F') ||
+        (i >= 'a' && i <= 'f')) {
+      EXPECT_TRUE(isxdigit(i)) << i;
+    } else {
+      EXPECT_FALSE(isxdigit(i)) << i;
+    }
+  }
 }
 
 TEST(ctype, isxdigit_l) {
-  EXPECT_TRUE(isxdigit_l('0', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isxdigit_l('x', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isxdigit_l('1', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isxdigit_l('a', LC_GLOBAL_LOCALE));
-  EXPECT_TRUE(isxdigit_l('A', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isxdigit_l('g', LC_GLOBAL_LOCALE));
-  EXPECT_FALSE(isxdigit_l(' ', LC_GLOBAL_LOCALE));
+  for (int i = kMin; i < kMax; ++i) {
+    if ((i >= '0' && i <= '9') ||
+        (i >= 'A' && i <= 'F') ||
+        (i >= 'a' && i <= 'f')) {
+      EXPECT_TRUE(isxdigit_l(i, LC_GLOBAL_LOCALE)) << i;
+    } else {
+      EXPECT_FALSE(isxdigit_l(i, LC_GLOBAL_LOCALE)) << i;
+    }
+  }
 }
 
 TEST(ctype, toascii) {
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index e7274f7..e98d66f 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -600,7 +600,7 @@
 void GetPss(bool shared_relro, const char* lib, const char* relro_file, pid_t pid,
             size_t* total_pss) {
   android::meminfo::ProcMemInfo proc_mem(pid);
-  const std::vector<android::meminfo::Vma>& maps = proc_mem.Maps();
+  const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
   ASSERT_GT(maps.size(), 0UL);
 
   // Calculate total PSS of the library.
@@ -612,7 +612,9 @@
           saw_relro_file = true;
       }
 
-      *total_pss += vma.usage.pss;
+      android::meminfo::Vma update_vma(vma);
+      ASSERT_TRUE(proc_mem.FillInVmaStats(update_vma));
+      *total_pss += update_vma.usage.pss;
     }
   }
 
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 989e2d0..0407553 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -371,7 +371,8 @@
   auto root = doc.FirstChildElement();
   ASSERT_NE(nullptr, root);
   ASSERT_STREQ("malloc", root->Name());
-  if (std::string(root->Attribute("version")) == "jemalloc-1") {
+  std::string version(root->Attribute("version"));
+  if (version == "jemalloc-1") {
     // Verify jemalloc version of this data.
     ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
 
@@ -404,9 +405,9 @@
       }
     }
   } else {
-    // Only verify that this is debug-malloc-1, the malloc debug unit tests
-    // verify the output.
-    ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
+    // Do not verify output for scudo or debug malloc.
+    ASSERT_TRUE(version == "scudo-1" || version == "debug-malloc-1")
+        << "Unknown version: " << version;
   }
 #endif
 }
@@ -431,7 +432,8 @@
   auto root = doc.FirstChildElement();
   ASSERT_NE(nullptr, root);
   ASSERT_STREQ("malloc", root->Name());
-  if (std::string(root->Attribute("version")) == "jemalloc-1") {
+  std::string version(root->Attribute("version"));
+  if (version == "jemalloc-1") {
     // Verify jemalloc version of this data.
     ASSERT_STREQ("jemalloc-1", root->Attribute("version"));
 
@@ -458,9 +460,9 @@
     EXPECT_LE(mallinfo_before_allocated_bytes, total_allocated_bytes);
     EXPECT_GE(mallinfo_after_allocated_bytes, total_allocated_bytes);
   } else {
-    // Only verify that this is debug-malloc-1, the malloc debug unit tests
-    // verify the output.
-    ASSERT_STREQ("debug-malloc-1", root->Attribute("version"));
+    // Do not verify output for scudo or debug malloc.
+    ASSERT_TRUE(version == "scudo-1" || version == "debug-malloc-1")
+        << "Unknown version: " << version;
   }
 #endif
 }