Merge "Nullability check for select module."
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index c5a6ac3..8ffd96f 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -107,7 +107,7 @@
 ## Correct soname/path handling (Available in API level >= 23)
 
 The dynamic linker now understands the difference
-between a library’s soname and its path  (public bug
+between a library’s soname and its path (public bug
 https://code.google.com/p/android/issues/detail?id=6670). API level 23
 is the first release where search by soname is implemented. Earlier
 releases would assume that the basename of the library was the soname,
@@ -326,12 +326,12 @@
 
 ## Missing SONAME (Enforced for API level >= 23)
 
-Each ELF shared object (“native library”) must have a SONAME (Shared
-Object Name) attribute. The NDK toolchain adds this attribute by default,
-so its absence indicates either a misconfigured alternative toolchain
-or a misconfiguration in your build system. A missing SONAME may lead
-to runtime issues such as the wrong library being loaded: the filename
-is used instead when this attribute is missing.
+Each ELF shared object (“native library”) must have a SONAME
+(Shared Object Name) attribute. The NDK build systems add this
+attribute by default, so its absence (or an incorrect soname) indicates
+a misconfiguration in your build system. A missing SONAME may lead to
+runtime issues such as the wrong library being loaded: the filename is
+used instead when this attribute is missing.
 
 ```
 $ readelf --dynamic libWithSoName.so | grep SONAME
@@ -346,7 +346,7 @@
 *Resolution*: the current NDK generates the correct SONAME by
 default. Ensure you're using the current NDK and that you haven't
 configured your build system to generate incorrect SONAME entries (using
-the -soname linker option).
+the `-soname` linker option).
 
 ## `__register_atfork` (Available in API level >= 23)
 
diff --git a/apex/Android.bp b/apex/Android.bp
index 90a14b2..6201ad1 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -41,6 +41,11 @@
         "libc_malloc_debug",
         "libc_malloc_hooks",
     ],
+    arch: {
+        arm64: {
+            native_shared_libs: ["libc_hwasan", "libclang_rt.hwasan"],
+        },
+    },
     binaries: [
         "linkerconfig",
     ],
diff --git a/benchmarks/malloc_benchmark.cpp b/benchmarks/malloc_benchmark.cpp
index 18ba523..e733cd0 100644
--- a/benchmarks/malloc_benchmark.cpp
+++ b/benchmarks/malloc_benchmark.cpp
@@ -36,11 +36,11 @@
 
 #if defined(__BIONIC__)
 
-static void BM_mallopt_purge(benchmark::State& state) {
+static void RunMalloptPurge(benchmark::State& state, int purge_value) {
   static size_t sizes[] = {8, 16, 32, 64, 128, 1024, 4096, 16384, 65536, 131072, 1048576};
   static int pagesize = getpagesize();
   mallopt(M_DECAY_TIME, 1);
-  mallopt(M_PURGE, 0);
+  mallopt(M_PURGE_ALL, 0);
   for (auto _ : state) {
     state.PauseTiming();
     std::vector<void*> ptrs;
@@ -63,10 +63,19 @@
     ptrs.clear();
     state.ResumeTiming();
 
-    mallopt(M_PURGE, 0);
+    mallopt(purge_value, 0);
   }
   mallopt(M_DECAY_TIME, 0);
 }
+
+static void BM_mallopt_purge(benchmark::State& state) {
+  RunMalloptPurge(state, M_PURGE);
+}
 BIONIC_BENCHMARK(BM_mallopt_purge);
 
+static void BM_mallopt_purge_all(benchmark::State& state) {
+  RunMalloptPurge(state, M_PURGE_ALL);
+}
+BIONIC_BENCHMARK(BM_mallopt_purge_all);
+
 #endif
diff --git a/benchmarks/malloc_map_benchmark.cpp b/benchmarks/malloc_map_benchmark.cpp
index ba4d62c..5757325 100644
--- a/benchmarks/malloc_map_benchmark.cpp
+++ b/benchmarks/malloc_map_benchmark.cpp
@@ -69,7 +69,7 @@
   for (auto _ : state) {
 #if defined(__BIONIC__)
     state.PauseTiming();
-    mallopt(M_PURGE, 0);
+    mallopt(M_PURGE_ALL, 0);
     uint64_t rss_bytes_before = 0;
     Gather(&rss_bytes_before);
     state.ResumeTiming();
@@ -80,7 +80,7 @@
     }
 #if defined(__BIONIC__)
     state.PauseTiming();
-    mallopt(M_PURGE, 0);
+    mallopt(M_PURGE_ALL, 0);
     Gather(&rss_bytes);
     // Try and record only the memory used in the map.
     rss_bytes -= rss_bytes_before;
diff --git a/benchmarks/malloc_rss_benchmark.cpp b/benchmarks/malloc_rss_benchmark.cpp
index 58f61d9..4b34e72 100644
--- a/benchmarks/malloc_rss_benchmark.cpp
+++ b/benchmarks/malloc_rss_benchmark.cpp
@@ -112,7 +112,7 @@
 
   // Do an explicit purge to ensure we will be more likely to get the actual
   // in-use memory.
-  mallopt(M_PURGE, 0);
+  mallopt(M_PURGE_ALL, 0);
 
   android::meminfo::ProcMemInfo proc_mem(getpid());
   const std::vector<android::meminfo::Vma>& maps = proc_mem.MapsWithoutUsageStats();
diff --git a/docs/elf-tls.md b/docs/elf-tls.md
index 4a62793..d408b3f 100644
--- a/docs/elf-tls.md
+++ b/docs/elf-tls.md
@@ -101,9 +101,9 @@
 `R_TLS_DTPOFF` is a dynamic relocation to the offset of `tls_var` within its module's `PT_TLS`
 segment.
 
-`__tls_get_addr` looks up `TlsIndex::module`'s entry in the DTV and adds `TlsIndex::offset` to the
-module's TLS block. Before it can do this, it ensures that the module's TLS block is allocated. A
-simple approach is to allocate memory lazily:
+`__tls_get_addr` looks up `TlsIndex::module_id`'s entry in the DTV and adds `TlsIndex::offset` to
+the module's TLS block. Before it can do this, it ensures that the module's TLS block is allocated.
+A simple approach is to allocate memory lazily:
 
 1. If the current thread's DTV generation count is less than the current global TLS generation, then
    `__tls_get_addr` may reallocate the DTV or free blocks for unloaded modules.
diff --git a/docs/status.md b/docs/status.md
index 5d2603a..3d104e4 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -59,6 +59,9 @@
   * `close_range` and `copy_file_range` (Linux-specific GNU extensions).
   * `memset_explicit` in <string.h> (C23 addition).
   * `__freadahead` in <stdio_ext.h> (in musl but not glibc).
+  * `posix_spawn_file_actions_addchdir_np` and
+    `posix_spawn_file_actions_addfchdir_np` in <spawn.h> (in musl/glibc
+    and macOS, but not iOS).
 
 New libc behavior in U (API level 34):
   * Support for `%b` and `%B` in the printf/wprintf family, `%b` in the
diff --git a/libc/Android.bp b/libc/Android.bp
index c101f45..f5f5f7c 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -827,6 +827,7 @@
         riscv64: {
             srcs: [
                "arch-riscv64/string/__memset_chk.S",
+               "arch-riscv64/string/__memcpy_chk.S",
             ],
         },
     },
@@ -1317,7 +1318,7 @@
 // ========================================================
 
 genrule {
-    name: "syscalls-arm.S",
+    name: "syscalls-arm",
     out: ["syscalls-arm.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1325,7 +1326,7 @@
 }
 
 genrule {
-    name: "syscalls-arm64.S",
+    name: "syscalls-arm64",
     out: ["syscalls-arm64.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1333,7 +1334,7 @@
 }
 
 genrule {
-    name: "syscalls-riscv64.S",
+    name: "syscalls-riscv64",
     out: ["syscalls-riscv64.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1341,7 +1342,7 @@
 }
 
 genrule {
-    name: "syscalls-x86.S",
+    name: "syscalls-x86",
     out: ["syscalls-x86.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1349,7 +1350,7 @@
 }
 
 genrule {
-    name: "syscalls-x86_64.S",
+    name: "syscalls-x86_64",
     out: ["syscalls-x86_64.S"],
     srcs: ["SYSCALLS.TXT"],
     tools: ["gensyscalls"],
@@ -1361,19 +1362,19 @@
     srcs: ["bionic/__set_errno.cpp"],
     arch: {
         arm: {
-            srcs: [":syscalls-arm.S"],
+            srcs: [":syscalls-arm"],
         },
         arm64: {
-            srcs: [":syscalls-arm64.S"],
+            srcs: [":syscalls-arm64"],
         },
         riscv64: {
-            srcs: [":syscalls-riscv64.S"],
+            srcs: [":syscalls-riscv64"],
         },
         x86: {
-            srcs: [":syscalls-x86.S"],
+            srcs: [":syscalls-x86"],
         },
         x86_64: {
-            srcs: [":syscalls-x86_64.S"],
+            srcs: [":syscalls-x86_64"],
         },
     },
     name: "libc_syscalls",
@@ -1673,13 +1674,12 @@
 // ========================================================
 // libc.a + libc.so
 // ========================================================
-cc_library {
+cc_defaults {
     defaults: [
         "libc_defaults",
         "libc_native_allocator_defaults",
     ],
-    name: "libc",
-    static_ndk_lib: true,
+    name: "libc_library_defaults",
     product_variables: {
         platform_sdk_version: {
             asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1806,20 +1806,7 @@
         },
     },
 
-    stubs: {
-        symbol_file: "libc.map.txt",
-        versions: [
-            "29",
-            "R",
-            "current",
-        ],
-    },
-    llndk: {
-        symbol_file: "libc.map.txt",
-        export_headers_as_system: true,
-        export_preprocessed_headers: ["include"],
-        export_llndk_headers: ["libc_llndk_headers"],
-    },
+
     apex_available: [
         "//apex_available:platform",
         "com.android.runtime",
@@ -1834,9 +1821,58 @@
     },
 }
 
+cc_library {
+    name: "libc",
+      defaults: [
+        "libc_library_defaults",
+    ],
+    stubs: {
+        symbol_file: "libc.map.txt",
+        versions: [
+            "29",
+            "R",
+            "current",
+        ],
+    },
+    static_ndk_lib: true,
+    llndk: {
+        symbol_file: "libc.map.txt",
+        export_headers_as_system: true,
+        export_preprocessed_headers: ["include"],
+        export_llndk_headers: ["libc_llndk_headers"],
+    },
+}
+
+cc_library {
+    name: "libc_hwasan",
+      defaults: [
+        "libc_library_defaults",
+    ],
+    sanitize: {
+        hwaddress: true,
+    },
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    stem: "libc",
+    relative_install_path: "hwasan",
+    // We don't really need the stubs, but this needs to stay to trigger the
+    // symlink logic in soong.
+    stubs: {
+        symbol_file: "libc.map.txt",
+    },
+    native_bridge_supported: false,
+    // It is never correct to depend on this directly. This is only
+    // needed for the runtime apex, and in base_system.mk.
+    visibility: ["//bionic/apex"],
+}
+
 genrule {
     name: "libc.arm.map",
-    out: ["libc.arm.map"],
+    out: ["libc.arm.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -1844,7 +1880,7 @@
 
 genrule {
     name: "libc.arm64.map",
-    out: ["libc.arm64.map"],
+    out: ["libc.arm64.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -1852,7 +1888,7 @@
 
 genrule {
     name: "libc.riscv64.map",
-    out: ["libc.riscv64.map"],
+    out: ["libc.riscv64.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -1860,7 +1896,7 @@
 
 genrule {
     name: "libc.x86.map",
-    out: ["libc.x86.map"],
+    out: ["libc.x86.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -1868,7 +1904,7 @@
 
 genrule {
     name: "libc.x86_64.map",
-    out: ["libc.x86_64.map"],
+    out: ["libc.x86_64.map.txt"],
     srcs: ["libc.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2073,7 +2109,7 @@
 
 genrule {
     name: "libstdc++.arm.map",
-    out: ["libstdc++.arm.map"],
+    out: ["libstdc++.arm.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -2081,7 +2117,7 @@
 
 genrule {
     name: "libstdc++.arm64.map",
-    out: ["libstdc++.arm64.map"],
+    out: ["libstdc++.arm64.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -2089,7 +2125,7 @@
 
 genrule {
     name: "libstdc++.riscv64.map",
-    out: ["libstdc++.riscv64.map"],
+    out: ["libstdc++.riscv64.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -2097,7 +2133,7 @@
 
 genrule {
     name: "libstdc++.x86.map",
-    out: ["libstdc++.x86.map"],
+    out: ["libstdc++.x86.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -2105,7 +2141,7 @@
 
 genrule {
     name: "libstdc++.x86_64.map",
-    out: ["libstdc++.x86_64.map"],
+    out: ["libstdc++.x86_64.map.txt"],
     srcs: ["libstdc++.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2178,6 +2214,8 @@
     srcs: ["arch-common/bionic/crtbrand.S"],
 
     defaults: ["crt_so_defaults"],
+    // crtbrand is an intermediate artifact, not a final CRT object.
+    exclude_from_ndk_sysroot: true,
 }
 
 cc_object {
@@ -2307,6 +2345,11 @@
                 "arch-arm64/string/__memcpy_chk.S",
             ],
         },
+        riscv64: {
+            srcs: [
+               "arch-riscv64/string/__memcpy_chk.S",
+            ],
+        },
     },
     whole_static_libs: [
         "libarm-optimized-routines-mem",
diff --git a/libc/NOTICE b/libc/NOTICE
index 9d55592..4d3a108 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -894,6 +894,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2023 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1980, 1983, 1988, 1993
    The Regents of the University of California.  All rights reserved.
 
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index 8e00b56..d787a56 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -46,8 +46,6 @@
 // 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
 // 1      sigmask         signal mask (not used with _setjmp / _longjmp)
 // 2      core_base       base of core registers (x18-x30, sp)
-//                        (We only store the low bits of x18 to avoid leaking the
-//                        shadow call stack address into memory.)
 // 16     float_base      base of float registers (d8-d15)
 // 24     checksum        checksum of core registers
 // 25     reserved        reserved entries (room to grow)
@@ -68,8 +66,6 @@
 #define _JB_D8_D9       (_JB_D10_D11 + 2)
 #define _JB_CHECKSUM    (_JB_D8_D9 + 2)
 
-#define SCS_MASK (SCS_SIZE - 1)
-
 .macro m_mangle_registers reg, sp_reg
   eor x3, x3, \reg
   eor x19, x19, \reg
@@ -155,6 +151,9 @@
   bic x1, x1, #1
 
   // Mask off the high bits of the shadow call stack pointer.
+  // We only store the low bits of x18 to avoid leaking the
+  // shadow call stack address into memory.
+  // See the SCS commentary in pthread_internal.h for more detail.
   and x3, x18, #SCS_MASK
 
   // Save core registers.
diff --git a/libc/arch-riscv64/bionic/__bionic_clone.S b/libc/arch-riscv64/bionic/__bionic_clone.S
index d535095..2827857 100644
--- a/libc/arch-riscv64/bionic/__bionic_clone.S
+++ b/libc/arch-riscv64/bionic/__bionic_clone.S
@@ -51,7 +51,7 @@
 .L_bc_failure:
   # Set errno if something went wrong.
   neg a0, a0
-  j __set_errno_internal
+  tail __set_errno_internal
 
 .L_bc_child:
   # We're in the child now. Set the end of the frame record chain.
@@ -62,5 +62,5 @@
   ld a0, 0(sp)
   ld a1, 8(sp)
   addi sp, sp, 16
-  j __start_thread
+  tail __start_thread
 END(__bionic_clone)
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
index eea2978..26f7ec9 100644
--- a/libc/arch-riscv64/bionic/setjmp.S
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -36,45 +36,47 @@
 // 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
 // 1      sigmask         64-bit signal mask
 // 2      ra
-// 3      s0
+// 3      sp
+// 4      gp
+// 5      s0
 // ......
-// 14     s11
-// 15     sp
-// 16     fs0
+// 16     s11
+// 17     fs0
 // ......
-// 27     fs11
-// 28     checksum
+// 28     fs11
+// 29     checksum
 // _JBLEN: defined in bionic/libc/include/setjmp.h
 
 #define _JB_SIGFLAG   0
 #define _JB_SIGMASK   1 * 8
 #define _JB_RA        2 * 8
-#define _JB_S0        3 * 8
-#define _JB_S1        4 * 8
-#define _JB_S2        5 * 8
-#define _JB_S3        6 * 8
-#define _JB_S4        7 * 8
-#define _JB_S5        8 * 8
-#define _JB_S6        9 * 8
-#define _JB_S7       10 * 8
-#define _JB_S8       11 * 8
-#define _JB_S9       12 * 8
-#define _JB_S10      13 * 8
-#define _JB_S11      14 * 8
-#define _JB_SP       15 * 8
-#define _JB_FS0      16 * 8
-#define _JB_FS1      17 * 8
-#define _JB_FS2      18 * 8
-#define _JB_FS3      19 * 8
-#define _JB_FS4      20 * 8
-#define _JB_FS5      21 * 8
-#define _JB_FS6      22 * 8
-#define _JB_FS7      23 * 8
-#define _JB_FS8      24 * 8
-#define _JB_FS9      25 * 8
-#define _JB_FS10     26 * 8
-#define _JB_FS11     27 * 8
-#define _JB_CHECKSUM 28 * 8
+#define _JB_SP        3 * 8
+#define _JB_GP        4 * 8
+#define _JB_S0        5 * 8
+#define _JB_S1        6 * 8
+#define _JB_S2        7 * 8
+#define _JB_S3        8 * 8
+#define _JB_S4        9 * 8
+#define _JB_S5       10 * 8
+#define _JB_S6       11 * 8
+#define _JB_S7       12 * 8
+#define _JB_S8       13 * 8
+#define _JB_S9       14 * 8
+#define _JB_S10      15 * 8
+#define _JB_S11      16 * 8
+#define _JB_FS0      17 * 8
+#define _JB_FS1      18 * 8
+#define _JB_FS2      19 * 8
+#define _JB_FS3      20 * 8
+#define _JB_FS4      21 * 8
+#define _JB_FS5      22 * 8
+#define _JB_FS6      23 * 8
+#define _JB_FS7      24 * 8
+#define _JB_FS8      25 * 8
+#define _JB_FS9      26 * 8
+#define _JB_FS10     27 * 8
+#define _JB_FS11     28 * 8
+#define _JB_CHECKSUM 29 * 8
 
 .macro m_mangle_registers reg, sp_reg
   xor s0, s0, \reg
@@ -89,12 +91,13 @@
   xor s9, s9, \reg
   xor s10, s10, \reg
   xor s11, s11, \reg
+  xor a4, a4, \reg  // a4 is the masked gp (x3) for SCS.
   xor \sp_reg, \sp_reg, \reg
 .endm
 
 .macro m_calculate_checksum dst, src, scratch
   li \dst, 0
-  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
+  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
     ld \scratch, (\i * 8)(\src)
     xor \dst, \dst, \scratch
   .endr
@@ -151,10 +154,19 @@
   ld a1, _JB_SIGFLAG(a0)
   andi a1, a1, -2
 
+  // Mask off the high bits of the shadow call stack pointer.
+  // We only store the low bits of gp to avoid leaking the
+  // shadow call stack address into memory.
+  // See the SCS commentary in pthread_internal.h for more detail.
+  li a4, SCS_MASK
+  and a4, a4, gp
+
   // Save core registers.
   mv a2, sp
   m_mangle_registers a1, sp_reg=a2
   sd ra,  _JB_RA(a0)
+  sd a4,  _JB_GP(a0)  // a4 is the masked gp (x3) for SCS.
+  sd a2,  _JB_SP(a0)
   sd s0,  _JB_S0(a0)
   sd s1,  _JB_S1(a0)
   sd s2,  _JB_S2(a0)
@@ -167,7 +179,6 @@
   sd s9,  _JB_S9(a0)
   sd s10, _JB_S10(a0)
   sd s11, _JB_S11(a0)
-  sd a2,  _JB_SP(a0)
   m_unmangle_registers a1, sp_reg=a2
 
   // Save floating point registers.
@@ -229,6 +240,7 @@
   // Restore core registers.
   andi a2, a2, -2
   ld ra,  _JB_RA(a0)
+  ld a4,  _JB_GP(a0)  // Don't clobber the upper bits of gp (x3) used for SCS yet.
   ld s0,  _JB_S0(a0)
   ld s1,  _JB_S1(a0)
   ld s2,  _JB_S2(a0)
@@ -245,6 +257,11 @@
   m_unmangle_registers a2, sp_reg=a3
   mv sp, a3
 
+  // Restore the low bits of the shadow call stack pointer.
+  li a5, ~SCS_MASK
+  and gp, gp, a5
+  or gp, gp, a4
+
   addi sp, sp, -24
   sd   ra, 0(sp)
   sd   a0, 8(sp)
diff --git a/libc/arch-riscv64/bionic/syscall.S b/libc/arch-riscv64/bionic/syscall.S
index 7b9d3ca..1a6e60a 100644
--- a/libc/arch-riscv64/bionic/syscall.S
+++ b/libc/arch-riscv64/bionic/syscall.S
@@ -49,5 +49,5 @@
   ret
 1:
   neg a0, a0
-  j __set_errno_internal
+  tail __set_errno_internal
 END(syscall)
diff --git a/libc/arch-riscv64/bionic/vfork.S b/libc/arch-riscv64/bionic/vfork.S
index 0eff9e9..29ab405 100644
--- a/libc/arch-riscv64/bionic/vfork.S
+++ b/libc/arch-riscv64/bionic/vfork.S
@@ -62,5 +62,5 @@
 
 .L_failure:
   neg     a0, a0
-  j       __set_errno_internal
+  tail    __set_errno_internal
 END(vfork)
diff --git a/libc/arch-riscv64/string/__memcpy_chk.S b/libc/arch-riscv64/string/__memcpy_chk.S
new file mode 100644
index 0000000..4a2d13d
--- /dev/null
+++ b/libc/arch-riscv64/string/__memcpy_chk.S
@@ -0,0 +1,9 @@
+#include <private/bionic_asm.h>
+
+ENTRY(__memcpy_chk)
+  bleu a2, a3, 1f
+  call __memcpy_chk_fail
+
+1:
+   tail memcpy
+END(__memcpy_chk)
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 2380e68..420560f 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -254,7 +254,7 @@
     bool alternate = false;
     size_t bytelen = sizeof(int);
     int slen;
-    char buffer[32]; /* temporary buffer used to format numbers */
+    char buffer[64];  // temporary buffer used to format numbers/format errno string
 
     char c;
 
@@ -359,8 +359,7 @@
       buffer[1] = 'x';
       format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
     } else if (c == 'm') {
-      char buf[256];
-      str = strerror_r(errno, buf, sizeof(buf));
+      strerror_r(errno, buffer, sizeof(buffer));
     } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
       /* integers - first read value from stack */
       uint64_t value;
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 73cf973..7dee5e3 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -489,9 +489,9 @@
   return strcpy(dst, src);
 }
 
-#if !defined(__arm__) && !defined(__aarch64__)
+#if !defined(__arm__) && !defined(__aarch64__) && !defined(__riscv)
 // Runtime implementation of __memcpy_chk (used directly by compiler, not in headers).
-// arm32 and arm64 have assembler implementations, and don't need this C fallback.
+// arm32,arm64,riscv have assembler implementations, and don't need this C fallback.
 extern "C" void* __memcpy_chk(void* dst, const void* src, size_t count, size_t dst_len) {
   __check_count("memcpy", "count", count);
   __check_buffer_access("memcpy", "write into", count, dst_len);
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index 251633d..fab29ef 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -307,8 +307,10 @@
     sysprop_names[3] = persist_default_sysprop;
   }
 
+  // TODO(mitchp): Log overrides using this.
+  const char* source;
   return get_config_from_env_or_sysprops(env_var, sysprop_names, arraysize(sysprop_names),
-                                         value_out, PROP_VALUE_MAX);
+                                         value_out, PROP_VALUE_MAX, &source);
 }
 
 bool GetGwpAsanIntegerOption(unsigned long long* result,
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index ef488ee..ce3f314 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -102,7 +102,7 @@
       }
     }
     return 1;
-  } else if (param == M_PURGE) {
+  } else if (param == M_PURGE || param == M_PURGE_ALL) {
     // Only clear the current thread cache since there is no easy way to
     // clear the caches of other threads.
     // This must be done first so that cleared allocations get purged
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 5d5ecac..59b2ddb 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -289,6 +289,7 @@
       "LD_DEBUG",
       "LD_DEBUG_OUTPUT",
       "LD_DYNAMIC_WEAK",
+      "LD_HWASAN",
       "LD_LIBRARY_PATH",
       "LD_ORIGIN_PATH",
       "LD_PRELOAD",
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index d64d402..0935cd6 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -217,16 +217,13 @@
 // Returns true if there's an environment setting (either sysprop or env var)
 // that should overwrite the ELF note, and places the equivalent heap tagging
 // level into *level.
-static bool get_environment_memtag_setting(HeapTaggingLevel* level) {
+static bool get_environment_memtag_setting(const char* basename, HeapTaggingLevel* level) {
   static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process.";
   static const char kMemtagGlobalSysprop[] = "persist.arm64.memtag.default";
   static const char kMemtagOverrideSyspropPrefix[] =
       "persist.device_config.memory_safety_native.mode_override.process.";
 
-  const char* progname = __libc_shared_globals()->init_progname;
-  if (progname == nullptr) return false;
-
-  const char* basename = __gnu_basename(progname);
+  if (basename == nullptr) return false;
 
   char options_str[PROP_VALUE_MAX];
   char sysprop_name[512];
@@ -237,8 +234,9 @@
                            kMemtagOverrideSyspropPrefix, basename);
   const char* sys_prop_names[] = {sysprop_name, remote_sysprop_name, kMemtagGlobalSysprop};
 
+  const char* source = nullptr;
   if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", sys_prop_names, arraysize(sys_prop_names),
-                                       options_str, sizeof(options_str))) {
+                                       options_str, sizeof(options_str), &source)) {
     return false;
   }
 
@@ -249,27 +247,35 @@
   } else if (strcmp("off", options_str) == 0) {
     *level = M_HEAP_TAGGING_LEVEL_TBI;
   } else {
-    async_safe_format_log(
-        ANDROID_LOG_ERROR, "libc",
-        "unrecognized memtag level: \"%s\" (options are \"sync\", \"async\", or \"off\").",
-        options_str);
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "%s: unrecognized memtag level in %s: \"%s\" (options are \"sync\", "
+                          "\"async\", or \"off\").",
+                          basename, source, options_str);
     return false;
   }
-
+  async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "%s: chose memtag level \"%s\" from %s.",
+                        basename, options_str, source);
   return true;
 }
 
+static void log_elf_memtag_level(const char* basename, const char* level) {
+  async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "%s: chose memtag level \"%s\" from ELF note",
+                        basename ?: "<unknown>", level);
+}
+
 // Returns the initial heap tagging level. Note: This function will never return
 // M_HEAP_TAGGING_LEVEL_NONE, if MTE isn't enabled for this process we enable
 // M_HEAP_TAGGING_LEVEL_TBI.
 static HeapTaggingLevel __get_heap_tagging_level(const void* phdr_start, size_t phdr_ct,
                                                  uintptr_t load_bias, bool* stack) {
+  const char* progname = __libc_shared_globals()->init_progname;
+  const char* basename = progname ? __gnu_basename(progname) : nullptr;
   unsigned note_val =
       __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
   *stack = note_val & NT_MEMTAG_STACK;
 
   HeapTaggingLevel level;
-  if (get_environment_memtag_setting(&level)) return level;
+  if (get_environment_memtag_setting(basename, &level)) return level;
 
   // Note, previously (in Android 12), any value outside of bits [0..3] resulted
   // in a check-fail. In order to be permissive of further extensions, we
@@ -284,14 +290,17 @@
       // by anyone, but we note it (heh) here for posterity, in case the zero
       // level becomes meaningful, and binaries with this note can be executed
       // on Android 12 devices.
+      log_elf_memtag_level(basename, "off");
       return M_HEAP_TAGGING_LEVEL_TBI;
     case NT_MEMTAG_LEVEL_ASYNC:
+      log_elf_memtag_level(basename, "async");
       return M_HEAP_TAGGING_LEVEL_ASYNC;
     case NT_MEMTAG_LEVEL_SYNC:
     default:
       // We allow future extensions to specify mode 3 (currently unused), with
       // the idea that it might be used for ASYMM mode or something else. On
       // this version of Android, it falls back to SYNC mode.
+      log_elf_memtag_level(basename, "sync");
       return M_HEAP_TAGGING_LEVEL_SYNC;
   }
 }
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 417ce76..7bf9b40 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -116,14 +116,14 @@
 }
 
 static void __init_shadow_call_stack(pthread_internal_t* thread __unused) {
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__riscv)
   // Allocate the stack and the guard region.
   char* scs_guard_region = reinterpret_cast<char*>(
       mmap(nullptr, SCS_GUARD_REGION_SIZE, 0, MAP_PRIVATE | MAP_ANON, -1, 0));
   thread->shadow_call_stack_guard_region = scs_guard_region;
 
   // The address is aligned to SCS_SIZE so that we only need to store the lower log2(SCS_SIZE) bits
-  // in jmp_buf.
+  // in jmp_buf. See the SCS commentary in pthread_internal.h for more detail.
   char* scs_aligned_guard_region =
       reinterpret_cast<char*>(align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
 
@@ -133,11 +133,15 @@
   size_t scs_offset =
       (getpid() == 1) ? 0 : (arc4random_uniform(SCS_GUARD_REGION_SIZE / SCS_SIZE - 1) * SCS_SIZE);
 
-  // Make the stack readable and writable and store its address in register x18. This is
-  // deliberately the only place where the address is stored.
-  char *scs = scs_aligned_guard_region + scs_offset;
+  // Make the stack read-write, and store its address in the register we're using as the shadow
+  // stack pointer. This is deliberately the only place where the address is stored.
+  char* scs = scs_aligned_guard_region + scs_offset;
   mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
+#if defined(__aarch64__)
   __asm__ __volatile__("mov x18, %0" ::"r"(scs));
+#elif defined(__riscv)
+  __asm__ __volatile__("mv gp, %0" ::"r"(scs));
+#endif
 #endif
 }
 
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index bde95ec..f584b27 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -117,7 +117,7 @@
     __rt_sigprocmask(SIG_BLOCK, &set, nullptr, sizeof(sigset64_t));
   }
 
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__riscv)
   // Free the shadow call stack and guard pages.
   munmap(thread->shadow_call_stack_guard_region, SCS_GUARD_REGION_SIZE);
 #endif
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 7222b62..a3a4ccd 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -105,9 +105,14 @@
 
   void* alternate_signal_stack;
 
-  // The start address of the shadow call stack's guard region (arm64 only).
+  // The start address of the shadow call stack's guard region (arm64/riscv64).
+  // This region is SCS_GUARD_REGION_SIZE bytes large, but only SCS_SIZE bytes
+  // are actually used.
+  //
   // This address is only used to deallocate the shadow call stack on thread
-  // exit; the address of the stack itself is stored only in the x18 register.
+  // exit; the address of the stack itself is stored only in the register used
+  // as the shadow stack pointer (x18 on arm64, gp on riscv64).
+  //
   // Because the protection offered by SCS relies on the secrecy of the stack
   // address, storing the address here weakens the protection, but only
   // slightly, because it is relatively easy for an attacker to discover the
@@ -115,13 +120,24 @@
   // to other allocations), but not the stack itself, which is <0.1% of the size
   // of the guard region.
   //
+  // longjmp()/setjmp() don't store all the bits of the shadow stack pointer,
+  // only the bottom bits covered by SCS_MASK. Since longjmp()/setjmp() between
+  // different threads is undefined behavior (and unsupported on Android), we
+  // can retrieve the high bits of the shadow stack pointer from the current
+  // value in the register --- all the jmp_buf needs to store is where exactly
+  // the shadow stack pointer is *within* the thread's shadow stack: the bottom
+  // bits of the register.
+  //
   // There are at least two other options for discovering the start address of
   // the guard region on thread exit, but they are not as simple as storing in
   // TLS.
-  // 1) Derive it from the value of the x18 register. This is only possible in
-  //    processes that do not contain legacy code that might clobber x18,
-  //    therefore each process must declare early during process startup whether
-  //    it might load legacy code.
+  //
+  // 1) Derive it from the current value of the shadow stack pointer. This is
+  //    only possible in processes that do not contain legacy code that might
+  //    clobber x18 on arm64, therefore each process must declare early during
+  //    process startup whether it might load legacy code.
+  //    TODO: riscv64 has no legacy code, so we can actually go this route
+  //    there, but hopefully we'll actually get the Zsslpcfi extension instead.
   // 2) Mark the guard region as such using prctl(PR_SET_VMA_ANON_NAME) and
   //    discover its address by reading /proc/self/maps. One issue with this is
   //    that reading /proc/self/maps can race with allocations, so we may need
diff --git a/libc/bionic/scandir.cpp b/libc/bionic/scandir.cpp
index f528286..0acef36 100644
--- a/libc/bionic/scandir.cpp
+++ b/libc/bionic/scandir.cpp
@@ -69,11 +69,8 @@
   }
 
   void Sort(int (*comparator)(const dirent**, const dirent**)) {
-    // If we have entries and a comparator, sort them.
-    if (size_ > 0 && comparator != nullptr) {
-      qsort(names_, size_, sizeof(dirent*),
-            reinterpret_cast<int (*)(const void*, const void*)>(comparator));
-    }
+    qsort(names_, size_, sizeof(dirent*),
+          reinterpret_cast<int (*)(const void*, const void*)>(comparator));
   }
 
  private:
@@ -120,7 +117,9 @@
     names.Add(entry);
   }
 
-  names.Sort(comparator);
+  if (comparator != nullptr) {
+    names.Sort(comparator);
+  }
 
   size_t size = names.size();
   *name_list = names.release();
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 7e80ef6..5d76f77 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -68,7 +68,9 @@
 enum Action {
   kOpen,
   kClose,
-  kDup2
+  kDup2,
+  kChdir,
+  kFchdir,
 };
 
 struct __posix_spawn_file_action {
@@ -93,6 +95,10 @@
     } else if (what == kClose) {
       // Failure to close is ignored.
       close(fd);
+    } else if (what == kChdir) {
+      if (chdir(path) == -1) _exit(127);
+    } else if (what == kFchdir) {
+      if (fchdir(fd) == -1) _exit(127);
     } else {
       // It's a dup2.
       if (fd == new_fd) {
@@ -340,7 +346,7 @@
   if (action == nullptr) return errno;
 
   action->next = nullptr;
-  if (path != nullptr) {
+  if (what == kOpen || what == kChdir) {
     action->path = strdup(path);
     if (action->path == nullptr) {
       free(action);
@@ -380,3 +386,12 @@
   if (fd < 0 || new_fd < 0) return EBADF;
   return posix_spawn_add_file_action(actions, kDup2, fd, new_fd, nullptr, 0, 0);
 }
+
+int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t* actions, const char* path) {
+  return posix_spawn_add_file_action(actions, kChdir, -1, -1, path, 0, 0);
+}
+
+int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t* actions, int fd) {
+  if (fd < 0) return EBADF;
+  return posix_spawn_add_file_action(actions, kFchdir, fd, -1, nullptr, 0, 0);
+}
diff --git a/libc/bionic/sysprop_helpers.cpp b/libc/bionic/sysprop_helpers.cpp
index 5627034..2051330 100644
--- a/libc/bionic/sysprop_helpers.cpp
+++ b/libc/bionic/sysprop_helpers.cpp
@@ -57,18 +57,22 @@
 }
 
 bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const* sys_prop_names,
-                                     size_t sys_prop_names_size, char* options,
-                                     size_t options_size) {
+                                     size_t sys_prop_names_size, char* options, size_t options_size,
+                                     const char** chosen_source) {
   const char* env = getenv(env_var_name);
   if (env && *env != '\0') {
     strncpy(options, env, options_size);
     options[options_size - 1] = '\0';  // Ensure null-termination.
+    *chosen_source = env_var_name;
     return true;
   }
 
   for (size_t i = 0; i < sys_prop_names_size; ++i) {
     if (sys_prop_names[i] == nullptr) continue;
-    if (get_property_value(sys_prop_names[i], options, options_size)) return true;
+    if (get_property_value(sys_prop_names[i], options, options_size)) {
+      *chosen_source = sys_prop_names[i];
+      return true;
+    }
   }
   return false;
 }
diff --git a/libc/bionic/sysprop_helpers.h b/libc/bionic/sysprop_helpers.h
index a02c2dc..84e7af1 100644
--- a/libc/bionic/sysprop_helpers.h
+++ b/libc/bionic/sysprop_helpers.h
@@ -36,10 +36,13 @@
 //   2. System properties, in the order they're specified in sys_prop_names.
 // If neither of these options are specified (or they're both an empty string),
 // this function returns false. Otherwise, it returns true, and the presiding
-// options string is written to the `options` buffer of size `size`. If this
-// function returns true, `options` is guaranteed to be null-terminated.
+// options string is written to the `options` buffer of size `size`. It will
+// store a pointer to either env_var_name, or into the relevant entry of
+// sys_prop_names into choicen_source, indiciating which value was used. If
+// this function returns true, `options` is guaranteed to be null-terminated.
 // `options_size` should be at least PROP_VALUE_MAX.
 __LIBC_HIDDEN__ bool get_config_from_env_or_sysprops(const char* env_var_name,
                                                      const char* const* sys_prop_names,
                                                      size_t sys_prop_names_size, char* options,
-                                                     size_t options_size);
+                                                     size_t options_size,
+                                                     const char** chosen_source);
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index 3d04610..4d6a1fb 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -51,6 +51,9 @@
   return nullptr;
 }
 
+// O_TMPFILE isn't available until Linux 3.11, so we fall back to this on
+// older kernels. AOSP was on a new enough kernel in the Lollipop timeframe,
+// so this code should be obsolete by 2025.
 static FILE* __tmpfile_dir_legacy(const char* tmp_dir) {
   char* path = nullptr;
   if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
@@ -79,25 +82,18 @@
   return __fd_to_fp(fd);
 }
 
-static FILE* __tmpfile_dir(const char* tmp_dir) {
-  int fd = open(tmp_dir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
-  if (fd == -1) return __tmpfile_dir_legacy(tmp_dir);
-  return __fd_to_fp(fd);
+const char* __get_TMPDIR() {
+  // Use $TMPDIR if set, or fall back to /data/local/tmp otherwise.
+  // Useless for apps, but good enough for the shell.
+  const char* tmpdir = getenv("TMPDIR");
+  return (tmpdir == nullptr) ? "/data/local/tmp" : tmpdir;
 }
 
 FILE* tmpfile() {
-  // TODO: get this app's temporary directory from the framework ("/data/data/app/cache").
-
-  // $EXTERNAL_STORAGE turns out not to be very useful because it doesn't support hard links.
-  // This means we can't do the usual trick of calling unlink before handing the file back.
-
-  FILE* fp = __tmpfile_dir("/data/local/tmp");
-  if (fp == nullptr) {
-    // P_tmpdir is "/tmp/", but POSIX explicitly says that tmpdir(3) should try P_tmpdir before
-    // giving up. This is potentially useful for bionic on the host anyway.
-    fp = __tmpfile_dir(P_tmpdir);
-  }
-  return fp;
+  const char* tmpdir = __get_TMPDIR();
+  int fd = open(tmpdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
+  if (fd == -1) return __tmpfile_dir_legacy(tmpdir);
+  return __fd_to_fp(fd);
 }
 __strong_alias(tmpfile64, tmpfile);
 
@@ -107,7 +103,7 @@
   // since we can't easily remove it...
 
   // $TMPDIR overrides any directory passed in.
-  char* tmpdir = getenv("TMPDIR");
+  const char* tmpdir = getenv("TMPDIR");
   if (tmpdir != nullptr) dir = tmpdir;
 
   // If we still have no directory, we'll give you a default.
@@ -136,12 +132,7 @@
   static char buf[L_tmpnam];
   if (s == nullptr) s = buf;
 
-  // Use $TMPDIR if set, or fall back to /data/local/tmp otherwise.
-  // Useless for apps, but good enough for the shell.
-  const char* dir = getenv("TMPDIR");
-  if (dir == nullptr) dir = "/data/local/tmp";
-
   // Make up a mktemp(3) template and defer to it for the real work.
-  snprintf(s, L_tmpnam, "%s/tmpnam.XXXXXXXXXX", dir);
+  snprintf(s, L_tmpnam, "%s/tmpnam.XXXXXXXXXX", __get_TMPDIR());
   return mktemp(s);
 }
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 79085d1..6602e5d 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -162,9 +162,15 @@
  */
 #define __ANDROID_API_T__ 33
 
-/** Names the "U" API level (34), for comparison against `__ANDROID_API__`. */
+/**
+ * Names the Android 14 (aka "U" or "UpsideDownCake") API level (34),
+ * for comparison against `__ANDROID_API__`.
+ */
 #define __ANDROID_API_U__ 34
 
+/** Names the "V" API level (35), for comparison against `__ANDROID_API__`. */
+#define __ANDROID_API_V__ 35
+
 /* This file is included in <features.h>, and might be used from .S files. */
 #if !defined(__ASSEMBLY__)
 
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index f0b731c..f216aab 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -157,7 +157,7 @@
   uint64_t flags;
 
   /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
-  void*   reserved_addr;
+  void*   _Nullable reserved_addr;
   /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
   size_t  reserved_size;
 
@@ -170,7 +170,7 @@
   off64_t library_fd_offset;
 
   /** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */
-  struct android_namespace_t* library_namespace;
+  struct android_namespace_t* _Nullable library_namespace;
 } android_dlextinfo;
 
 /**
@@ -180,7 +180,7 @@
  *
  * Available since API level 21.
  */
-void* android_dlopen_ext(const char* __filename, int __flags, const android_dlextinfo* __info)
+void* _Nullable android_dlopen_ext(const char* _Nullable __filename, int __flags, const android_dlextinfo* _Nullable __info)
   __INTRODUCED_IN(21);
 
 __END_DECLS
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 59ce133..3de0649 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -159,7 +159,7 @@
  *
  * The return value points to memory with static lifetime, do not attempt to modify it.
  */
-const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
+const char* _Nonnull android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
 
 /*
  * Get an owner tag's value, with the type masked off.
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index e9b606a..f0985fe 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -38,15 +38,15 @@
 
 __BEGIN_DECLS
 
-static __inline double strtod_l(const char* __s, char** __end_ptr, locale_t __l) {
+static __inline double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
   return strtod(__s, __end_ptr);
 }
 
-static __inline float strtof_l(const char* __s, char** __end_ptr, locale_t __l) {
+static __inline float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
   return strtof(__s, __end_ptr);
 }
 
-static __inline long strtol_l(const char* __s, char** __end_ptr, int __base, locale_t __l) {
+static __inline long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) {
   return strtol(__s, __end_ptr, __base);
 }
 
diff --git a/libc/include/android/set_abort_message.h b/libc/include/android/set_abort_message.h
index 5d8d8ee..2be01a9 100644
--- a/libc/include/android/set_abort_message.h
+++ b/libc/include/android/set_abort_message.h
@@ -46,6 +46,6 @@
  *
  * Available since API level 21.
  */
-void android_set_abort_message(const char* __msg) __INTRODUCED_IN(21);
+void android_set_abort_message(const char* _Nullable __msg) __INTRODUCED_IN(21);
 
 __END_DECLS
diff --git a/libc/include/assert.h b/libc/include/assert.h
index 79e7b86..8db970b 100644
--- a/libc/include/assert.h
+++ b/libc/include/assert.h
@@ -75,12 +75,12 @@
  * __assert() is called by assert() on failure. Most users want assert()
  * instead, but this can be useful for reporting other failures.
  */
-void __assert(const char* __file, int __line, const char* __msg) __noreturn;
+void __assert(const char* _Nonnull __file, int __line, const char* _Nonnull __msg) __noreturn;
 
 /**
  * __assert2() is called by assert() on failure. Most users want assert()
  * instead, but this can be useful for reporting other failures.
  */
-void __assert2(const char* __file, int __line, const char* __function, const char* __msg) __noreturn;
+void __assert2(const char* _Nonnull __file, int __line, const char* _Nonnull __function, const char* _Nonnull __msg) __noreturn;
 
 __END_DECLS
diff --git a/libc/include/bits/elf_common.h b/libc/include/bits/elf_common.h
index ea833f4..b3c57a2 100644
--- a/libc/include/bits/elf_common.h
+++ b/libc/include/bits/elf_common.h
@@ -418,12 +418,12 @@
 #define	SHT_HIOS		0x6fffffff	/* Last of OS specific semantics */
 #define	SHT_LOPROC		0x70000000	/* reserved range for processor */
 #define	SHT_X86_64_UNWIND	0x70000001	/* unwind information */
-#define	SHT_AMD64_UNWIND	SHT_X86_64_UNWIND 
+#define	SHT_AMD64_UNWIND	SHT_X86_64_UNWIND
 
 #define	SHT_ARM_EXIDX		0x70000001	/* Exception index table. */
-#define	SHT_ARM_PREEMPTMAP	0x70000002	/* BPABI DLL dynamic linking 
+#define	SHT_ARM_PREEMPTMAP	0x70000002	/* BPABI DLL dynamic linking
 						   pre-emption map. */
-#define	SHT_ARM_ATTRIBUTES	0x70000003	/* Object file compatibility 
+#define	SHT_ARM_ATTRIBUTES	0x70000003	/* Object file compatibility
 						   attributes. */
 #define	SHT_ARM_DEBUGOVERLAY	0x70000004	/* See DBGOVL for details. */
 #define	SHT_ARM_OVERLAYSECTION	0x70000005	/* See DBGOVL for details. */
@@ -648,6 +648,11 @@
 #define	DT_AARCH64_BTI_PLT		0x70000001
 #define	DT_AARCH64_PAC_PLT		0x70000003
 #define	DT_AARCH64_VARIANT_PCS		0x70000005
+#define DT_AARCH64_MEMTAG_MODE		0x70000009
+#define DT_AARCH64_MEMTAG_HEAP		0x7000000b
+#define DT_AARCH64_MEMTAG_STACK		0x7000000c
+#define DT_AARCH64_MEMTAG_GLOBALS	0x7000000d
+#define DT_AARCH64_MEMTAG_GLOBALSSZ	0x7000000f
 
 #define	DT_ARM_SYMTABSZ			0x70000001
 #define	DT_ARM_PREEMPTMAP		0x70000002
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 2328b1a..2751b9e 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -95,7 +95,7 @@
  *
  * Returns null and sets `errno` on failure.
  */
-DIR* opendir(const char* __path);
+DIR* _Nullable opendir(const char* _Nonnull __path);
 
 /**
  * [fopendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
@@ -103,7 +103,7 @@
  *
  * Returns null and sets `errno` on failure.
  */
-DIR* fdopendir(int __dir_fd);
+DIR* _Nullable fdopendir(int __dir_fd);
 
 /**
  * [readdir(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
@@ -113,7 +113,7 @@
  * or returns null and leaves `errno` unchanged at the end of the directory,
  * or returns null and sets `errno` on failure.
  */
-struct dirent* readdir(DIR* __dir);
+struct dirent* _Nullable readdir(DIR* _Nonnull __dir);
 
 /**
  * [readdir64(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
@@ -123,10 +123,10 @@
  * or returns null and leaves `errno` unchanged at the end of the directory,
  * or returns null and sets `errno` on failure.
  */
-struct dirent64* readdir64(DIR* __dir) __INTRODUCED_IN(21);
+struct dirent64* _Nullable readdir64(DIR* _Nonnull __dir) __INTRODUCED_IN(21);
 
-int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
-int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
+int readdir_r(DIR* _Nonnull __dir, struct dirent* _Nonnull __entry, struct dirent* _Nullable * _Nonnull __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
+int readdir64_r(DIR* _Nonnull __dir, struct dirent64* _Nonnull __entry, struct dirent64* _Nullable * _Nonnull __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
 
 /**
  * [closedir(3)](http://man7.org/linux/man-pages/man3/closedir.3.html)
@@ -134,13 +134,13 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int closedir(DIR* __dir);
+int closedir(DIR* _Nonnull __dir);
 
 /**
  * [rewinddir(3)](http://man7.org/linux/man-pages/man3/rewinddir.3.html)
  * rewinds a directory stream to the first entry.
  */
-void rewinddir(DIR* __dir);
+void rewinddir(DIR* _Nonnull __dir);
 
 /**
  * [seekdir(3)](http://man7.org/linux/man-pages/man3/seekdir.3.html)
@@ -149,7 +149,7 @@
  *
  * Available since API level 23.
  */
-void seekdir(DIR* __dir, long __location) __INTRODUCED_IN(23);
+void seekdir(DIR* _Nonnull __dir, long __location) __INTRODUCED_IN(23);
 
 /**
  * [telldir(3)](http://man7.org/linux/man-pages/man3/telldir.3.html)
@@ -160,7 +160,7 @@
  *
  * Available since API level 23.
  */
-long telldir(DIR* __dir) __INTRODUCED_IN(23);
+long telldir(DIR* _Nonnull __dir) __INTRODUCED_IN(23);
 
 /**
  * [dirfd(3)](http://man7.org/linux/man-pages/man3/dirfd.3.html)
@@ -168,13 +168,13 @@
  *
  * Returns a file descriptor on success and returns -1 and sets `errno` on failure.
  */
-int dirfd(DIR* __dir);
+int dirfd(DIR* _Nonnull __dir);
 
 /**
  * [alphasort](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
  * comparator for use with scandir() that uses strcoll().
  */
-int alphasort(const struct dirent** __lhs, const struct dirent** __rhs);
+int alphasort(const struct dirent* _Nonnull * _Nonnull __lhs, const struct dirent* _Nonnull * _Nonnull __rhs);
 
 /**
  * [alphasort64](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
@@ -182,31 +182,33 @@
  *
  * Available since API level 21.
  */
-int alphasort64(const struct dirent64** __lhs, const struct dirent64** __rhs) __INTRODUCED_IN(21);
+int alphasort64(const struct dirent64* _Nonnull * _Nonnull __lhs, const struct dirent64* _Nonnull * _Nonnull __rhs) __INTRODUCED_IN(21);
 
 /**
  * [scandir(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
  * scans all the directory `__path`, filtering entries with `__filter` and
  * sorting them with qsort() using the given `__comparator`, and storing them
  * into `__name_list`. Passing NULL as the filter accepts all entries.
+ * Passing NULL as the comparator skips sorting.
  *
  * Returns the number of entries returned in the list on success,
  * and returns -1 and sets `errno` on failure.
  */
-int scandir(const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**));
+int scandir(const char* _Nonnull __path, struct dirent* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent* _Nonnull), int (* _Nullable __comparator)(const struct dirent* _Nonnull * _Nonnull, const struct dirent* _Nonnull * _Nonnull));
 
 /**
  * [scandir64(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
  * scans all the directory `__path`, filtering entries with `__filter` and
  * sorting them with qsort() using the given `__comparator`, and storing them
  * into `__name_list`. Passing NULL as the filter accepts all entries.
+ * Passing NULL as the comparator skips sorting.
  *
  * Returns the number of entries returned in the list on success,
  * and returns -1 and sets `errno` on failure.
  *
  * Available since API level 21.
  */
-int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+int scandir64(const char* _Nonnull __path, struct dirent64* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent64* _Nonnull), int (* _Nullable __comparator)(const struct dirent64* _Nonnull * _Nonnull, const struct dirent64* _Nonnull * _Nonnull)) __INTRODUCED_IN(21);
 
 #if defined(__USE_GNU)
 
@@ -216,13 +218,14 @@
  * filtering entries with `__filter` and sorting them with qsort() using the
  * given `__comparator`, and storing them into `__name_list`. Passing NULL as
  * the filter accepts all entries.
+ * Passing NULL as the comparator skips sorting.
  *
  * Returns the number of entries returned in the list on success,
  * and returns -1 and sets `errno` on failure.
  *
  * Available since API level 24.
  */
-int scandirat64(int __dir_fd, const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(24);
+int scandirat64(int __dir_fd, const char* _Nonnull __path, struct dirent64* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent64* _Nonnull), int (* _Nullable __comparator)(const struct dirent64* _Nonnull * _Nonnull, const struct dirent64* _Nonnull * _Nonnull)) __INTRODUCED_IN(24);
 
 /**
  * [scandirat(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
@@ -230,13 +233,14 @@
  * filtering entries with `__filter` and sorting them with qsort() using the
  * given `__comparator`, and storing them into `__name_list`. Passing NULL as
  * the filter accepts all entries.
+ * Passing NULL as the comparator skips sorting.
  *
  * Returns the number of entries returned in the list on success,
  * and returns -1 and sets `errno` on failure.
  *
  * Available since API level 24.
  */
-int scandirat(int __dir_fd, const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**)) __INTRODUCED_IN(24);
+int scandirat(int __dir_fd, const char* _Nonnull __path, struct dirent* _Nonnull * _Nonnull * _Nonnull __name_list, int (* _Nullable __filter)(const struct dirent* _Nonnull), int (* _Nullable __comparator)(const struct dirent* _Nonnull * _Nonnull, const struct dirent* _Nonnull * _Nonnull)) __INTRODUCED_IN(24);
 
 #endif
 
diff --git a/libc/include/fts.h b/libc/include/fts.h
index 7e63111..bae2615 100644
--- a/libc/include/fts.h
+++ b/libc/include/fts.h
@@ -39,15 +39,15 @@
 #include <sys/types.h>
 
 typedef struct {
-	struct _ftsent *fts_cur;	/* current node */
-	struct _ftsent *fts_child;	/* linked list of children */
-	struct _ftsent **fts_array;	/* sort array */
+	struct _ftsent * _Nullable fts_cur;	/* current node */
+	struct _ftsent * _Nullable fts_child;	/* linked list of children */
+	struct _ftsent * _Nullable * _Nullable fts_array;	/* sort array */
 	dev_t fts_dev;			/* starting device # */
-	char *fts_path;			/* path for this descent */
+	char * _Nullable fts_path;			/* path for this descent */
 	int fts_rfd;			/* fd for root */
 	size_t fts_pathlen;		/* sizeof(path) */
 	int fts_nitems;			/* elements in the sort array */
-	int (*fts_compar)();		/* compare function */
+	int (* _Nullable fts_compar)();		/* compare function */
 
 #define	FTS_COMFOLLOW	0x0001		/* follow command line symlinks */
 #define	FTS_LOGICAL	0x0002		/* logical walk */
@@ -65,13 +65,13 @@
 } FTS;
 
 typedef struct _ftsent {
-	struct _ftsent *fts_cycle;	/* cycle node */
-	struct _ftsent *fts_parent;	/* parent directory */
-	struct _ftsent *fts_link;	/* next file in directory */
+	struct _ftsent * _Nullable fts_cycle;	/* cycle node */
+	struct _ftsent * _Nullable fts_parent;	/* parent directory */
+	struct _ftsent * _Nullable fts_link;	/* next file in directory */
 	long fts_number;	        /* local numeric value */
-	void *fts_pointer;	        /* local address value */
-	char *fts_accpath;		/* access path */
-	char *fts_path;			/* root path */
+	void * _Nullable fts_pointer;	        /* local address value */
+	char * _Nullable fts_accpath;		/* access path */
+	char * _Nullable fts_path;			/* root path */
 	int fts_errno;			/* errno for this node */
 	int fts_symfd;			/* fd for symlink */
 	size_t fts_pathlen;		/* strlen(fts_path) */
@@ -111,7 +111,7 @@
 #define	FTS_SKIP	 4		/* discard node */
 	unsigned short fts_instr;	/* fts_set() instructions */
 
-	struct stat *fts_statp;		/* stat(2) information */
+	struct stat * _Nullable fts_statp;		/* stat(2) information */
 	char fts_name[1];		/* file name */
 } FTSENT;
 
@@ -122,11 +122,11 @@
  * breakage in 21 that means you can't write code that runs on current devices and pre-21 devices,
  * so we break the tie in favor of current and future devices.
  */
-FTSENT* fts_children(FTS* __fts, int __options) __INTRODUCED_IN(21);
-int fts_close(FTS* __fts) __INTRODUCED_IN(21);
-FTS* fts_open(char* const* __path, int __options, int (*__comparator)(const FTSENT** __lhs, const FTSENT** __rhs)) __INTRODUCED_IN(21);
-FTSENT* fts_read(FTS* __fts) __INTRODUCED_IN(21);
-int fts_set(FTS* __fts, FTSENT* __entry, int __options) __INTRODUCED_IN(21);
+FTSENT* _Nullable fts_children(FTS* _Nonnull __fts, int __options) __INTRODUCED_IN(21);
+int fts_close(FTS* _Nonnull __fts) __INTRODUCED_IN(21);
+FTS* _Nullable fts_open(char* _Nonnull const* _Nonnull __path, int __options, int (* _Nullable __comparator)(const FTSENT* _Nonnull * _Nonnull  __lhs, const FTSENT* _Nonnull * _Nonnull __rhs)) __INTRODUCED_IN(21);
+FTSENT* _Nullable fts_read(FTS* _Nonnull __fts) __INTRODUCED_IN(21);
+int fts_set(FTS* _Nonnull __fts, FTSENT* _Nonnull __entry, int __options) __INTRODUCED_IN(21);
 
 __END_DECLS
 
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 014226a..c1c0442 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -49,8 +49,11 @@
 #define optional_argument 2
 
 struct option {
-  /** Name of long option. */
-  const char *name;
+  /**
+   * Name of long option. Options must have a non-NULL name.
+   * A NULL name signals the end of the options array.
+   */
+  const char * _Nullable name;
 
   /**
    * One of `no_argument`, `required_argument`, or `optional_argument`.
@@ -58,7 +61,7 @@
   int has_arg;
 
   /** If not NULL, set `*flag` to val when option found. */
-  int* flag;
+  int* _Nullable flag;
 
   /** If `flag` not NULL, the value to assign to `*flag`; otherwise the return value. */
   int val;
@@ -69,12 +72,12 @@
 /**
  * [getopt_long(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
  */
-int getopt_long(int __argc, char* const* __argv, const char* __options, const struct option* __long_options, int* __long_index);
+int getopt_long(int __argc, char* _Nonnull const* _Nonnull __argv, const char* _Nonnull __options, const struct option* _Nonnull __long_options, int* _Nullable __long_index);
 
 /**
  * [getopt_long_only(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
  */
-int getopt_long_only(int __argc, char* const* __argv, const char* __options, const struct option* __long_options, int* __long_index);
+int getopt_long_only(int __argc, char* _Nonnull const* _Nonnull __argv, const char* _Nonnull __options, const struct option* _Nonnull __long_options, int* _Nullable __long_index);
 
 #ifndef _OPTRESET_DECLARED
 #define _OPTRESET_DECLARED
diff --git a/libc/include/grp.h b/libc/include/grp.h
index 9d67adf..2451db5 100644
--- a/libc/include/grp.h
+++ b/libc/include/grp.h
@@ -39,26 +39,26 @@
 #include <sys/types.h>
 
 struct group {
-  char* gr_name; /* group name */
-  char* gr_passwd; /* group password */
+  char* _Nullable gr_name; /* group name */
+  char* _Nullable gr_passwd; /* group password */
   gid_t gr_gid; /* group id */
-  char** gr_mem; /* group members */
+  char* _Nullable * _Nullable gr_mem; /* group members */
 };
 
 __BEGIN_DECLS
 
-struct group* getgrgid(gid_t __gid);
-struct group* getgrnam(const char* __name);
+struct group* _Nullable getgrgid(gid_t __gid);
+struct group* _Nullable getgrnam(const char* _Nonnull __name);
 
 /* Note: Android has thousands and thousands of ids to iterate through. */
-struct group* getgrent(void) __INTRODUCED_IN(26);
+struct group* _Nullable getgrent(void) __INTRODUCED_IN(26);
 
 void setgrent(void) __INTRODUCED_IN(26);
 void endgrent(void) __INTRODUCED_IN(26);
-int getgrgid_r(gid_t __gid, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24);
-int getgrnam_r(const char* __name, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24);
-int getgrouplist(const char* __user, gid_t __group, gid_t* __groups, int* __group_count);
-int initgroups(const char* __user, gid_t __group);
+int getgrgid_r(gid_t __gid, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable * _Nonnull __result) __INTRODUCED_IN(24);
+int getgrnam_r(const char* _Nonnull __name, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable *_Nonnull __result) __INTRODUCED_IN(24);
+int getgrouplist(const char* _Nonnull __user, gid_t __group, gid_t* __BIONIC_COMPLICATED_NULLNESS __groups, int* _Nonnull __group_count);
+int initgroups(const char* _Nonnull __user, gid_t __group);
 
 __END_DECLS
 
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index f8b7f7d..76aee38 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -85,6 +85,42 @@
 #define	PRIiPTR			__PRI_PTR_prefix"i"		/* intptr_t */
 
 /* fprintf macros for unsigned integers */
+#define	PRIb8			"b"		/* int8_t */
+#define	PRIb16			"b"		/* int16_t */
+#define	PRIb32			"b"		/* int32_t */
+#define	PRIb64			__PRI_64_prefix"b"		/* int64_t */
+
+#define	PRIbLEAST8		"b"		/* int_least8_t */
+#define	PRIbLEAST16		"b"		/* int_least16_t */
+#define	PRIbLEAST32		"b"		/* int_least32_t */
+#define	PRIbLEAST64		__PRI_64_prefix"b"		/* int_least64_t */
+
+#define	PRIbFAST8		"b"		/* int_fast8_t */
+#define	PRIbFAST16		__PRI_FAST_prefix"b"	/* int_fast16_t */
+#define	PRIbFAST32		__PRI_FAST_prefix"b"	/* int_fast32_t */
+#define	PRIbFAST64		__PRI_64_prefix"b"		/* int_fast64_t */
+
+#define	PRIbMAX			"jb"		/* intmax_t */
+#define	PRIbPTR			__PRI_PTR_prefix"b"		/* intptr_t */
+
+#define	PRIB8			"B"		/* int8_t */
+#define	PRIB16			"B"		/* int16_t */
+#define	PRIB32			"B"		/* int32_t */
+#define	PRIB64			__PRI_64_prefix"B"		/* int64_t */
+
+#define	PRIBLEAST8		"B"		/* int_least8_t */
+#define	PRIBLEAST16		"B"		/* int_least16_t */
+#define	PRIBLEAST32		"B"		/* int_least32_t */
+#define	PRIBLEAST64		__PRI_64_prefix"B"		/* int_least64_t */
+
+#define	PRIBFAST8		"B"		/* int_fast8_t */
+#define	PRIBFAST16		__PRI_FAST_prefix"B"	/* int_fast16_t */
+#define	PRIBFAST32		__PRI_FAST_prefix"B"	/* int_fast32_t */
+#define	PRIBFAST64		__PRI_64_prefix"B"		/* int_fast64_t */
+
+#define	PRIBMAX			"jB"		/* intmax_t */
+#define	PRIBPTR			__PRI_PTR_prefix"B"		/* intptr_t */
+
 #define	PRIo8			"o"		/* int8_t */
 #define	PRIo16			"o"		/* int16_t */
 #define	PRIo32			"o"		/* int32_t */
@@ -195,6 +231,42 @@
 #define	SCNiPTR			__PRI_PTR_prefix"i"		/* intptr_t */
 
 /* fscanf macros for unsigned integers */
+#define	SCNb8			"hhb"		/* uint8_t */
+#define	SCNb16			"hb"		/* uint16_t */
+#define	SCNb32			"b"		/* uint32_t */
+#define	SCNb64			__PRI_64_prefix"b"		/* uint64_t */
+
+#define	SCNbLEAST8		"hhb"		/* uint_least8_t */
+#define	SCNbLEAST16		"hb"		/* uint_least16_t */
+#define	SCNbLEAST32		"b"		/* uint_least32_t */
+#define	SCNbLEAST64		__PRI_64_prefix"b"		/* uint_least64_t */
+
+#define	SCNbFAST8		"hhb"		/* uint_fast8_t */
+#define	SCNbFAST16		__PRI_FAST_prefix"b"	/* uint_fast16_t */
+#define	SCNbFAST32		__PRI_FAST_prefix"b"	/* uint_fast32_t */
+#define	SCNbFAST64		__PRI_64_prefix"b"		/* uint_fast64_t */
+
+#define	SCNbMAX			"jb"		/* uintmax_t */
+#define	SCNbPTR			__PRI_PTR_prefix"b"		/* uintptr_t */
+
+#define	SCNB8			"hhB"		/* uint8_t */
+#define	SCNB16			"hB"		/* uint16_t */
+#define	SCNB32			"B"		/* uint32_t */
+#define	SCNB64			__PRI_64_prefix"B"		/* uint64_t */
+
+#define	SCNBLEAST8		"hhB"		/* uint_least8_t */
+#define	SCNBLEAST16		"hB"		/* uint_least16_t */
+#define	SCNBLEAST32		"B"		/* uint_least32_t */
+#define	SCNBLEAST64		__PRI_64_prefix"B"		/* uint_least64_t */
+
+#define	SCNBFAST8		"hhB"		/* uint_fast8_t */
+#define	SCNBFAST16		__PRI_FAST_prefix"B"	/* uint_fast16_t */
+#define	SCNBFAST32		__PRI_FAST_prefix"B"	/* uint_fast32_t */
+#define	SCNBFAST64		__PRI_64_prefix"B"		/* uint_fast64_t */
+
+#define	SCNBMAX			"jB"		/* uintmax_t */
+#define	SCNBPTR			__PRI_PTR_prefix"B"		/* uintptr_t */
+
 #define	SCNo8			"hho"		/* uint8_t */
 #define	SCNo16			"ho"		/* uint16_t */
 #define	SCNo32			"o"		/* uint32_t */
diff --git a/libc/include/link.h b/libc/include/link.h
index bd430f5..a0a3d60 100644
--- a/libc/include/link.h
+++ b/libc/include/link.h
@@ -44,41 +44,41 @@
 
 struct dl_phdr_info {
   ElfW(Addr) dlpi_addr;
-  const char* dlpi_name;
-  const ElfW(Phdr)* dlpi_phdr;
+  const char* _Nullable dlpi_name;
+  const ElfW(Phdr)* _Nullable dlpi_phdr;
   ElfW(Half) dlpi_phnum;
 
   // These fields were added in Android R.
   unsigned long long dlpi_adds;
   unsigned long long dlpi_subs;
   size_t dlpi_tls_modid;
-  void* dlpi_tls_data;
+  void* _Nullable dlpi_tls_data;
 };
 
 #if defined(__arm__)
-int dl_iterate_phdr(int (*__callback)(struct dl_phdr_info*, size_t, void*), void* __data) __INTRODUCED_IN(21);
+int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull, size_t, void* _Nullable), void* _Nullable __data) __INTRODUCED_IN(21);
 #else
-int dl_iterate_phdr(int (*__callback)(struct dl_phdr_info*, size_t, void*), void* __data);
+int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull, size_t, void*_Nullable ), void* _Nullable __data);
 #endif
 
 #ifdef __arm__
 typedef uintptr_t _Unwind_Ptr;
-_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);
+_Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int* _Nonnull);
 #endif
 
 /* Used by the dynamic linker to communicate with the debugger. */
 struct link_map {
   ElfW(Addr) l_addr;
-  char* l_name;
-  ElfW(Dyn)* l_ld;
-  struct link_map* l_next;
-  struct link_map* l_prev;
+  char* _Nullable l_name;
+  ElfW(Dyn)* _Nullable l_ld;
+  struct link_map* _Nullable l_next;
+  struct link_map* _Nullable l_prev;
 };
 
 /* Used by the dynamic linker to communicate with the debugger. */
 struct r_debug {
   int32_t r_version;
-  struct link_map* r_map;
+  struct link_map* _Nullable r_map;
   ElfW(Addr) r_brk;
   enum {
     RT_CONSISTENT,
diff --git a/libc/include/locale.h b/libc/include/locale.h
index 8785b24..27f2a3f 100644
--- a/libc/include/locale.h
+++ b/libc/include/locale.h
@@ -70,16 +70,16 @@
                      LC_IDENTIFICATION_MASK)
 
 struct lconv {
-  char* decimal_point;
-  char* thousands_sep;
-  char* grouping;
-  char* int_curr_symbol;
-  char* currency_symbol;
-  char* mon_decimal_point;
-  char* mon_thousands_sep;
-  char* mon_grouping;
-  char* positive_sign;
-  char* negative_sign;
+  char* _Nonnull decimal_point;
+  char* _Nonnull thousands_sep;
+  char* _Nonnull grouping;
+  char* _Nonnull int_curr_symbol;
+  char* _Nonnull currency_symbol;
+  char* _Nonnull mon_decimal_point;
+  char* _Nonnull mon_thousands_sep;
+  char* _Nonnull mon_grouping;
+  char* _Nonnull positive_sign;
+  char* _Nonnull negative_sign;
   char int_frac_digits;
   char frac_digits;
   char p_cs_precedes;
@@ -96,13 +96,13 @@
   char int_n_sign_posn;
 };
 
-struct lconv* localeconv(void) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
+struct lconv* _Nonnull localeconv(void) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
 
-locale_t duplocale(locale_t __l) __INTRODUCED_IN(21);
-void freelocale(locale_t __l) __INTRODUCED_IN(21);
-locale_t newlocale(int __category_mask, const char* __locale_name, locale_t __base) __INTRODUCED_IN(21);
-char* setlocale(int __category, const char* __locale_name);
-locale_t uselocale(locale_t __l) __INTRODUCED_IN(21);
+locale_t _Nullable duplocale(locale_t _Nonnull __l) __INTRODUCED_IN(21);
+void freelocale(locale_t _Nonnull __l) __INTRODUCED_IN(21);
+locale_t _Nullable newlocale(int __category_mask, const char* _Nonnull __locale_name, locale_t _Nullable __base) __INTRODUCED_IN(21);
+char* _Nullable setlocale(int __category, const char* _Nullable __locale_name);
+locale_t _Nullable uselocale(locale_t _Nullable __l) __INTRODUCED_IN(21);
 
 #define LC_GLOBAL_LOCALE __BIONIC_CAST(reinterpret_cast, locale_t, -1L)
 
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 02bda60..6a2d380 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -183,7 +183,15 @@
  * Available since API level 28.
  */
 #define M_PURGE (-101)
-
+/**
+ * mallopt() option to immediately purge all possible memory back to
+ * the kernel. This call can take longer than a normal purge since it
+ * examines everything. In some cases, it can take more than twice the
+ * time of a M_PURGE call. The value is ignored.
+ *
+ * Available since API level 34.
+ */
+#define M_PURGE_ALL (-104)
 
 /**
  * mallopt() option to tune the allocator's choice of memory tags to
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index d5987dc..43cab1f 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -47,21 +47,21 @@
 #define MNTOPT_SUID "suid"
 
 struct mntent {
-  char* mnt_fsname;
-  char* mnt_dir;
-  char* mnt_type;
-  char* mnt_opts;
+  char* _Nullable mnt_fsname;
+  char* _Nullable mnt_dir;
+  char* _Nullable mnt_type;
+  char* _Nullable mnt_opts;
   int mnt_freq;
   int mnt_passno;
 };
 
 __BEGIN_DECLS
 
-int endmntent(FILE* __fp) __INTRODUCED_IN(21);
-struct mntent* getmntent(FILE* __fp);
-struct mntent* getmntent_r(FILE* __fp, struct mntent* __entry, char* __buf, int __size) __INTRODUCED_IN(21);
-FILE* setmntent(const char* __filename, const char* __type) __INTRODUCED_IN(21);
-char* hasmntopt(const struct mntent* __entry, const char* __option) __INTRODUCED_IN(26);
+int endmntent(FILE* _Nullable __fp) __INTRODUCED_IN(21);
+struct mntent* _Nullable getmntent(FILE* _Nonnull __fp);
+struct mntent* _Nullable getmntent_r(FILE* _Nonnull __fp, struct mntent* _Nonnull __entry, char* _Nonnull __buf, int __size) __INTRODUCED_IN(21);
+FILE* _Nullable setmntent(const char* _Nonnull __filename, const char* _Nonnull __type) __INTRODUCED_IN(21);
+char* _Nullable hasmntopt(const struct mntent* _Nonnull __entry, const char* _Nonnull __option) __INTRODUCED_IN(26);
 
 __END_DECLS
 
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index fd1ebc3..98695eb 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -94,41 +94,41 @@
 #define PTHREAD_SCOPE_SYSTEM 0
 #define PTHREAD_SCOPE_PROCESS 1
 
-int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void));
+int pthread_atfork(void (* _Nullable __prepare)(void), void (* _Nullable __parent)(void), void (* _Nullable __child)(void));
 
-int pthread_attr_destroy(pthread_attr_t* __attr);
-int pthread_attr_getdetachstate(const pthread_attr_t* __attr, int* __state);
-int pthread_attr_getguardsize(const pthread_attr_t* __attr, size_t* __size);
-int pthread_attr_getinheritsched(const pthread_attr_t* __attr, int* __flag) __INTRODUCED_IN(28);
-int pthread_attr_getschedparam(const pthread_attr_t* __attr, struct sched_param* __param);
-int pthread_attr_getschedpolicy(const pthread_attr_t* __attr, int* __policy);
-int pthread_attr_getscope(const pthread_attr_t* __attr, int* __scope);
-int pthread_attr_getstack(const pthread_attr_t* __attr, void** __addr, size_t* __size);
-int pthread_attr_getstacksize(const pthread_attr_t* __attr, size_t* __size);
-int pthread_attr_init(pthread_attr_t* __attr);
-int pthread_attr_setdetachstate(pthread_attr_t* __attr, int __state);
-int pthread_attr_setguardsize(pthread_attr_t* __attr, size_t __size);
-int pthread_attr_setinheritsched(pthread_attr_t* __attr, int __flag) __INTRODUCED_IN(28);
-int pthread_attr_setschedparam(pthread_attr_t* __attr, const struct sched_param* __param);
-int pthread_attr_setschedpolicy(pthread_attr_t* __attr, int __policy);
-int pthread_attr_setscope(pthread_attr_t* __attr, int __scope);
-int pthread_attr_setstack(pthread_attr_t* __attr, void* __addr, size_t __size);
-int pthread_attr_setstacksize(pthread_attr_t* __addr, size_t __size);
+int pthread_attr_destroy(pthread_attr_t* _Nonnull __attr);
+int pthread_attr_getdetachstate(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __state);
+int pthread_attr_getguardsize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+int pthread_attr_getinheritsched(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __flag) __INTRODUCED_IN(28);
+int pthread_attr_getschedparam(const pthread_attr_t* _Nonnull __attr, struct sched_param* _Nonnull __param);
+int pthread_attr_getschedpolicy(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __policy);
+int pthread_attr_getscope(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __scope);
+int pthread_attr_getstack(const pthread_attr_t* _Nonnull __attr, void* _Nullable * _Nonnull __addr, size_t* _Nonnull __size);
+int pthread_attr_getstacksize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+int pthread_attr_init(pthread_attr_t* _Nonnull __attr);
+int pthread_attr_setdetachstate(pthread_attr_t* _Nonnull __attr, int __state);
+int pthread_attr_setguardsize(pthread_attr_t* _Nonnull __attr, size_t __size);
+int pthread_attr_setinheritsched(pthread_attr_t* _Nonnull __attr, int __flag) __INTRODUCED_IN(28);
+int pthread_attr_setschedparam(pthread_attr_t* _Nonnull __attr, const struct sched_param* _Nonnull __param);
+int pthread_attr_setschedpolicy(pthread_attr_t* _Nonnull __attr, int __policy);
+int pthread_attr_setscope(pthread_attr_t* _Nonnull __attr, int __scope);
+int pthread_attr_setstack(pthread_attr_t* _Nonnull __attr, void* _Nonnull __addr, size_t __size);
+int pthread_attr_setstacksize(pthread_attr_t* _Nonnull __addr, size_t __size);
 
-int pthread_condattr_destroy(pthread_condattr_t* __attr);
-int pthread_condattr_getclock(const pthread_condattr_t* __attr, clockid_t* __clock) __INTRODUCED_IN(21);
-int pthread_condattr_getpshared(const pthread_condattr_t* __attr, int* __shared);
-int pthread_condattr_init(pthread_condattr_t* __attr);
-int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __INTRODUCED_IN(21);
-int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared);
+int pthread_condattr_destroy(pthread_condattr_t* _Nonnull __attr);
+int pthread_condattr_getclock(const pthread_condattr_t* _Nonnull __attr, clockid_t* _Nonnull __clock) __INTRODUCED_IN(21);
+int pthread_condattr_getpshared(const pthread_condattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_condattr_init(pthread_condattr_t* _Nonnull __attr);
+int pthread_condattr_setclock(pthread_condattr_t* _Nonnull __attr, clockid_t __clock) __INTRODUCED_IN(21);
+int pthread_condattr_setpshared(pthread_condattr_t* _Nonnull __attr, int __shared);
 
-int pthread_cond_broadcast(pthread_cond_t* __cond);
-int pthread_cond_clockwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, clockid_t __clock,
-                           const struct timespec* __timeout) __INTRODUCED_IN(30);
-int pthread_cond_destroy(pthread_cond_t* __cond);
-int pthread_cond_init(pthread_cond_t* __cond, const pthread_condattr_t* __attr);
-int pthread_cond_signal(pthread_cond_t* __cond);
-int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout);
+int pthread_cond_broadcast(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_clockwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
+                           const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_cond_destroy(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_init(pthread_cond_t* _Nonnull __cond, const pthread_condattr_t* _Nullable __attr);
+int pthread_cond_signal(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_timedwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout);
 /*
  * Condition variables use CLOCK_REALTIME by default for their timeouts, however that is
  * typically inappropriate, since that clock can change dramatically, causing the timeout to
@@ -139,9 +139,9 @@
  * Note that pthread_cond_clockwait() allows specifying an arbitrary clock and has superseded this
  * function.
  */
-int pthread_cond_timedwait_monotonic_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex,
-                                        const struct timespec* __timeout) __INTRODUCED_IN_64(28);
-int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex,
+                                        const struct timespec* _Nullable __timeout) __INTRODUCED_IN_64(28);
+int pthread_cond_wait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex);
 
 #if defined(__clang__)
 /*
@@ -153,44 +153,44 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wbuiltin-requires-header"
 #endif
-int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+int pthread_create(pthread_t* _Nonnull __pthread_ptr, pthread_attr_t const* _Nullable __attr, void* _Nonnull (* _Nonnull __start_routine)(void* _Nonnull), void* _Nullable);
 #if defined(__clang__)
 #pragma clang diagnostic pop
 #endif
 
 int pthread_detach(pthread_t __pthread);
-void pthread_exit(void* __return_value) __noreturn;
+void pthread_exit(void* _Nullable __return_value) __noreturn;
 
 int pthread_equal(pthread_t __lhs, pthread_t __rhs);
 
-int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* __attr);
+int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* _Nonnull __attr);
 
-int pthread_getcpuclockid(pthread_t __pthread, clockid_t* __clock);
+int pthread_getcpuclockid(pthread_t __pthread, clockid_t* _Nonnull __clock);
 
-void* pthread_getspecific(pthread_key_t __key);
+void* _Nullable pthread_getspecific(pthread_key_t __key);
 
 pid_t pthread_gettid_np(pthread_t __pthread) __INTRODUCED_IN(21);
 
-int pthread_join(pthread_t __pthread, void** __return_value_ptr);
+int pthread_join(pthread_t __pthread, void* _Nullable * _Nullable __return_value_ptr);
 
-int pthread_key_create(pthread_key_t* __key_ptr, void (*__key_destructor)(void*));
+int pthread_key_create(pthread_key_t* _Nonnull __key_ptr, void (* _Nullable __key_destructor)(void* _Nullable));
 int pthread_key_delete(pthread_key_t __key);
 
-int pthread_mutexattr_destroy(pthread_mutexattr_t* __attr);
-int pthread_mutexattr_getpshared(const pthread_mutexattr_t* __attr, int* __shared);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t* __attr, int* __type);
-int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* __attr, int* __protocol) __INTRODUCED_IN(28);
-int pthread_mutexattr_init(pthread_mutexattr_t* __attr);
-int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared);
-int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type);
-int pthread_mutexattr_setprotocol(pthread_mutexattr_t* __attr, int __protocol) __INTRODUCED_IN(28);
+int pthread_mutexattr_destroy(pthread_mutexattr_t* _Nonnull __attr);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __type);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __protocol) __INTRODUCED_IN(28);
+int pthread_mutexattr_init(pthread_mutexattr_t* _Nonnull __attr);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t* _Nonnull __attr, int __shared);
+int pthread_mutexattr_settype(pthread_mutexattr_t* _Nonnull __attr, int __type);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t* _Nonnull __attr, int __protocol) __INTRODUCED_IN(28);
 
-int pthread_mutex_clocklock(pthread_mutex_t* __mutex, clockid_t __clock,
-                            const struct timespec* __abstime) __INTRODUCED_IN(30);
-int pthread_mutex_destroy(pthread_mutex_t* __mutex);
-int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr);
-int pthread_mutex_lock(pthread_mutex_t* __mutex);
-int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __timeout)
+int pthread_mutex_clocklock(pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
+                            const struct timespec* _Nullable __abstime) __INTRODUCED_IN(30);
+int pthread_mutex_destroy(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_init(pthread_mutex_t* _Nonnull __mutex, const pthread_mutexattr_t* _Nullable __attr);
+int pthread_mutex_lock(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_timedlock(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
   __INTRODUCED_IN(21);
 
 /*
@@ -202,69 +202,69 @@
  * Note that pthread_mutex_clocklock() allows specifying an arbitrary clock and has superseded this
  * function.
  */
-int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* __mutex, const struct timespec* __timeout)
+int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
     __INTRODUCED_IN(28);
-int pthread_mutex_trylock(pthread_mutex_t* __mutex);
-int pthread_mutex_unlock(pthread_mutex_t* __mutex);
+int pthread_mutex_trylock(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_unlock(pthread_mutex_t* _Nonnull __mutex);
 
-int pthread_once(pthread_once_t* __once, void (*__init_routine)(void));
+int pthread_once(pthread_once_t* _Nonnull __once, void (* _Nonnull __init_routine)(void));
 
-int pthread_rwlockattr_init(pthread_rwlockattr_t* __attr);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t* __attr);
-int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* __attr, int* __shared);
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* __attr, int __shared);
-int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kind)
+int pthread_rwlockattr_init(pthread_rwlockattr_t* _Nonnull __attr);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t* _Nonnull __attr);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _Nonnull __attr, int __shared);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __kind)
   __INTRODUCED_IN(23);
-int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* _Nonnull __attr, int __kind) __INTRODUCED_IN(23);
 
-int pthread_rwlock_clockrdlock(pthread_rwlock_t* __rwlock, clockid_t __clock,
-                               const struct timespec* __timeout) __INTRODUCED_IN(30);
-int pthread_rwlock_clockwrlock(pthread_rwlock_t* __rwlock, clockid_t __clock,
-                               const struct timespec* __timeout) __INTRODUCED_IN(30);
-int pthread_rwlock_destroy(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_init(pthread_rwlock_t* __rwlock, const pthread_rwlockattr_t* __attr);
-int pthread_rwlock_rdlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_timedrdlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_clockrdlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
+                               const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_rwlock_clockwrlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
+                               const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_rwlock_destroy(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_init(pthread_rwlock_t* _Nonnull __rwlock, const pthread_rwlockattr_t* _Nullable __attr);
+int pthread_rwlock_rdlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
 /* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
-int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* __rwlock,
-                                            const struct timespec* __timeout) __INTRODUCED_IN(28);
-int pthread_rwlock_timedwrlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
+                                            const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
 /* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
-int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* __rwlock,
-                                            const struct timespec* __timeout) __INTRODUCED_IN(28);
-int pthread_rwlock_tryrdlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_trywrlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_unlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_wrlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
+                                            const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_trywrlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull __rwlock);
 
 #if __ANDROID_API__ >= 24
-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* __shared) __INTRODUCED_IN(24);
-int pthread_barrierattr_setpshared(pthread_barrierattr_t* __attr, int __shared) __INTRODUCED_IN(24);
+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 __shared) __INTRODUCED_IN(24);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t* _Nonnull __attr, int __shared) __INTRODUCED_IN(24);
 #endif
 
 #if __ANDROID_API__ >= 24
-int pthread_barrier_init(pthread_barrier_t* __barrier, const pthread_barrierattr_t* __attr, unsigned __count) __INTRODUCED_IN(24);
-int pthread_barrier_destroy(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
-int pthread_barrier_wait(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
+int pthread_barrier_init(pthread_barrier_t* _Nonnull __barrier, const pthread_barrierattr_t* _Nullable __attr, unsigned __count) __INTRODUCED_IN(24);
+int pthread_barrier_destroy(pthread_barrier_t* _Nonnull __barrier) __INTRODUCED_IN(24);
+int pthread_barrier_wait(pthread_barrier_t* _Nonnull __barrier) __INTRODUCED_IN(24);
 #endif
 
 #if __ANDROID_API__ >= 24
-int pthread_spin_destroy(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_init(pthread_spinlock_t* __spinlock, int __shared) __INTRODUCED_IN(24);
-int pthread_spin_lock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_trylock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_unlock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_destroy(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_init(pthread_spinlock_t* _Nonnull __spinlock, int __shared) __INTRODUCED_IN(24);
+int pthread_spin_lock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_trylock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_unlock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
 #endif
 
 pthread_t pthread_self(void) __attribute_const__;
 
 #if defined(__USE_GNU)
-int pthread_getname_np(pthread_t __pthread, char* __buf, size_t __n) __INTRODUCED_IN(26);
+int pthread_getname_np(pthread_t __pthread, char* _Nonnull __buf, size_t __n) __INTRODUCED_IN(26);
 #endif
 /* TODO: this should be __USE_GNU too. */
-int pthread_setname_np(pthread_t __pthread, const char* __name);
+int pthread_setname_np(pthread_t __pthread, const char* _Nonnull __name);
 
 /**
  * [pthread_setschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html)
@@ -277,7 +277,7 @@
  *
  * Returns 0 on success and returns an error number on failure.
  */
-int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* __param);
+int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* _Nonnull __param);
 
 /**
  * [pthread_getschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_getschedparam.3.html)
@@ -285,7 +285,7 @@
  *
  * Returns 0 on success and returns an error number on failure.
  */
-int pthread_getschedparam(pthread_t __pthread, int* __policy, struct sched_param* __param);
+int pthread_getschedparam(pthread_t __pthread, int* _Nonnull __policy, struct sched_param* _Nonnull __param);
 
 /**
  * [pthread_setschedprio(3)](https://man7.org/linux/man-pages/man3/pthread_setschedprio.3.html)
@@ -302,18 +302,18 @@
  */
 int pthread_setschedprio(pthread_t __pthread, int __priority) __INTRODUCED_IN(28);
 
-int pthread_setspecific(pthread_key_t __key, const void* __value);
+int pthread_setspecific(pthread_key_t __key, const void* _Nullable __value);
 
-typedef void (*__pthread_cleanup_func_t)(void*);
+typedef void (* _Nullable __pthread_cleanup_func_t)(void* _Nullable);
 
 typedef struct __pthread_cleanup_t {
-  struct __pthread_cleanup_t*   __cleanup_prev;
-  __pthread_cleanup_func_t      __cleanup_routine;
-  void*                         __cleanup_arg;
+  struct __pthread_cleanup_t*   _Nullable __cleanup_prev;
+  __pthread_cleanup_func_t      _Nullable __cleanup_routine;
+  void*                         _Nullable __cleanup_arg;
 } __pthread_cleanup_t;
 
-void __pthread_cleanup_push(__pthread_cleanup_t* c, __pthread_cleanup_func_t, void*);
-void __pthread_cleanup_pop(__pthread_cleanup_t*, int);
+void __pthread_cleanup_push(__pthread_cleanup_t* _Nonnull c, __pthread_cleanup_func_t _Nullable, void* _Nullable);
+void __pthread_cleanup_pop(__pthread_cleanup_t* _Nonnull, int);
 
 /* Believe or not, the definitions of pthread_cleanup_push and
  * pthread_cleanup_pop below are correct. Posix states that these
diff --git a/libc/include/pwd.h b/libc/include/pwd.h
index d481aac..2b17fbf 100644
--- a/libc/include/pwd.h
+++ b/libc/include/pwd.h
@@ -66,31 +66,31 @@
 __BEGIN_DECLS
 
 struct passwd {
-  char* pw_name;
-  char* pw_passwd;
+  char* _Nullable pw_name;
+  char* _Nullable pw_passwd;
   uid_t pw_uid;
   gid_t pw_gid;
 #ifdef __LP64__
-  char* pw_gecos;
+  char* _Nullable pw_gecos;
 #else
   /* Note: On LP32, we define pw_gecos to pw_passwd since they're both NULL. */
 # define pw_gecos pw_passwd
 #endif
-  char* pw_dir;
-  char* pw_shell;
+  char* _Nullable pw_dir;
+  char* _Nullable pw_shell;
 };
 
-struct passwd* getpwnam(const char* __name);
-struct passwd* getpwuid(uid_t __uid);
+struct passwd* _Nullable getpwnam(const char* _Nonnull __name);
+struct passwd* _Nullable getpwuid(uid_t __uid);
 
 /* Note: Android has thousands and thousands of ids to iterate through */
-struct passwd* getpwent(void) __INTRODUCED_IN(26);
+struct passwd* _Nullable getpwent(void) __INTRODUCED_IN(26);
 
 void setpwent(void) __INTRODUCED_IN(26);
 void endpwent(void) __INTRODUCED_IN(26);
 
-int getpwnam_r(const char* __name, struct passwd* __pwd, char* __buf, size_t __n, struct passwd** __result);
-int getpwuid_r(uid_t __uid, struct passwd* __pwd, char* __buf, size_t __n, struct passwd** __result);
+int getpwnam_r(const char* _Nonnull __name, struct passwd* _Nonnull __pwd, char* _Nonnull __buf, size_t __n, struct passwd* _Nullable * _Nonnull __result);
+int getpwuid_r(uid_t __uid, struct passwd* _Nonnull __pwd, char* _Nonnull __buf, size_t __n, struct passwd* _Nullable * _Nonnull __result);
 
 __END_DECLS
 
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index 6318d00..f25484a 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -40,24 +40,24 @@
 __BEGIN_DECLS
 
 #define b64_ntop __b64_ntop
-int b64_ntop(u_char const* __src, size_t __src_size, char* __dst, size_t __dst_size);
+int b64_ntop(u_char const* _Nonnull __src, size_t __src_size, char* _Nonnull __dst, size_t __dst_size);
 #define b64_pton __b64_pton
-int b64_pton(char const* __src, u_char* __dst, size_t __dst_size);
+int b64_pton(char const* _Nonnull __src, u_char* _Nonnull __dst, size_t __dst_size);
 
 #define dn_comp __dn_comp
-int dn_comp(const char* __src, u_char* __dst, int __dst_size, u_char** __dn_ptrs , u_char** __last_dn_ptr);
+int dn_comp(const char* _Nonnull __src, u_char* _Nonnull __dst, int __dst_size, u_char* _Nullable * _Nullable __dn_ptrs , u_char* _Nullable * _Nullable __last_dn_ptr);
 
-int dn_expand(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, int __dst_size);
+int dn_expand(const u_char* _Nonnull __msg, const u_char* _Nonnull __eom, const u_char* _Nonnull __src, char* _Nonnull __dst, int __dst_size);
 
 #define p_class __p_class
-const char* p_class(int __class);
+const char* _Nonnull p_class(int __class);
 #define p_type __p_type
-const char* p_type(int __type);
+const char* _Nonnull p_type(int __type);
 
 int res_init(void);
-int res_mkquery(int __opcode, const char* __domain_name, int __class, int __type, const u_char* __data, int __data_size, const u_char* __new_rr_in, u_char* __buf, int __buf_size);
-int res_query(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
-int res_search(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
+int res_mkquery(int __opcode, const char* _Nonnull __domain_name, int __class, int __type, const u_char* _Nullable __data, int __data_size, const u_char* _Nullable __new_rr_in, u_char* _Nonnull __buf, int __buf_size);
+int res_query(const char* _Nonnull __name, int __class, int __type, u_char* _Nonnull __answer, int __answer_size);
+int res_search(const char* _Nonnull __name, int __class, int __type, u_char* _Nonnull __answer, int __answer_size);
 
 #define res_randomid __res_randomid
 u_int __res_randomid(void) __INTRODUCED_IN(29);
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 364ca10..26bc742 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -104,7 +104,7 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* __param);
+int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* _Nonnull __param);
 
 /**
  * [sched_getscheduler(2)](http://man7.org/linux/man-pages/man2/sched_getcpu.2.html)
@@ -145,7 +145,7 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int sched_setparam(pid_t __pid, const struct sched_param* __param);
+int sched_setparam(pid_t __pid, const struct sched_param* _Nonnull __param);
 
 /**
  * [sched_getparam(2)](http://man7.org/linux/man-pages/man2/sched_getparam.2.html)
@@ -153,7 +153,7 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int sched_getparam(pid_t __pid, struct sched_param* __param);
+int sched_getparam(pid_t __pid, struct sched_param* _Nonnull __param);
 
 /**
  * [sched_rr_get_interval(2)](http://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html)
@@ -161,7 +161,7 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int sched_rr_get_interval(pid_t __pid, struct timespec* __quantum);
+int sched_rr_get_interval(pid_t __pid, struct timespec* _Nonnull __quantum);
 
 #if defined(__USE_GNU)
 
@@ -172,7 +172,7 @@
  * Returns the pid of the child to the caller on success and
  * returns -1 and sets `errno` on failure.
  */
-int clone(int (*__fn)(void*), void* __child_stack, int __flags, void* __arg, ...) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(17);
+int clone(int (* __BIONIC_COMPLICATED_NULLNESS __fn)(void* __BIONIC_COMPLICATED_NULLNESS ), void* __BIONIC_COMPLICATED_NULLNESS __child_stack, int __flags, void* _Nullable __arg, ...) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(17);
 
 /**
  * [unshare(2)](http://man7.org/linux/man-pages/man2/unshare.2.html)
@@ -228,7 +228,7 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* __set);
+int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* _Nonnull __set);
 
 /**
  * [sched_getaffinity(2)](http://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)
@@ -236,7 +236,7 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* __set);
+int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* _Nonnull __set);
 
 /**
  * [CPU_ZERO](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
@@ -308,7 +308,7 @@
  * how many bits are set in a dynamic CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_COUNT_S(setsize, set)  __sched_cpucount((setsize), (set))
-int __sched_cpucount(size_t __set_size, const cpu_set_t* __set);
+int __sched_cpucount(size_t __set_size, const cpu_set_t* _Nonnull __set);
 
 /**
  * [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
@@ -379,14 +379,14 @@
  * allocates a CPU set large enough for CPUs in the range 0..count-1.
  */
 #define CPU_ALLOC(count)  __sched_cpualloc((count))
-cpu_set_t* __sched_cpualloc(size_t __count);
+cpu_set_t* _Nullable __sched_cpualloc(size_t __count);
 
 /**
  * [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
  * deallocates a CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_FREE(set)     __sched_cpufree((set))
-void __sched_cpufree(cpu_set_t* __set);
+void __sched_cpufree(cpu_set_t* _Nonnull __set);
 
 #endif /* __USE_GNU */
 
diff --git a/libc/include/search.h b/libc/include/search.h
index 7c4989a..00deef1 100644
--- a/libc/include/search.h
+++ b/libc/include/search.h
@@ -25,9 +25,9 @@
 /** See hsearch()/hsearch_r(). */
 typedef struct entry {
   /** The string key. */
-  char* key;
+  char* _Nullable key;
   /** The associated data. */
-  void* data;
+  void* _Nullable data;
 } ENTRY;
 
 /**
@@ -57,7 +57,7 @@
 #if defined(__USE_BSD) || defined(__USE_GNU)
 /** The hash table type for hcreate_r()/hdestroy_r()/hsearch_r(). */
 struct hsearch_data {
-  struct __hsearch* __hsearch;
+  struct __hsearch* _Nullable __hsearch;
 };
 #endif
 
@@ -69,7 +69,7 @@
  *
  * Available since API level 21.
  */
-void insque(void* __element, void* __previous) __INTRODUCED_IN(21);
+void insque(void* _Nonnull __element, void* _Nullable __previous) __INTRODUCED_IN(21);
 
 /**
  * [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes
@@ -77,7 +77,7 @@
  *
  * Available since API level 21.
  */
-void remque(void* __element) __INTRODUCED_IN(21);
+void remque(void* _Nonnull __element) __INTRODUCED_IN(21);
 
 /**
  * [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html)
@@ -112,7 +112,7 @@
  *
  * Available since API level 28.
  */
-ENTRY* hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
+ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
 
 #if defined(__USE_BSD) || defined(__USE_GNU)
 
@@ -124,7 +124,7 @@
  *
  * Available since API level 28.
  */
-int hcreate_r(size_t __n, struct hsearch_data* __table) __INTRODUCED_IN(28);
+int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
 
 /**
  * [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
@@ -132,7 +132,7 @@
  *
  * Available since API level 28.
  */
-void hdestroy_r(struct hsearch_data* __table) __INTRODUCED_IN(28);
+void hdestroy_r(struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
 
 /**
  * [hsearch_r(3)](http://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or
@@ -143,7 +143,7 @@
  *
  * Available since API level 28.
  */
-int hsearch_r(ENTRY __entry, ACTION __action, ENTRY** __result, struct hsearch_data* __table) __INTRODUCED_IN(28);
+int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
 
 #endif
 
@@ -158,7 +158,7 @@
  *
  * Available since API level 21.
  */
-void* lfind(const void* __key, const void* __array, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(21);
+void* _Nullable lfind(const void* _Nonnull __key, const void* _Nonnull __array, size_t* _Nonnull __count, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)) __INTRODUCED_IN(21);
 
 /**
  * [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
@@ -173,7 +173,7 @@
  *
  * Available since API level 21.
  */
-void* lsearch(const void* __key, void* __array, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(21);
+void* _Nonnull lsearch(const void* _Nonnull __key, void* _Nonnull __array, size_t* _Nonnull __count, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)) __INTRODUCED_IN(21);
 
 /**
  * [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches
@@ -182,13 +182,13 @@
  *
  * Returns a pointer to the parent of the deleted node, or NULL on failure.
  */
-void* tdelete(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*));
+void* _Nullable tdelete(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
 
 /**
  * [tdestroy(3)](http://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
  * the hash table `__root` using `__free_fn` on each node.
  */
-void tdestroy(void* __root, void (*__free_fn)(void*));
+void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable));
 
 /**
  * [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches
@@ -197,7 +197,7 @@
  *
  * Returns a pointer to the matching node, or NULL on failure.
  */
-void* tfind(const void* __key, void* const* __root_ptr, int (*__comparator)(const void*, const void*));
+void* _Nullable tfind(const void* _Nonnull __key, void* _Nullable const* _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
 
 /**
  * [tsearch(3)](http://man7.org/linux/man-pages/man3/tsearch.3.html) searches
@@ -208,12 +208,12 @@
  *
  * Returns a pointer to the matching node, or to the newly-added node.
  */
-void* tsearch(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*));
+void* _Nullable tsearch(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
 
 /**
  * [twalk(3)](http://man7.org/linux/man-pages/man3/twalk.3.html) calls
  * `__visitor` on every node in the tree.
  */
-void twalk(const void* __root, void (*__visitor)(const void*, VISIT, int)) __INTRODUCED_IN(21);
+void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int)) __INTRODUCED_IN(21);
 
 __END_DECLS
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 5d66f7e..6ad9ea3 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -45,12 +45,12 @@
 
 #define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0)
 
-int sem_clockwait(sem_t* __sem, clockid_t __clock, const struct timespec* __ts) __INTRODUCED_IN(30);
-int sem_destroy(sem_t* __sem);
-int sem_getvalue(sem_t* __sem, int* __value);
-int sem_init(sem_t* __sem, int __shared, unsigned int __value);
-int sem_post(sem_t* __sem);
-int sem_timedwait(sem_t* __sem, const struct timespec* __ts);
+int sem_clockwait(sem_t* _Nonnull __sem, clockid_t __clock, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(30);
+int sem_destroy(sem_t* _Nonnull __sem);
+int sem_getvalue(sem_t* _Nonnull __sem, int* _Nonnull __value);
+int sem_init(sem_t* _Nonnull __sem, int __shared, unsigned int __value);
+int sem_post(sem_t* _Nonnull __sem);
+int sem_timedwait(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts);
 /*
  * POSIX historically only supported using sem_timedwait() with CLOCK_REALTIME, however that is
  * typically inappropriate, since that clock can change dramatically, causing the timeout to either
@@ -59,14 +59,14 @@
  * Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this
  * function.
  */
-int sem_timedwait_monotonic_np(sem_t* __sem, const struct timespec* __ts) __INTRODUCED_IN(28);
-int sem_trywait(sem_t* __sem);
-int sem_wait(sem_t* __sem);
+int sem_timedwait_monotonic_np(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(28);
+int sem_trywait(sem_t* _Nonnull __sem);
+int sem_wait(sem_t* _Nonnull __sem);
 
 /* These aren't actually implemented. */
-sem_t* sem_open(const char* __name, int _flags, ...);
-int sem_close(sem_t* __sem);
-int sem_unlink(const char* __name);
+sem_t* _Nullable sem_open(const char* _Nonnull __name, int _flags, ...);
+int sem_close(sem_t* _Nonnull __sem);
+int sem_unlink(const char* _Nonnull __name);
 
 __END_DECLS
 
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index a3de9c7..6d047ae 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -47,14 +47,33 @@
 #include <sys/cdefs.h>
 
 #if defined(__aarch64__)
+/**
+ * The size in words of an arm64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
 #define _JBLEN 32
 #elif defined(__arm__)
+/** The size in words of an arm32 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 64
 #elif defined(__i386__)
+/** The size in words of an x86 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 10
 #elif defined(__riscv)
-#define _JBLEN 29
+/**
+ * The size in words of a riscv64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
+#define _JBLEN 32
 #elif defined(__x86_64__)
+/** The size in words of an x86-64 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 11
 #endif
 
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index e445453..6c34b98 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -52,40 +52,43 @@
 typedef struct __posix_spawnattr* posix_spawnattr_t;
 typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t;
 
-int posix_spawn(pid_t* __pid, const char* __path, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN(28);
-int posix_spawnp(pid_t* __pid, const char* __file, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN(28);
+int posix_spawn(pid_t* _Nullable __pid, const char* _Nonnull __path, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28);
+int posix_spawnp(pid_t* _Nullable __pid, const char* _Nonnull __file, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28);
 
-int posix_spawnattr_init(posix_spawnattr_t* __attr) __INTRODUCED_IN(28);
-int posix_spawnattr_destroy(posix_spawnattr_t* __attr) __INTRODUCED_IN(28);
+int posix_spawnattr_init(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28);
+int posix_spawnattr_destroy(posix_spawnattr_t _Nonnull * _Nonnull __attr) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setflags(posix_spawnattr_t* __attr, short __flags) __INTRODUCED_IN(28);
-int posix_spawnattr_getflags(const posix_spawnattr_t* __attr, short* __flags) __INTRODUCED_IN(28);
+int posix_spawnattr_setflags(posix_spawnattr_t _Nonnull * _Nonnull __attr, short __flags) __INTRODUCED_IN(28);
+int posix_spawnattr_getflags(const posix_spawnattr_t _Nonnull * _Nonnull __attr, short* _Nonnull __flags) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setpgroup(posix_spawnattr_t* __attr, pid_t __pgroup) __INTRODUCED_IN(28);
-int posix_spawnattr_getpgroup(const posix_spawnattr_t* __attr, pid_t* __pgroup) __INTRODUCED_IN(28);
+int posix_spawnattr_setpgroup(posix_spawnattr_t _Nonnull * _Nonnull __attr, pid_t __pgroup) __INTRODUCED_IN(28);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t _Nonnull * _Nonnull __attr, pid_t* _Nonnull __pgroup) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setsigmask(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_setsigmask64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigmask(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigmask64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigmask(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigmask64(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigmask64(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setsigdefault(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_setsigdefault64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28);
-int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigdefault(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigdefault64(posix_spawnattr_t _Nonnull * _Nonnull __attr, const sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset_t* _Nonnull __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigdefault64(const posix_spawnattr_t _Nonnull * _Nonnull __attr, sigset64_t* _Nonnull __mask) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setschedparam(posix_spawnattr_t* __attr, const struct sched_param* __param) __INTRODUCED_IN(28);
-int posix_spawnattr_getschedparam(const posix_spawnattr_t* __attr, struct sched_param* __param) __INTRODUCED_IN(28);
+int posix_spawnattr_setschedparam(posix_spawnattr_t _Nonnull * _Nonnull __attr, const struct sched_param* _Nonnull __param) __INTRODUCED_IN(28);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t _Nonnull * _Nonnull __attr, struct sched_param* _Nonnull __param) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setschedpolicy(posix_spawnattr_t* __attr, int __policy) __INTRODUCED_IN(28);
-int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* __attr, int* __policy) __INTRODUCED_IN(28);
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t _Nonnull * _Nonnull __attr, int __policy) __INTRODUCED_IN(28);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t _Nonnull * _Nonnull __attr, int* _Nonnull __policy) __INTRODUCED_IN(28);
 
-int posix_spawn_file_actions_init(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions) __INTRODUCED_IN(28);
 
-int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* __actions, int __fd, const char* __path, int __flags, mode_t __mode) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* __actions, int __fd) __INTRODUCED_IN(28);
-int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, const char* _Nonnull __path, int __flags, mode_t __mode) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
+
+int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, const char* _Nonnull __path) __INTRODUCED_IN(34);
+int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t _Nonnull * _Nonnull __actions, int __fd) __INTRODUCED_IN(34);
 
 __END_DECLS
 
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index f4b2911..e748faa 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -59,9 +59,9 @@
 typedef struct __sFILE FILE;
 
 #if __ANDROID_API__ >= 23
-extern FILE* stdin __INTRODUCED_IN(23);
-extern FILE* stdout __INTRODUCED_IN(23);
-extern FILE* stderr __INTRODUCED_IN(23);
+extern FILE* _Nonnull stdin __INTRODUCED_IN(23);
+extern FILE* _Nonnull stdout __INTRODUCED_IN(23);
+extern FILE* _Nonnull stderr __INTRODUCED_IN(23);
 
 /* C99 and earlier plus current C++ standards say these must be macros. */
 #define stdin stdin
@@ -103,54 +103,54 @@
 #define L_tmpnam 4096
 #define TMP_MAX 308915776
 
-void clearerr(FILE* __fp);
-int fclose(FILE* __fp);
-int feof(FILE* __fp);
-int ferror(FILE* __fp);
-int fflush(FILE* __fp);
-int fgetc(FILE* __fp);
-char* fgets(char* __buf, int __size, FILE* __fp);
-int fprintf(FILE* __fp , const char* __fmt, ...) __printflike(2, 3);
-int fputc(int __ch, FILE* __fp);
-int fputs(const char* __s, FILE* __fp);
-size_t fread(void* __buf, size_t __size, size_t __count, FILE* __fp);
-int fscanf(FILE* __fp, const char* __fmt, ...) __scanflike(2, 3);
-size_t fwrite(const void* __buf, size_t __size, size_t __count, FILE* __fp);
-int getc(FILE* __fp);
+void clearerr(FILE* _Nonnull __fp);
+int fclose(FILE* _Nonnull __fp);
+int feof(FILE* _Nonnull __fp);
+int ferror(FILE* _Nonnull __fp);
+int fflush(FILE* _Nullable __fp);
+int fgetc(FILE* _Nonnull __fp);
+char* _Nullable fgets(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp);
+int fprintf(FILE* _Nonnull __fp , const char* _Nonnull __fmt, ...) __printflike(2, 3);
+int fputc(int __ch, FILE* _Nonnull __fp);
+int fputs(const char* _Nonnull __s, FILE* _Nonnull __fp);
+size_t fread(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
+int fscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, ...) __scanflike(2, 3);
+size_t fwrite(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
+int getc(FILE* _Nonnull __fp);
 int getchar(void);
-ssize_t getdelim(char** __line_ptr, size_t* __line_length_ptr, int __delimiter, FILE* __fp) __INTRODUCED_IN(18);
-ssize_t getline(char** __line_ptr, size_t* __line_length_ptr, FILE* __fp) __INTRODUCED_IN(18);
+ssize_t getdelim(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, int __delimiter, FILE* _Nonnull __fp) __INTRODUCED_IN(18);
+ssize_t getline(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, FILE* _Nonnull __fp) __INTRODUCED_IN(18);
 
-void perror(const char* __msg);
-int printf(const char* __fmt, ...) __printflike(1, 2);
-int putc(int __ch, FILE* __fp);
+void perror(const char* _Nullable __msg);
+int printf(const char* _Nonnull __fmt, ...) __printflike(1, 2);
+int putc(int __ch, FILE* _Nonnull __fp);
 int putchar(int __ch);
-int puts(const char* __s);
-int remove(const char* __path);
-void rewind(FILE* __fp);
-int scanf(const char* __fmt, ...) __scanflike(1, 2);
-void setbuf(FILE* __fp, char* __buf);
-int setvbuf(FILE* __fp, char* __buf, int __mode, size_t __size);
-int sscanf(const char* __s, const char* __fmt, ...) __scanflike(2, 3);
-int ungetc(int __ch, FILE* __fp);
-int vfprintf(FILE* __fp, const char* __fmt, va_list __args) __printflike(2, 0);
-int vprintf(const char* __fp, va_list __args) __printflike(1, 0);
+int puts(const char* _Nonnull __s);
+int remove(const char* _Nonnull __path);
+void rewind(FILE* _Nonnull __fp);
+int scanf(const char* _Nonnull __fmt, ...) __scanflike(1, 2);
+void setbuf(FILE* _Nonnull __fp, char* _Nullable __buf);
+int setvbuf(FILE* _Nonnull __fp, char* _Nullable __buf, int __mode, size_t __size);
+int sscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, ...) __scanflike(2, 3);
+int ungetc(int __ch, FILE* _Nonnull __fp);
+int vfprintf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
+int vprintf(const char* _Nonnull __fp, va_list __args) __printflike(1, 0);
 
-int dprintf(int __fd, const char* __fmt, ...) __printflike(2, 3) __INTRODUCED_IN(21);
-int vdprintf(int __fd, const char* __fmt, va_list __args) __printflike(2, 0) __INTRODUCED_IN(21);
+int dprintf(int __fd, const char* _Nonnull __fmt, ...) __printflike(2, 3) __INTRODUCED_IN(21);
+int vdprintf(int __fd, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0) __INTRODUCED_IN(21);
 
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L) || \
     (defined(__cplusplus) && __cplusplus <= 201103L)
-char* gets(char* __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
+char* _Nullable gets(char* _Nonnull __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
 #endif
-int sprintf(char* __s, const char* __fmt, ...)
+int sprintf(char* _Nonnull __s, const char* _Nonnull __fmt, ...)
     __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf");
-int vsprintf(char* __s, const char* __fmt, va_list __args)
+int vsprintf(char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args)
     __printflike(2, 0) __warnattr_strict("vsprintf is often misused; please use vsnprintf");
-char* tmpnam(char* __s)
+char* _Nullable tmpnam(char* _Nullable __s)
     __warnattr("tmpnam is unsafe, use mkstemp or tmpfile instead");
 #define P_tmpdir "/tmp/" /* deprecated */
-char* tempnam(const char* __dir, const char* __prefix)
+char* _Nullable tempnam(const char* _Nullable __dir, const char* _Nullable __prefix)
     __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
 
 /**
@@ -159,7 +159,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int rename(const char* __old_path, const char* __new_path);
+int rename(const char* _Nonnull __old_path, const char* _Nonnull __new_path);
 
 /**
  * [renameat(2)](http://man7.org/linux/man-pages/man2/renameat.2.html) changes
@@ -167,7 +167,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int renameat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path);
+int renameat(int __old_dir_fd, const char* _Nonnull __old_path, int __new_dir_fd, const char* _Nonnull __new_path);
 
 #if defined(__USE_GNU)
 
@@ -196,108 +196,111 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int renameat2(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path, unsigned __flags) __INTRODUCED_IN(30);
+int renameat2(int __old_dir_fd, const char* _Nonnull __old_path, int __new_dir_fd, const char* _Nonnull __new_path, unsigned __flags) __INTRODUCED_IN(30);
 
 #endif
 
-int fseek(FILE* __fp, long __offset, int __whence);
-long ftell(FILE* __fp);
+int fseek(FILE* _Nonnull __fp, long __offset, int __whence);
+long ftell(FILE* _Nonnull __fp);
 
 /* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
 #if defined(__USE_FILE_OFFSET64)
-int fgetpos(FILE* __fp, fpos_t* __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
-int fsetpos(FILE* __fp, const fpos_t* __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
-int fseeko(FILE* __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
-off_t ftello(FILE* __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
+int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
+int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
+int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
+off_t ftello(FILE* _Nonnull __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
 #  if defined(__USE_BSD)
-FILE* funopen(const void* __cookie,
-              int (*__read_fn)(void*, char*, int),
-              int (*__write_fn)(void*, const char*, int),
-              fpos_t (*__seek_fn)(void*, fpos_t, int),
-              int (*__close_fn)(void*)) __RENAME(funopen64) __INTRODUCED_IN(24);
+/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
+FILE* _Nullable funopen(const void* _Nullable __cookie,
+              int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
+              int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
+              fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
+              int (* _Nullable __close_fn)(void* _Nonnull)) __RENAME(funopen64) __INTRODUCED_IN(24);
 #  endif
 #else
-int fgetpos(FILE* __fp, fpos_t* __pos);
-int fsetpos(FILE* __fp, const fpos_t* __pos);
-int fseeko(FILE* __fp, off_t __offset, int __whence);
-off_t ftello(FILE* __fp);
+int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos);
+int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos);
+int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence);
+off_t ftello(FILE* _Nonnull __fp);
 #  if defined(__USE_BSD)
-FILE* funopen(const void* __cookie,
-              int (*__read_fn)(void*, char*, int),
-              int (*__write_fn)(void*, const char*, int),
-              fpos_t (*__seek_fn)(void*, fpos_t, int),
-              int (*__close_fn)(void*));
+/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
+FILE* _Nullable funopen(const void* _Nullable __cookie,
+              int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
+              int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
+              fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
+              int (* _Nullable __close_fn)(void* _Nonnull));
 #  endif
 #endif
-int fgetpos64(FILE* __fp, fpos64_t* __pos) __INTRODUCED_IN(24);
-int fsetpos64(FILE* __fp, const fpos64_t* __pos) __INTRODUCED_IN(24);
-int fseeko64(FILE* __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
-off64_t ftello64(FILE* __fp) __INTRODUCED_IN(24);
+int fgetpos64(FILE* _Nonnull __fp, fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
+int fsetpos64(FILE* _Nonnull __fp, const fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
+int fseeko64(FILE* _Nonnull __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
+off64_t ftello64(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
 #if defined(__USE_BSD)
-FILE* funopen64(const void* __cookie,
-                int (*__read_fn)(void*, char*, int),
-                int (*__write_fn)(void*, const char*, int),
-                fpos64_t (*__seek_fn)(void*, fpos64_t, int),
-                int (*__close_fn)(void*)) __INTRODUCED_IN(24);
+/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
+FILE* _Nullable funopen64(const void* _Nullable __cookie,
+                int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
+                int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
+                fpos64_t (* _Nullable __seek_fn)(void* _Nonnull, fpos64_t, int),
+                int (* _Nullable __close_fn)(void* _Nonnull)) __INTRODUCED_IN(24);
 #endif
 
-FILE* fopen(const char* __path, const char* __mode);
-FILE* fopen64(const char* __path, const char* __mode) __INTRODUCED_IN(24);
-FILE* freopen(const char* __path, const char* __mode, FILE* __fp);
-FILE* freopen64(const char* __path, const char* __mode, FILE* __fp) __INTRODUCED_IN(24);
-FILE* tmpfile(void);
-FILE* tmpfile64(void) __INTRODUCED_IN(24);
+FILE* _Nullable fopen(const char* _Nonnull __path, const char* _Nonnull __mode);
+FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
+FILE* _Nullable freopen(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp);
+FILE* _Nullable freopen64(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+FILE* _Nullable tmpfile(void);
+FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
 
-int snprintf(char* __buf, size_t __size, const char* __fmt, ...) __printflike(3, 4);
-int vfscanf(FILE* __fp, const char* __fmt, va_list __args) __scanflike(2, 0);
-int vscanf(const char* __fmt , va_list __args) __scanflike(1, 0);
-int vsnprintf(char* __buf, size_t __size, const char* __fmt, va_list __args) __printflike(3, 0);
-int vsscanf(const char* __s, const char* __fmt, va_list __args) __scanflike(2, 0);
+int snprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
+int vfscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
+int vscanf(const char* _Nonnull __fmt , va_list __args) __scanflike(1, 0);
+int vsnprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, va_list __args) __printflike(3, 0);
+int vsscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
 
 #define L_ctermid 1024 /* size for ctermid() */
-char* ctermid(char* __buf) __INTRODUCED_IN(26);
+char* _Nonnull ctermid(char* _Nullable __buf) __INTRODUCED_IN(26);
 
-FILE* fdopen(int __fd, const char* __mode);
-int fileno(FILE* __fp);
-int pclose(FILE* __fp);
-FILE* popen(const char* __command, const char* __mode);
-void flockfile(FILE* __fp);
-int ftrylockfile(FILE* __fp);
-void funlockfile(FILE* __fp);
-int getc_unlocked(FILE* __fp);
+FILE* _Nullable fdopen(int __fd, const char* _Nonnull __mode);
+int fileno(FILE* _Nonnull __fp);
+int pclose(FILE* _Nonnull __fp);
+FILE* _Nullable popen(const char* _Nonnull __command, const char* _Nonnull __mode);
+void flockfile(FILE* _Nonnull  __fp);
+int ftrylockfile(FILE* _Nonnull __fp);
+void funlockfile(FILE* _Nonnull __fp);
+int getc_unlocked(FILE* _Nonnull __fp);
 int getchar_unlocked(void);
-int putc_unlocked(int __ch, FILE* __fp);
+int putc_unlocked(int __ch, FILE* _Nonnull __fp);
 int putchar_unlocked(int __ch);
 
-FILE* fmemopen(void* __buf, size_t __size, const char* __mode) __INTRODUCED_IN(23);
-FILE* open_memstream(char** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23);
+FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23);
+FILE* _Nullable open_memstream(char* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
 
 #if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
-int  asprintf(char** __s_ptr, const char* __fmt, ...) __printflike(2, 3);
-char* fgetln(FILE* __fp, size_t* __length_ptr);
-int fpurge(FILE* __fp);
-void setbuffer(FILE* __fp, char* __buf, int __size);
-int setlinebuf(FILE* __fp);
-int vasprintf(char** __s_ptr, const char* __fmt, va_list __args) __printflike(2, 0);
-void clearerr_unlocked(FILE* __fp) __INTRODUCED_IN(23);
-int feof_unlocked(FILE* __fp) __INTRODUCED_IN(23);
-int ferror_unlocked(FILE* __fp) __INTRODUCED_IN(23);
-int fileno_unlocked(FILE* __fp) __INTRODUCED_IN(24);
+int  asprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, ...) __printflike(2, 3);
+char* _Nullable fgetln(FILE* _Nonnull __fp, size_t* _Nonnull __length_ptr);
+int fpurge(FILE* _Nonnull __fp);
+void setbuffer(FILE* _Nonnull __fp, char* _Nullable __buf, int __size);
+int setlinebuf(FILE* _Nonnull __fp);
+int vasprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
+void clearerr_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+int feof_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+int ferror_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
 #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
 #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
 #endif
 
 #if defined(__USE_BSD)
-int fflush_unlocked(FILE* __fp) __INTRODUCED_IN(28);
-int fgetc_unlocked(FILE* __fp) __INTRODUCED_IN(28);
-int fputc_unlocked(int __ch, FILE* __fp) __INTRODUCED_IN(28);
-size_t fread_unlocked(void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN(28);
-size_t fwrite_unlocked(const void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN(28);
+int fflush_unlocked(FILE* _Nullable __fp) __INTRODUCED_IN(28);
+int fgetc_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+int fputc_unlocked(int __ch, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+size_t fread_unlocked(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+size_t fwrite_unlocked(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
 #endif
 
 #if defined(__USE_GNU)
-int fputs_unlocked(const char* __s, FILE* __fp) __INTRODUCED_IN(28);
-char* fgets_unlocked(char* __buf, int __size, FILE* __fp) __INTRODUCED_IN(28);
+int fputs_unlocked(const char* _Nonnull __s, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+char* _Nullable fgets_unlocked(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
 #endif
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index b416f62..2bcb870 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -91,7 +91,7 @@
 
 void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
 
-void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
+void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nullable __lhs, const void* _Nullable __rhs));
 
 uint32_t arc4random(void);
 uint32_t arc4random_uniform(uint32_t __upper_bound);
diff --git a/libc/include/sys/capability.h b/libc/include/sys/capability.h
index 4cb698f..b43bbf0 100644
--- a/libc/include/sys/capability.h
+++ b/libc/include/sys/capability.h
@@ -44,7 +44,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int capget(cap_user_header_t __hdr_ptr, cap_user_data_t __data_ptr);
+int capget(cap_user_header_t _Nonnull __hdr_ptr, cap_user_data_t _Nullable __data_ptr);
 
 /**
  * [capset(2)](http://man7.org/linux/man-pages/man2/capset.2.html) sets the calling
@@ -52,6 +52,6 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int capset(cap_user_header_t __hdr_ptr, const cap_user_data_t __data_ptr);
+int capset(cap_user_header_t _Nonnull __hdr_ptr, const cap_user_data_t _Nullable __data_ptr);
 
 __END_DECLS
diff --git a/libc/include/sys/inotify.h b/libc/include/sys/inotify.h
index c3cdc85..e834d07 100644
--- a/libc/include/sys/inotify.h
+++ b/libc/include/sys/inotify.h
@@ -42,7 +42,7 @@
 
 int inotify_init(void);
 int inotify_init1(int __flags) __INTRODUCED_IN(21);
-int inotify_add_watch(int __fd, const char* __path, uint32_t __mask);
+int inotify_add_watch(int __fd, const char* _Nonnull __path, uint32_t __mask);
 int inotify_rm_watch(int __fd, uint32_t __watch_descriptor);
 
 __END_DECLS
diff --git a/libc/include/sys/ipc.h b/libc/include/sys/ipc.h
index c81ec1a..2e2b8cf 100644
--- a/libc/include/sys/ipc.h
+++ b/libc/include/sys/ipc.h
@@ -52,6 +52,6 @@
  *
  * Returns a key on success, and returns -1 and sets `errno` on failure.
  */
-key_t ftok(const char* __path, int __id);
+key_t ftok(const char* _Nonnull __path, int __id);
 
 __END_DECLS
diff --git a/libc/include/sys/mount.h b/libc/include/sys/mount.h
index 4db1ac1..aace205 100644
--- a/libc/include/sys/mount.h
+++ b/libc/include/sys/mount.h
@@ -55,7 +55,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int mount(const char* __source, const char* __target, const char* __fs_type, unsigned long __flags, const void* __data);
+int mount(const char* __BIONIC_COMPLICATED_NULLNESS __source, const char* _Nonnull __target, const char* __BIONIC_COMPLICATED_NULLNESS __fs_type, unsigned long __flags, const void* _Nullable __data);
 
 /**
  * [umount(2)](http://man7.org/linux/man-pages/man2/umount.2.html) unmounts the filesystem at
@@ -63,7 +63,7 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int umount(const char* __target);
+int umount(const char* _Nonnull __target);
 
 /**
  * [umount2(2)](http://man7.org/linux/man-pages/man2/umount2.2.html) unmounts the filesystem at
@@ -71,6 +71,6 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int umount2(const char* __target, int __flags);
+int umount2(const char* _Nonnull __target, int __flags);
 
 __END_DECLS
diff --git a/libc/include/sys/msg.h b/libc/include/sys/msg.h
index e19452c..ad481a0 100644
--- a/libc/include/sys/msg.h
+++ b/libc/include/sys/msg.h
@@ -46,12 +46,12 @@
 typedef __kernel_ulong_t msglen_t;
 
 /** Not useful on Android; disallowed by SELinux. */
-int msgctl(int __msg_id, int __cmd, struct msqid_ds* __buf) __INTRODUCED_IN(26);
+int msgctl(int __msg_id, int __cmd, struct msqid_ds* _Nullable __buf) __INTRODUCED_IN(26);
 /** Not useful on Android; disallowed by SELinux. */
 int msgget(key_t __key, int __flags) __INTRODUCED_IN(26);
 /** Not useful on Android; disallowed by SELinux. */
-ssize_t msgrcv(int __msg_id, void* __msgbuf_ptr, size_t __size, long __type, int __flags) __INTRODUCED_IN(26);
+ssize_t msgrcv(int __msg_id, void* _Nonnull __msgbuf_ptr, size_t __size, long __type, int __flags) __INTRODUCED_IN(26);
 /** Not useful on Android; disallowed by SELinux. */
-int msgsnd(int __msg_id, const void* __msgbuf_ptr, size_t __size, int __flags) __INTRODUCED_IN(26);
+int msgsnd(int __msg_id, const void* _Nonnull __msgbuf_ptr, size_t __size, int __flags) __INTRODUCED_IN(26);
 
 __END_DECLS
diff --git a/libc/include/sys/pidfd.h b/libc/include/sys/pidfd.h
index 6d0e809..30455bb 100644
--- a/libc/include/sys/pidfd.h
+++ b/libc/include/sys/pidfd.h
@@ -71,6 +71,6 @@
  *
  * Available since API level 31.
  */
-int pidfd_send_signal(int __pidfd, int __sig, siginfo_t *__info, unsigned int __flags) __INTRODUCED_IN(31);
+int pidfd_send_signal(int __pidfd, int __sig, siginfo_t * _Nullable __info, unsigned int __flags) __INTRODUCED_IN(31);
 
 __END_DECLS
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index be52bd9..0251176 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -50,7 +50,7 @@
  *
  * See also arc4random_buf() which is available in all API levels.
  */
-int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
 
 /**
  * [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
@@ -62,6 +62,6 @@
  *
  * See also arc4random_buf() which is available in all API levels.
  */
-ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
+ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
 
 __END_DECLS
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 60bbde8..4b00d5d 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -40,7 +40,7 @@
 
 /* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
 #if defined(__USE_FILE_OFFSET64)
-ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
 #else
 /**
  * [sendfile(2)](http://man7.org/linux/man-pages/man2/sendfile.2.html) copies data directly
@@ -50,13 +50,13 @@
  *
  * Available since API level 21.
  */
-ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count);
 #endif
 
 /**
  * Like sendfile() but allows using a 64-bit offset
  * even from a 32-bit process without `__FILE_OFFSET_BITS=64`.
  */
-ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* __offset, size_t __count) __INTRODUCED_IN(21);
+ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* _Nullable __offset, size_t __count) __INTRODUCED_IN(21);
 
 __END_DECLS
diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h
index bd911f7..f669cc8 100644
--- a/libc/include/sys/signalfd.h
+++ b/libc/include/sys/signalfd.h
@@ -48,11 +48,11 @@
  *
  * Available since API level 18.
  */
-int signalfd(int __fd, const sigset_t* __mask, int __flags) __INTRODUCED_IN(18);
+int signalfd(int __fd, const sigset_t* _Nonnull __mask, int __flags) __INTRODUCED_IN(18);
 
 /**
  * Like signalfd() but allows setting a signal mask with RT signals even from a 32-bit process.
  */
-int signalfd64(int __fd, const sigset64_t* __mask, int __flags) __INTRODUCED_IN(28);
+int signalfd64(int __fd, const sigset64_t* _Nonnull __mask, int __flags) __INTRODUCED_IN(28);
 
 __END_DECLS
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 8e5873d..bb6443b 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -316,6 +316,8 @@
 
 #define NGREG 32
 
+#if defined(__USE_GNU)
+
 #define REG_PC 0
 #define REG_RA 1
 #define REG_SP 2
@@ -323,6 +325,8 @@
 #define REG_S0 8
 #define REG_A0 10
 
+#endif // defined(__USE_GNU)
+
 typedef unsigned long __riscv_mc_gp_state[NGREG];
 
 typedef unsigned long greg_t;
@@ -362,9 +366,9 @@
 
 /* This matches the kernel <asm/ucontext.h> but using mcontext_t. */
 
-typedef struct ucontext_t {
+typedef struct ucontext {
   unsigned long uc_flags;
-  struct ucontext_t* uc_link;
+  struct ucontext* uc_link;
   stack_t uc_stack;
   union {
     sigset_t uc_sigmask;
diff --git a/libc/include/sys/utsname.h b/libc/include/sys/utsname.h
index 1fa3187..aa8c1a0 100644
--- a/libc/include/sys/utsname.h
+++ b/libc/include/sys/utsname.h
@@ -62,6 +62,6 @@
  *
  * Returns 0 on success, and returns -1 and sets `errno` on failure.
  */
-int uname(struct utsname* __buf);
+int uname(struct utsname* _Nonnull __buf);
 
 __END_DECLS
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 96974a2..e6fb855 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -37,9 +37,9 @@
 
 __BEGIN_DECLS
 
-pid_t wait(int* __status);
-pid_t waitpid(pid_t __pid, int* __status, int __options);
-pid_t wait4(pid_t __pid, int* __status, int __options, struct rusage* __rusage) __INTRODUCED_IN(18);
+pid_t wait(int* _Nullable __status);
+pid_t waitpid(pid_t __pid, int* _Nullable __status, int __options);
+pid_t wait4(pid_t __pid, int* _Nullable __status, int __options, struct rusage* _Nullable __rusage) __INTRODUCED_IN(18);
 
 /* Posix states that idtype_t should be an enumeration type, but
  * the kernel headers define P_ALL, P_PID and P_PGID as constant macros
@@ -47,6 +47,6 @@
  */
 typedef int idtype_t;
 
-int waitid(idtype_t __type, id_t __id, siginfo_t* __info, int __options);
+int waitid(idtype_t __type, id_t __id, siginfo_t* _Nullable __info, int __options);
 
 __END_DECLS
diff --git a/libc/include/threads.h b/libc/include/threads.h
index 1b00b8f..b1008de 100644
--- a/libc/include/threads.h
+++ b/libc/include/threads.h
@@ -51,9 +51,9 @@
 typedef pthread_mutex_t mtx_t;
 
 /** The type for a thread-specific storage destructor. */
-typedef void (*tss_dtor_t)(void*);
+typedef void (*tss_dtor_t)(void* _Nullable);
 /** The type of the function passed to thrd_create() to create a new thread. */
-typedef int (*thrd_start_t)(void*);
+typedef int (*thrd_start_t)(void* _Nullable);
 
 /** The type used by call_once(). */
 typedef pthread_once_t once_flag;
@@ -82,72 +82,72 @@
 // This file is implemented as static inlines before API level 30.
 
 /** Uses `__flag` to ensure that `__function` is called exactly once. */
-void call_once(once_flag* __flag, void (*__function)(void)) __INTRODUCED_IN(30);
+void call_once(once_flag* _Nonnull __flag, void (* _Nonnull __function)(void)) __INTRODUCED_IN(30);
 
 
 
 /**
  * Unblocks all threads blocked on `__cond`.
  */
-int cnd_broadcast(cnd_t* __cond) __INTRODUCED_IN(30);
+int cnd_broadcast(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
 
 /**
  * Destroys a condition variable.
  */
-void cnd_destroy(cnd_t* __cond) __INTRODUCED_IN(30);
+void cnd_destroy(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
 
 /**
  * Creates a condition variable.
  */
-int cnd_init(cnd_t* __cond) __INTRODUCED_IN(30);
+int cnd_init(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
 
 /**
  * Unblocks one thread blocked on `__cond`.
  */
-int cnd_signal(cnd_t* __cond) __INTRODUCED_IN(30);
+int cnd_signal(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
 
 /**
  * Unlocks `__mutex` and blocks until `__cond` is signaled or `__timeout` occurs.
  */
-int cnd_timedwait(cnd_t* __cond, mtx_t* __mutex, const struct timespec* __timeout)
+int cnd_timedwait(cnd_t* _Nonnull __cond, mtx_t* _Nonnull __mutex, const struct timespec* _Nonnull __timeout)
     __INTRODUCED_IN(30);
 
 /**
  * Unlocks `__mutex` and blocks until `__cond` is signaled.
  */
-int cnd_wait(cnd_t* __cond, mtx_t* __mutex) __INTRODUCED_IN(30);
+int cnd_wait(cnd_t* _Nonnull __cond, mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
 
 
 
 /**
  * Destroys a mutex.
  */
-void mtx_destroy(mtx_t* __mutex) __INTRODUCED_IN(30);
+void mtx_destroy(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
 
 /**
  * Creates a mutex.
  */
-int mtx_init(mtx_t* __mutex, int __type) __INTRODUCED_IN(30);
+int mtx_init(mtx_t* _Nonnull __mutex, int __type) __INTRODUCED_IN(30);
 
 /**
  * Blocks until `__mutex` is acquired.
  */
-int mtx_lock(mtx_t* __mutex) __INTRODUCED_IN(30);
+int mtx_lock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
 
 /**
  * Blocks until `__mutex` is acquired or `__timeout` expires.
  */
-int mtx_timedlock(mtx_t* __mutex, const struct timespec* __timeout) __INTRODUCED_IN(30);
+int mtx_timedlock(mtx_t* _Nonnull __mutex, const struct timespec* _Nonnull __timeout) __INTRODUCED_IN(30);
 
 /**
  * Acquires `__mutex` or returns `thrd_busy`.
  */
-int mtx_trylock(mtx_t* __mutex) __INTRODUCED_IN(30);
+int mtx_trylock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
 
 /**
  * Unlocks `__mutex`.
  */
-int mtx_unlock(mtx_t* __mutex) __INTRODUCED_IN(30);
+int mtx_unlock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
 
 
 
@@ -155,7 +155,7 @@
  * Creates a new thread running `__function(__arg)`, and sets `*__thrd` to
  * the new thread.
  */
-int thrd_create(thrd_t* __thrd, thrd_start_t __function, void* __arg) __INTRODUCED_IN(30);
+int thrd_create(thrd_t* _Nonnull __thrd, thrd_start_t _Nonnull __function, void* _Nullable __arg) __INTRODUCED_IN(30);
 
 /**
  * Returns the `thrd_t` corresponding to the caller.
@@ -181,7 +181,7 @@
  * Blocks until `__thrd` terminates. If `__result` is not null, `*__result`
  * is set to the exiting thread's result.
  */
-int thrd_join(thrd_t __thrd, int* __result) __INTRODUCED_IN(30);
+int thrd_join(thrd_t __thrd, int* _Nullable __result) __INTRODUCED_IN(30);
 
 /**
  * Blocks the caller for at least `__duration` unless a signal is delivered.
@@ -190,7 +190,7 @@
  *
  * Returns 0 on success, or -1 if a signal was delivered.
  */
-int thrd_sleep(const struct timespec* __duration, struct timespec* __remaining) __INTRODUCED_IN(30);
+int thrd_sleep(const struct timespec* _Nonnull __duration, struct timespec* _Nullable __remaining) __INTRODUCED_IN(30);
 
 /**
  * Request that other threads should be scheduled.
@@ -203,7 +203,7 @@
  * Creates a thread-specific storage key with the associated destructor (which
  * may be null).
  */
-int tss_create(tss_t* __key, tss_dtor_t __dtor) __INTRODUCED_IN(30);
+int tss_create(tss_t* _Nonnull __key, tss_dtor_t _Nullable __dtor) __INTRODUCED_IN(30);
 
 /**
  * Destroys a thread-specific storage key.
@@ -214,13 +214,13 @@
  * Returns the value for the current thread held in the thread-specific storage
  * identified by `__key`.
  */
-void* tss_get(tss_t __key) __INTRODUCED_IN(30);
+void* _Nullable tss_get(tss_t __key) __INTRODUCED_IN(30);
 
 /**
  * Sets the current thread's value for the thread-specific storage identified
  * by `__key` to `__value`.
  */
-int tss_set(tss_t __key, void* __value) __INTRODUCED_IN(30);
+int tss_set(tss_t __key, void* _Nonnull __value) __INTRODUCED_IN(30);
 
 #endif
 
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index 7aa5718..d249f8a 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -30,7 +30,7 @@
 
 /**
  * @file utmp.h
- * @brief POSIX login records.
+ * @brief No-op implementation of non-POSIX login records. See <utmpx.h> for the POSIX equivalents.
  */
 
 #include <sys/cdefs.h>
@@ -69,12 +69,12 @@
 };
 
 struct exit_status {
-  short int e_termination;
-  short int e_exit;
+  short e_termination;
+  short e_exit;
 };
 
 struct utmp {
-  short int ut_type;
+  short ut_type;
   pid_t ut_pid;
   char ut_line[UT_LINESIZE];
   char ut_id[4];
@@ -83,7 +83,7 @@
 
   struct exit_status ut_exit;
 
-  long int ut_session;
+  long ut_session;
   struct timeval ut_tv;
 
   int32_t ut_addr_v6[4];
@@ -97,21 +97,25 @@
 __BEGIN_DECLS
 
 /**
- * Does nothing.
+ * Returns -1 and sets errno to ENOTSUP.
  */
 int utmpname(const char* _Nonnull __path);
+
 /**
  * Does nothing.
  */
 void setutent(void);
+
 /**
- * Does nothing.
+ * Does nothing and returns null.
  */
 struct utmp* _Nullable getutent(void);
+
 /**
- * Does nothing.
+ * Does nothing and returns null.
  */
 struct utmp* _Nullable pututline(const struct utmp* _Nonnull __entry);
+
 /**
  * Does nothing.
  */
diff --git a/libc/include/utmpx.h b/libc/include/utmpx.h
new file mode 100644
index 0000000..5ed8e1a
--- /dev/null
+++ b/libc/include/utmpx.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+/**
+ * @file utmpx.h
+ * @brief No-op implementation of POSIX login records.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <time.h>
+
+#define EMPTY         0
+#define RUN_LVL       1
+#define BOOT_TIME     2
+#define NEW_TIME      3
+#define OLD_TIME      4
+#define INIT_PROCESS  5
+#define LOGIN_PROCESS 6
+#define USER_PROCESS  7
+#define DEAD_PROCESS  8
+#define ACCOUNTING    9
+
+struct utmpx {
+  short ut_type;
+  pid_t ut_pid;
+  char ut_line[32];
+  char ut_id[4];
+  char ut_user[32];
+  char ut_host[256];
+
+  struct {
+    short e_termination;
+    short e_exit;
+  } ut_exit;
+
+  long ut_session;
+  struct timeval ut_tv;
+
+  int32_t ut_addr_v6[4];
+  char unused[20];
+};
+
+__BEGIN_DECLS
+
+/**
+ * Does nothing.
+ */
+void setutxent(void) __RENAME(setutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable getutxent(void) __RENAME(getutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable getutxid(const struct utmpx* _Nonnull __entry) __RENAME(getutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable getutxline(const struct utmpx* _Nonnull __entry) __RENAME(getutent);
+
+/**
+ * Does nothing and returns null.
+ */
+struct utmpx* _Nullable pututxline(const struct utmpx* _Nonnull __entry) __RENAME(pututline);
+
+/**
+ * Does nothing.
+ */
+void endutxent(void) __RENAME(endutent);
+
+__END_DECLS
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index add3606..39f9374 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -44,97 +44,96 @@
 __BEGIN_DECLS
 
 wint_t btowc(int __ch);
-int fwprintf(FILE* __fp, const wchar_t* __fmt, ...);
-int fwscanf(FILE* __fp, const wchar_t* __fmt, ...);
-wint_t fgetwc(FILE* __fp);
-wchar_t* fgetws(wchar_t* __buf, int __size, FILE* __fp);
-wint_t fputwc(wchar_t __wc, FILE* __fp);
-int fputws(const wchar_t* __s, FILE* __fp);
-int fwide(FILE* __fp, int __mode);
-wint_t getwc(FILE* __fp);
+int fwprintf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, ...);
+int fwscanf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, ...);
+wint_t fgetwc(FILE* _Nonnull __fp);
+wchar_t* _Nullable fgetws(wchar_t* _Nonnull __buf, int __size, FILE* _Nonnull __fp);
+wint_t fputwc(wchar_t __wc, FILE* _Nonnull __fp);
+int fputws(const wchar_t* _Nonnull __s, FILE* _Nonnull __fp);
+int fwide(FILE* _Nonnull __fp, int __mode);
+wint_t getwc(FILE* _Nonnull __fp);
 wint_t getwchar(void);
-int mbsinit(const mbstate_t* __ps);
-size_t mbrlen(const char* __s, size_t __n, mbstate_t* __ps);
-size_t mbrtowc(wchar_t* __buf, const char* __s, size_t __n, mbstate_t* __ps);
-size_t mbsrtowcs(wchar_t* __dst, const char** __src, size_t __dst_n, mbstate_t* __ps);
-size_t mbsnrtowcs(wchar_t* __dst, const char** __src, size_t __src_n, size_t __dst_n, mbstate_t* __ps) __INTRODUCED_IN(21);
-wint_t putwc(wchar_t __wc, FILE* __fp);
+int mbsinit(const mbstate_t* _Nullable __ps);
+size_t mbrlen(const char* _Nullable __s, size_t __n, mbstate_t* _Nullable __ps);
+size_t mbrtowc(wchar_t* _Nullable __buf, const char* _Nullable __s, size_t __n, mbstate_t* _Nullable __ps);
+size_t mbsrtowcs(wchar_t* _Nullable __dst, const char* _Nullable * _Nonnull __src, size_t __dst_n, mbstate_t* _Nullable __ps);
+size_t mbsnrtowcs(wchar_t* _Nullable __dst, const char* _Nullable * _Nullable  __src, size_t __src_n, size_t __dst_n, mbstate_t* _Nullable __ps) __INTRODUCED_IN(21);
+wint_t putwc(wchar_t __wc, FILE* _Nonnull __fp);
 wint_t putwchar(wchar_t __wc);
-int swprintf(wchar_t* __buf, size_t __n, const wchar_t* __fmt, ...);
-int swscanf(const wchar_t* __s, const wchar_t* __fmt, ...);
-wint_t ungetwc(wint_t __wc, FILE* __fp);
-int vfwprintf(FILE* __fp, const wchar_t* __fmt, va_list __args);
-int vfwscanf(FILE* __fp, const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
-int vswprintf(wchar_t* __buf, size_t __n, const wchar_t* __fmt, va_list __args);
-int vswscanf(const wchar_t* __s, const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
-int vwprintf(const wchar_t* __fmt, va_list __args);
-int vwscanf(const wchar_t* __fmt, va_list __args) __INTRODUCED_IN(21);
-wchar_t* wcpcpy(wchar_t* __dst, const wchar_t* __src);
-wchar_t* wcpncpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-size_t wcrtomb(char* __buf, wchar_t __wc, mbstate_t* __ps);
-int wcscasecmp(const wchar_t* __lhs, const wchar_t* __rhs);
-int wcscasecmp_l(const wchar_t* __lhs, const wchar_t* __rhs, locale_t __l) __INTRODUCED_IN(23);
-wchar_t* wcscat(wchar_t* __dst, const wchar_t* __src);
-wchar_t* wcschr(const wchar_t* __s, wchar_t __wc);
-int wcscmp(const wchar_t* __lhs, const wchar_t* __rhs);
-int wcscoll(const wchar_t* __lhs, const wchar_t* __rhs);
-wchar_t* wcscpy(wchar_t* __dst, const wchar_t* __src);
-size_t wcscspn(const wchar_t* __s, const wchar_t* __accept);
-size_t wcsftime(wchar_t* __buf, size_t __n, const wchar_t* __fmt, const struct tm* __tm);
-size_t wcsftime_l(wchar_t* __buf, size_t __n, const wchar_t* __fmt, const struct tm* __tm, locale_t __l) __INTRODUCED_IN(28);
-size_t wcslen(const wchar_t* __s);
-int wcsncasecmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-int wcsncasecmp_l(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n, locale_t __l) __INTRODUCED_IN(23);
-wchar_t* wcsncat(wchar_t* __dst, const wchar_t* __src, size_t __n);
-int wcsncmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-wchar_t* wcsncpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-size_t wcsnrtombs(char* __dst, const wchar_t** __src, size_t __src_n, size_t __dst_n, mbstate_t* __ps) __INTRODUCED_IN(21);
-wchar_t* wcspbrk(const wchar_t* __s, const wchar_t* __accept);
-wchar_t* wcsrchr(const wchar_t* __s, wchar_t __wc);
-size_t wcsrtombs(char* __dst, const wchar_t** __src, size_t __dst_n, mbstate_t* __ps);
-size_t wcsspn(const wchar_t* __s, const wchar_t* __accept);
-wchar_t* wcsstr(const wchar_t* __haystack, const wchar_t* __needle);
-double wcstod(const wchar_t* __s, wchar_t** __end_ptr);
-double wcstod_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(28);
-float wcstof(const wchar_t* __s, wchar_t** __end_ptr) __INTRODUCED_IN(21);
-float wcstof_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(28);
-wchar_t* wcstok(wchar_t* __s, const wchar_t* __delimiter, wchar_t** __ptr);
-long wcstol(const wchar_t* __s, wchar_t** __end_ptr, int __base);
-long wcstol_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(28);
-long long wcstoll(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
-long double wcstold(const wchar_t* __s, wchar_t** __end_ptr) __RENAME_LDBL(wcstod, 3, 21);
-unsigned long wcstoul(const wchar_t* __s, wchar_t** __end_ptr, int __base);
-unsigned long wcstoul_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(28);
-unsigned long long wcstoull(const wchar_t* __s, wchar_t** __end_ptr, int __base) __INTRODUCED_IN(21);
-int wcswidth(const wchar_t* __s, size_t __n);
-size_t wcsxfrm(wchar_t* __dst, const wchar_t* __src, size_t __n);
+int swprintf(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nonnull __fmt, ...);
+int swscanf(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __fmt, ...);
+wint_t ungetwc(wint_t __wc, FILE* _Nonnull __fp);
+int vfwprintf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, va_list __args);
+int vfwscanf(FILE* _Nonnull __fp, const wchar_t* _Nonnull __fmt, va_list __args) __INTRODUCED_IN(21);
+int vswprintf(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nonnull __fmt, va_list __args);
+int vswscanf(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __fmt, va_list __args) __INTRODUCED_IN(21);
+int vwprintf(const wchar_t* _Nonnull __fmt, va_list __args);
+int vwscanf(const wchar_t* _Nonnull __fmt, va_list __args) __INTRODUCED_IN(21);
+wchar_t* _Nonnull wcpcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
+wchar_t* _Nonnull wcpncpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+size_t wcrtomb(char* _Nullable __buf, wchar_t __wc, mbstate_t* _Nullable __ps);
+int wcscasecmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+int wcscasecmp_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+wchar_t* _Nonnull wcscat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
+wchar_t* _Nullable wcschr(const wchar_t * _Nonnull __s, wchar_t __wc);
+int wcscmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+int wcscoll(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs);
+wchar_t* _Nonnull wcscpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src);
+size_t wcscspn(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
+size_t wcsftime(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nullable __fmt, const struct tm* _Nonnull __tm);
+size_t wcsftime_l(wchar_t* _Nonnull __buf, size_t __n, const wchar_t* _Nullable __fmt, const struct tm* _Nonnull __tm, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+size_t wcslen(const wchar_t* _Nonnull __s);
+int wcsncasecmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n);
+int wcsncasecmp_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n, locale_t _Nonnull __l) __INTRODUCED_IN(23);
+wchar_t* _Nonnull wcsncat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+int wcsncmp(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, size_t __n);
+wchar_t* _Nonnull wcsncpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+size_t wcsnrtombs(char* _Nullable __dst, const wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __src, size_t __src_n, size_t __dst_n, mbstate_t* _Nullable __ps) __INTRODUCED_IN(21);
+wchar_t* _Nullable wcspbrk(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
+wchar_t* _Nullable wcsrchr(const wchar_t* _Nonnull __s, wchar_t __wc);
+size_t wcsrtombs(char* _Nullable __dst, const wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __src, size_t __dst_n, mbstate_t* _Nullable __ps);
+size_t wcsspn(const wchar_t* _Nonnull __s, const wchar_t* _Nonnull __accept);
+wchar_t* _Nullable wcsstr(const wchar_t* _Nonnull __haystack, const wchar_t* _Nonnull __needle);
+double wcstod(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr);
+double wcstod_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+float wcstof(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __INTRODUCED_IN(21);
+float wcstof_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+wchar_t* _Nullable wcstok(wchar_t* _Nullable __s, const wchar_t* _Nonnull __delimiter, wchar_t* _Nonnull * _Nonnull __ptr);
+long wcstol(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
+long wcstol_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+long long wcstoll(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
+long double wcstold(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr) __RENAME_LDBL(wcstod, 3, 21);
+unsigned long wcstoul(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base);
+unsigned long wcstoul_l(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(28);
+unsigned long long wcstoull(const wchar_t* _Nonnull __s, wchar_t* __BIONIC_COMPLICATED_NULLNESS * _Nullable __end_ptr, int __base) __INTRODUCED_IN(21);
+int wcswidth(const wchar_t* _Nonnull __s, size_t __n);
+size_t wcsxfrm(wchar_t* __BIONIC_COMPLICATED_NULLNESS __dst, const wchar_t* _Nonnull __src, size_t __n);
 int wctob(wint_t __wc);
 int wcwidth(wchar_t __wc);
-wchar_t* wmemchr(const wchar_t* __src, wchar_t __wc, size_t __n);
-int wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n);
-wchar_t* wmemcpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
+wchar_t* _Nullable wmemchr(const wchar_t* _Nonnull __src, wchar_t __wc, size_t __n);
+int wmemcmp(const wchar_t* _Nullable __lhs, const wchar_t* _Nullable __rhs, size_t __n);
+wchar_t* _Nonnull wmemcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
 #if defined(__USE_GNU)
-wchar_t* wmempcpy(wchar_t* __dst, const wchar_t* __src, size_t __n) __INTRODUCED_IN(23);
+wchar_t* _Nonnull wmempcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n) __INTRODUCED_IN(23);
 #endif
-wchar_t* wmemmove(wchar_t* __dst, const wchar_t* __src, size_t __n);
-wchar_t* wmemset(wchar_t* __dst, wchar_t __wc, size_t __n);
-int wprintf(const wchar_t* __fmt, ...);
-int wscanf(const wchar_t* __fmt, ...);
+wchar_t* _Nonnull wmemmove(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+wchar_t* _Nonnull wmemset(wchar_t* _Nonnull __dst, wchar_t __wc, size_t __n);
+int wprintf(const wchar_t* _Nonnull __fmt, ...);
+int wscanf(const wchar_t* _Nonnull __fmt, ...);
 
-long long wcstoll_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
-unsigned long long wcstoull_l(const wchar_t* __s, wchar_t** __end_ptr, int __base, locale_t __l) __INTRODUCED_IN(21);
-long double wcstold_l(const wchar_t* __s, wchar_t** __end_ptr, locale_t __l) __INTRODUCED_IN(21);
+long long wcstoll_l(const wchar_t* _Nonnull __s, wchar_t* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+unsigned long long wcstoull_l(const wchar_t* _Nonnull __s, wchar_t* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+long double wcstold_l(const wchar_t* _Nonnull __s, wchar_t* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) __INTRODUCED_IN(21);
 
-int wcscoll_l(const wchar_t* __lhs, const wchar_t* __rhs, locale_t __l) __attribute_pure__
+int wcscoll_l(const wchar_t* _Nonnull __lhs, const wchar_t* _Nonnull __rhs, locale_t _Nonnull __l) __attribute_pure__
     __INTRODUCED_IN(21);
-size_t wcsxfrm_l(wchar_t* __dst, const wchar_t* __src, size_t __n, locale_t __l) __INTRODUCED_IN(21);
+size_t wcsxfrm_l(wchar_t* __BIONIC_COMPLICATED_NULLNESS __dst, const wchar_t* _Nonnull __src, size_t __n, locale_t _Nonnull __l) __INTRODUCED_IN(21);
+size_t wcslcat(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
+size_t wcslcpy(wchar_t* _Nonnull __dst, const wchar_t* _Nonnull __src, size_t __n);
 
-size_t wcslcat(wchar_t* __dst, const wchar_t* __src, size_t __n);
-size_t wcslcpy(wchar_t* __dst, const wchar_t* __src, size_t __n);
-
-FILE* open_wmemstream(wchar_t** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23);
-wchar_t* wcsdup(const wchar_t* __s);
-size_t wcsnlen(const wchar_t* __s, size_t __n);
+FILE* _Nullable open_wmemstream(wchar_t* _Nonnull * _Nonnull __ptr, size_t* _Nonnull  __size_ptr) __INTRODUCED_IN(23);
+wchar_t* _Nullable wcsdup(const wchar_t* _Nonnull __s);
+size_t wcsnlen(const wchar_t* _Nonnull __s, size_t __n);
 
 __END_DECLS
 
diff --git a/libc/kernel/android/scsi/scsi/sg.h b/libc/kernel/android/scsi/scsi/sg.h
index 6911b16..9ba6cd6 100644
--- a/libc/kernel/android/scsi/scsi/sg.h
+++ b/libc/kernel/android/scsi/scsi/sg.h
@@ -20,7 +20,7 @@
 #define _SCSI_GENERIC_H
 #include <linux/compiler.h>
 typedef struct sg_iovec {
-  void __user * iov_base;
+  void  * iov_base;
   size_t iov_len;
 } sg_iovec_t;
 typedef struct sg_io_hdr {
@@ -30,13 +30,13 @@
   unsigned char mx_sb_len;
   unsigned short iovec_count;
   unsigned int dxfer_len;
-  void __user * dxferp;
-  unsigned char __user * cmdp;
-  void __user * sbp;
+  void  * dxferp;
+  unsigned char  * cmdp;
+  void  * sbp;
   unsigned int timeout;
   unsigned int flags;
   int pack_id;
-  void __user * usr_ptr;
+  void  * usr_ptr;
   unsigned char status;
   unsigned char masked_status;
   unsigned char msg_status;
@@ -96,7 +96,7 @@
   char sg_io_owned;
   char problem;
   int pack_id;
-  void __user * usr_ptr;
+  void  * usr_ptr;
   unsigned int duration;
   int unused;
 } sg_req_info_t;
diff --git a/libc/kernel/android/uapi/linux/compiler.h b/libc/kernel/android/uapi/linux/compiler.h
index 8e89655..42d59aa 100644
--- a/libc/kernel/android/uapi/linux/compiler.h
+++ b/libc/kernel/android/uapi/linux/compiler.h
@@ -1,18 +1,11 @@
-#ifndef _UAPI_LINUX_COMPILER_H
-#define _UAPI_LINUX_COMPILER_H
+#pragma once
 
 /*
- * This file is not currently in the Linux kernel tree.
- * Upstream uapi headers refer to <linux/compiler.h> but there is
- * no such uapi file. We've sent this upstream, and are optimistically
- * adding it to bionic in the meantime. This should be replaced by
- * a scrubbed header from external/kernel-headers when possible.
+ * There is no `include/uapi/linux/compiler.h`, just `include/linux/compiler.h`.
  *
- * An alternative to this file is to check in a symbolic link to the
- * non-uapi <linux/compiler.h>. That's fine for building bionic too.
+ * We don't need anything _in_ this file, but we do need this file.
+ * The two #defines are for backwards compatibility.
  */
 
-#define __user
 #define __force
-
-#endif /* _UAPI_LINUX_COMPILER_H */
+#define __user
diff --git a/libc/kernel/android/uapi/linux/compiler_types.h b/libc/kernel/android/uapi/linux/compiler_types.h
index 94f4fbe..859ae05 100644
--- a/libc/kernel/android/uapi/linux/compiler_types.h
+++ b/libc/kernel/android/uapi/linux/compiler_types.h
@@ -1,5 +1,11 @@
+#pragma once
+
 /*
- * The compiler.h file has been split into compiler.h and compiler_types.h.
- * However, to compile bionic we only need the compiler.h.
+ * There is no `include/uapi/linux/compiler_types.h`, just
+ * `include/linux/compiler_types.h`.
+ *
+ * We don't need anything _in_ this file, but we do need this file.
+ * The #include is for backwards compatibility.
  */
+
 #include <linux/compiler.h>
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index d0fe157..91d26ce 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -1,9 +1,4 @@
-# this module contains all the defaults used by the generation of cleaned-up headers
-# for the Bionic C library
-#
-
-import time, os, sys
-from utils import *
+# All the defaults used to generate the cleaned-up uapi headers for bionic.
 
 # the list of include directories that belong to the kernel
 # tree. used when looking for sources...
@@ -48,6 +43,7 @@
     "in_addr": False,
     "ip_mreq_source": False,
     "ip_msfilter": False,
+    "timespec": False,
     }
 
 # define to true if you want to remove all defined(CONFIG_FOO) tests
@@ -97,6 +93,9 @@
     # Replace __packed with __attribute__((__packed__)) to avoid depending
     # on sys/cdefs.h
     "__packed": "__attribute__((__packed__))",
+    # Remove unused macros (http://b/262917450).
+    "__force": "",
+    "__user": "",
     }
 
 
diff --git a/libc/kernel/uapi/asm-arm/asm/signal.h b/libc/kernel/uapi/asm-arm/asm/signal.h
index 0424380..90cb8d6 100644
--- a/libc/kernel/uapi/asm-arm/asm/signal.h
+++ b/libc/kernel/uapi/asm-arm/asm/signal.h
@@ -76,7 +76,7 @@
 #define sa_handler _u._sa_handler
 #define sa_sigaction _u._sa_sigaction
 typedef struct sigaltstack {
-  void __user * ss_sp;
+  void  * ss_sp;
   int ss_flags;
   __kernel_size_t ss_size;
 } stack_t;
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index ecc2e01..ce0c318 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -121,7 +121,7 @@
 struct kvm_arm_copy_mte_tags {
   __u64 guest_ipa;
   __u64 length;
-  void __user * addr;
+  void  * addr;
   __u64 flags;
   __u64 reserved[2];
 };
diff --git a/libc/kernel/uapi/asm-generic/poll.h b/libc/kernel/uapi/asm-generic/poll.h
index 372bc77..ba6f2e9 100644
--- a/libc/kernel/uapi/asm-generic/poll.h
+++ b/libc/kernel/uapi/asm-generic/poll.h
@@ -41,8 +41,8 @@
 #ifndef POLLRDHUP
 #define POLLRDHUP 0x2000
 #endif
-#define POLLFREE (__force __poll_t) 0x4000
-#define POLL_BUSY_LOOP (__force __poll_t) 0x8000
+#define POLLFREE ( __poll_t) 0x4000
+#define POLL_BUSY_LOOP ( __poll_t) 0x8000
 struct pollfd {
   int fd;
   short events;
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index c5e4178..90393ba 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -22,7 +22,7 @@
 #include <linux/types.h>
 typedef union sigval {
   int sival_int;
-  void __user * sival_ptr;
+  void  * sival_ptr;
 } sigval_t;
 #define SI_MAX_SIZE 128
 #ifndef __ARCH_SI_BAND_T
@@ -58,7 +58,7 @@
     __ARCH_SI_CLOCK_T _stime;
   } _sigchld;
   struct {
-    void __user * _addr;
+    void  * _addr;
 #ifdef __ia64__
     int _imm;
     unsigned int _flags;
@@ -70,8 +70,8 @@
       short _addr_lsb;
       struct {
         char _dummy_bnd[__ADDR_BND_PKEY_PAD];
-        void __user * _lower;
-        void __user * _upper;
+        void  * _lower;
+        void  * _upper;
       } _addr_bnd;
       struct {
         char _dummy_pkey[__ADDR_BND_PKEY_PAD];
@@ -89,7 +89,7 @@
     int _fd;
   } _sigpoll;
   struct {
-    void __user * _call_addr;
+    void  * _call_addr;
     int _syscall;
     unsigned int _arch;
   } _sigsys;
diff --git a/libc/kernel/uapi/asm-generic/signal-defs.h b/libc/kernel/uapi/asm-generic/signal-defs.h
index c7e9504..dea8fbc 100644
--- a/libc/kernel/uapi/asm-generic/signal-defs.h
+++ b/libc/kernel/uapi/asm-generic/signal-defs.h
@@ -55,11 +55,11 @@
 #endif
 #ifndef __ASSEMBLY__
 typedef void __signalfn_t(int);
-typedef __signalfn_t __user * __sighandler_t;
+typedef __signalfn_t  * __sighandler_t;
 typedef void __restorefn_t(void);
-typedef __restorefn_t __user * __sigrestore_t;
-#define SIG_DFL ((__force __sighandler_t) 0)
-#define SIG_IGN ((__force __sighandler_t) 1)
-#define SIG_ERR ((__force __sighandler_t) - 1)
+typedef __restorefn_t  * __sigrestore_t;
+#define SIG_DFL (( __sighandler_t) 0)
+#define SIG_IGN (( __sighandler_t) 1)
+#define SIG_ERR (( __sighandler_t) - 1)
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-generic/signal.h b/libc/kernel/uapi/asm-generic/signal.h
index 5cb1dce..9cf393f 100644
--- a/libc/kernel/uapi/asm-generic/signal.h
+++ b/libc/kernel/uapi/asm-generic/signal.h
@@ -82,7 +82,7 @@
   sigset_t sa_mask;
 };
 typedef struct sigaltstack {
-  void __user * ss_sp;
+  void  * ss_sp;
   int ss_flags;
   __kernel_size_t ss_size;
 } stack_t;
diff --git a/libc/kernel/uapi/asm-x86/asm/sigcontext.h b/libc/kernel/uapi/asm-x86/asm/sigcontext.h
index 7d5b4d4..c790950 100644
--- a/libc/kernel/uapi/asm-x86/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-x86/asm/sigcontext.h
@@ -180,7 +180,7 @@
   __u32 eflags;
   __u32 esp_at_signal;
   __u16 ss, __ssh;
-  struct _fpstate __user * fpstate;
+  struct _fpstate  * fpstate;
   __u32 oldmask;
   __u32 cr2;
 };
@@ -215,7 +215,7 @@
   __u64 trapno;
   __u64 oldmask;
   __u64 cr2;
-  struct _fpstate __user * fpstate;
+  struct _fpstate  * fpstate;
 #ifdef __ILP32__
   __u32 __fpstate_pad;
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/signal.h b/libc/kernel/uapi/asm-x86/asm/signal.h
index cbeeac4..37dce50 100644
--- a/libc/kernel/uapi/asm-x86/asm/signal.h
+++ b/libc/kernel/uapi/asm-x86/asm/signal.h
@@ -88,7 +88,7 @@
 };
 #endif
 typedef struct sigaltstack {
-  void __user * ss_sp;
+  void  * ss_sp;
   int ss_flags;
   __kernel_size_t ss_size;
 } stack_t;
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 878e899..1954452 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -78,19 +78,19 @@
   int version_minor;
   int version_patchlevel;
   __kernel_size_t name_len;
-  char __user * name;
+  char  * name;
   __kernel_size_t date_len;
-  char __user * date;
+  char  * date;
   __kernel_size_t desc_len;
-  char __user * desc;
+  char  * desc;
 };
 struct drm_unique {
   __kernel_size_t unique_len;
-  char __user * unique;
+  char  * unique;
 };
 struct drm_list {
   int count;
-  struct drm_version __user * version;
+  struct drm_version  * version;
 };
 struct drm_block {
   int unused;
@@ -202,37 +202,37 @@
 };
 struct drm_buf_info {
   int count;
-  struct drm_buf_desc __user * list;
+  struct drm_buf_desc  * list;
 };
 struct drm_buf_free {
   int count;
-  int __user * list;
+  int  * list;
 };
 struct drm_buf_pub {
   int idx;
   int total;
   int used;
-  void __user * address;
+  void  * address;
 };
 struct drm_buf_map {
   int count;
 #ifdef __cplusplus
-  void __user * virt;
+  void  * virt;
 #else
-  void __user * __linux_virtual;
+  void  * __linux_virtual;
 #endif
-  struct drm_buf_pub __user * list;
+  struct drm_buf_pub  * list;
 };
 struct drm_dma {
   int context;
   int send_count;
-  int __user * send_indices;
-  int __user * send_sizes;
+  int  * send_indices;
+  int  * send_sizes;
   enum drm_dma_flags flags;
   int request_count;
   int request_size;
-  int __user * request_indices;
-  int __user * request_sizes;
+  int  * request_indices;
+  int  * request_sizes;
   int granted_count;
 };
 enum drm_ctx_flags {
@@ -245,7 +245,7 @@
 };
 struct drm_ctx_res {
   int count;
-  struct drm_ctx __user * contexts;
+  struct drm_ctx  * contexts;
 };
 struct drm_draw {
   drm_drawable_t handle;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index a8982bf..794e784 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -287,18 +287,18 @@
   int DR1;
   int DR4;
   int num_cliprects;
-  struct drm_clip_rect __user * cliprects;
+  struct drm_clip_rect  * cliprects;
 } drm_i915_batchbuffer_t;
 typedef struct _drm_i915_cmdbuffer {
-  char __user * buf;
+  char  * buf;
   int sz;
   int DR1;
   int DR4;
   int num_cliprects;
-  struct drm_clip_rect __user * cliprects;
+  struct drm_clip_rect  * cliprects;
 } drm_i915_cmdbuffer_t;
 typedef struct drm_i915_irq_emit {
-  int __user * irq_seq;
+  int  * irq_seq;
 } drm_i915_irq_emit_t;
 typedef struct drm_i915_irq_wait {
   int irq_seq;
@@ -371,7 +371,7 @@
 #define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57
 struct drm_i915_getparam {
   __s32 param;
-  int __user * value;
+  int  * value;
 };
 typedef struct drm_i915_getparam drm_i915_getparam_t;
 #define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
@@ -387,7 +387,7 @@
   int region;
   int alignment;
   int size;
-  int __user * region_offset;
+  int  * region_offset;
 } drm_i915_mem_alloc_t;
 typedef struct drm_i915_mem_free {
   int region;
diff --git a/libc/kernel/uapi/drm/mga_drm.h b/libc/kernel/uapi/drm/mga_drm.h
index dc62961..eb55fa7 100644
--- a/libc/kernel/uapi/drm/mga_drm.h
+++ b/libc/kernel/uapi/drm/mga_drm.h
@@ -239,7 +239,7 @@
 #define MGA_PARAM_CARD_TYPE 2
 typedef struct drm_mga_getparam {
   int param;
-  void __user * value;
+  void  * value;
 } drm_mga_getparam_t;
 #ifdef __cplusplus
 }
diff --git a/libc/kernel/uapi/drm/r128_drm.h b/libc/kernel/uapi/drm/r128_drm.h
index 618b6dc..3e013b1 100644
--- a/libc/kernel/uapi/drm/r128_drm.h
+++ b/libc/kernel/uapi/drm/r128_drm.h
@@ -204,13 +204,13 @@
     R128_READ_PIXELS = 0x04
   } func;
   int n;
-  int __user * x;
-  int __user * y;
-  unsigned int __user * buffer;
-  unsigned char __user * mask;
+  int  * x;
+  int  * y;
+  unsigned int  * buffer;
+  unsigned char  * mask;
 } drm_r128_depth_t;
 typedef struct drm_r128_stipple {
-  unsigned int __user * mask;
+  unsigned int  * mask;
 } drm_r128_stipple_t;
 typedef struct drm_r128_indirect {
   int idx;
@@ -227,7 +227,7 @@
 #define R128_PARAM_IRQ_NR 1
 typedef struct drm_r128_getparam {
   int param;
-  void __user * value;
+  void  * value;
 } drm_r128_getparam_t;
 #ifdef __cplusplus
 }
diff --git a/libc/kernel/uapi/drm/radeon_drm.h b/libc/kernel/uapi/drm/radeon_drm.h
index 9dc69ad..3ec6bb3 100644
--- a/libc/kernel/uapi/drm/radeon_drm.h
+++ b/libc/kernel/uapi/drm/radeon_drm.h
@@ -479,7 +479,7 @@
   unsigned int clear_depth;
   unsigned int color_mask;
   unsigned int depth_mask;
-  drm_radeon_clear_rect_t __user * depth_boxes;
+  drm_radeon_clear_rect_t  * depth_boxes;
 } drm_radeon_clear_t;
 typedef struct drm_radeon_vertex {
   int prim;
@@ -498,20 +498,20 @@
   int idx;
   int discard;
   int nr_states;
-  drm_radeon_state_t __user * state;
+  drm_radeon_state_t  * state;
   int nr_prims;
-  drm_radeon_prim_t __user * prim;
+  drm_radeon_prim_t  * prim;
 } drm_radeon_vertex2_t;
 typedef struct drm_radeon_cmd_buffer {
   int bufsz;
-  char __user * buf;
+  char  * buf;
   int nbox;
-  struct drm_clip_rect __user * boxes;
+  struct drm_clip_rect  * boxes;
 } drm_radeon_cmd_buffer_t;
 typedef struct drm_radeon_tex_image {
   unsigned int x, y;
   unsigned int width, height;
-  const void __user * data;
+  const void  * data;
 } drm_radeon_tex_image_t;
 typedef struct drm_radeon_texture {
   unsigned int offset;
@@ -519,10 +519,10 @@
   int format;
   int width;
   int height;
-  drm_radeon_tex_image_t __user * image;
+  drm_radeon_tex_image_t  * image;
 } drm_radeon_texture_t;
 typedef struct drm_radeon_stipple {
-  unsigned int __user * mask;
+  unsigned int  * mask;
 } drm_radeon_stipple_t;
 typedef struct drm_radeon_indirect {
   int idx;
@@ -552,7 +552,7 @@
 #define RADEON_PARAM_NUM_Z_PIPES 17
 typedef struct drm_radeon_getparam {
   int param;
-  void __user * value;
+  void  * value;
 } drm_radeon_getparam_t;
 #define RADEON_MEM_REGION_GART 1
 #define RADEON_MEM_REGION_FB 2
@@ -560,7 +560,7 @@
   int region;
   int alignment;
   int size;
-  int __user * region_offset;
+  int  * region_offset;
 } drm_radeon_mem_alloc_t;
 typedef struct drm_radeon_mem_free {
   int region;
@@ -572,7 +572,7 @@
   int start;
 } drm_radeon_mem_init_heap_t;
 typedef struct drm_radeon_irq_emit {
-  int __user * irq_seq;
+  int  * irq_seq;
 } drm_radeon_irq_emit_t;
 typedef struct drm_radeon_irq_wait {
   int irq_seq;
diff --git a/libc/kernel/uapi/drm/savage_drm.h b/libc/kernel/uapi/drm/savage_drm.h
index ae87d21..efc0ae6 100644
--- a/libc/kernel/uapi/drm/savage_drm.h
+++ b/libc/kernel/uapi/drm/savage_drm.h
@@ -68,14 +68,14 @@
 } drm_savage_init_t;
 typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
 typedef struct drm_savage_cmdbuf {
-  drm_savage_cmd_header_t __user * cmd_addr;
+  drm_savage_cmd_header_t  * cmd_addr;
   unsigned int size;
   unsigned int dma_idx;
   int discard;
-  unsigned int __user * vb_addr;
+  unsigned int  * vb_addr;
   unsigned int vb_size;
   unsigned int vb_stride;
-  struct drm_clip_rect __user * box_addr;
+  struct drm_clip_rect  * box_addr;
   unsigned int nbox;
 } drm_savage_cmdbuf_t;
 #define SAVAGE_WAIT_2D 0x1
diff --git a/libc/kernel/uapi/drm/via_drm.h b/libc/kernel/uapi/drm/via_drm.h
index 9ef645a..95a149b 100644
--- a/libc/kernel/uapi/drm/via_drm.h
+++ b/libc/kernel/uapi/drm/via_drm.h
@@ -125,7 +125,7 @@
   unsigned long reg_pause_addr;
 } drm_via_dma_init_t;
 typedef struct _drm_via_cmdbuffer {
-  char __user * buf;
+  char  * buf;
   unsigned long size;
 } drm_via_cmdbuffer_t;
 typedef struct _drm_via_tex_region {
diff --git a/libc/kernel/uapi/linux/atm.h b/libc/kernel/uapi/linux/atm.h
index 488fa05..72d329d 100644
--- a/libc/kernel/uapi/linux/atm.h
+++ b/libc/kernel/uapi/linux/atm.h
@@ -140,7 +140,7 @@
 struct atmif_sioc {
   int number;
   int length;
-  void __user * arg;
+  void  * arg;
 };
 typedef unsigned short atm_backend_t;
 #endif
diff --git a/libc/kernel/uapi/linux/atmdev.h b/libc/kernel/uapi/linux/atmdev.h
index 69eb240..74cdfc1 100644
--- a/libc/kernel/uapi/linux/atmdev.h
+++ b/libc/kernel/uapi/linux/atmdev.h
@@ -86,7 +86,7 @@
 #define ATM_LM_RMT_ANALOG __ATM_LM_MKRMT(__ATM_LM_ANALOG)
 struct atm_iobuf {
   int length;
-  void __user * buffer;
+  void  * buffer;
 };
 #define ATM_CI_MAX - 1
 struct atm_cirange {
diff --git a/libc/kernel/uapi/linux/blkpg.h b/libc/kernel/uapi/linux/blkpg.h
index fdde696..bfe504f 100644
--- a/libc/kernel/uapi/linux/blkpg.h
+++ b/libc/kernel/uapi/linux/blkpg.h
@@ -25,7 +25,7 @@
   int op;
   int flags;
   int datalen;
-  void __user * data;
+  void  * data;
 };
 #define BLKPG_ADD_PARTITION 1
 #define BLKPG_DEL_PARTITION 2
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 8039625..0fdac66 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -79,7 +79,7 @@
   union {
     struct {
       __u64 size;
-      struct btrfs_qgroup_inherit __user * qgroup_inherit;
+      struct btrfs_qgroup_inherit  * qgroup_inherit;
     };
     __u64 unused[4];
   };
@@ -432,7 +432,7 @@
 struct btrfs_ioctl_send_args {
   __s64 send_fd;
   __u64 clone_sources_count;
-  __u64 __user * clone_sources;
+  __u64  * clone_sources;
   __u64 parent_root;
   __u64 flags;
   __u32 version;
@@ -469,7 +469,7 @@
   __u8 align[7];
 };
 struct btrfs_ioctl_encoded_io_args {
-  const struct iovec __user * iov;
+  const struct iovec  * iov;
   unsigned long iovcnt;
   __s64 offset;
   __u64 flags;
diff --git a/libc/kernel/uapi/linux/byteorder/big_endian.h b/libc/kernel/uapi/linux/byteorder/big_endian.h
index b6c978b..82c5a4c 100644
--- a/libc/kernel/uapi/linux/byteorder/big_endian.h
+++ b/libc/kernel/uapi/linux/byteorder/big_endian.h
@@ -27,34 +27,34 @@
 #include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/swab.h>
-#define __constant_htonl(x) ((__force __be32) (__u32) (x))
-#define __constant_ntohl(x) ((__force __u32) (__be32) (x))
-#define __constant_htons(x) ((__force __be16) (__u16) (x))
-#define __constant_ntohs(x) ((__force __u16) (__be16) (x))
-#define __constant_cpu_to_le64(x) ((__force __le64) ___constant_swab64((x)))
-#define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64) (__le64) (x))
-#define __constant_cpu_to_le32(x) ((__force __le32) ___constant_swab32((x)))
-#define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32) (__le32) (x))
-#define __constant_cpu_to_le16(x) ((__force __le16) ___constant_swab16((x)))
-#define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16) (__le16) (x))
-#define __constant_cpu_to_be64(x) ((__force __be64) (__u64) (x))
-#define __constant_be64_to_cpu(x) ((__force __u64) (__be64) (x))
-#define __constant_cpu_to_be32(x) ((__force __be32) (__u32) (x))
-#define __constant_be32_to_cpu(x) ((__force __u32) (__be32) (x))
-#define __constant_cpu_to_be16(x) ((__force __be16) (__u16) (x))
-#define __constant_be16_to_cpu(x) ((__force __u16) (__be16) (x))
-#define __cpu_to_le64(x) ((__force __le64) __swab64((x)))
-#define __le64_to_cpu(x) __swab64((__force __u64) (__le64) (x))
-#define __cpu_to_le32(x) ((__force __le32) __swab32((x)))
-#define __le32_to_cpu(x) __swab32((__force __u32) (__le32) (x))
-#define __cpu_to_le16(x) ((__force __le16) __swab16((x)))
-#define __le16_to_cpu(x) __swab16((__force __u16) (__le16) (x))
-#define __cpu_to_be64(x) ((__force __be64) (__u64) (x))
-#define __be64_to_cpu(x) ((__force __u64) (__be64) (x))
-#define __cpu_to_be32(x) ((__force __be32) (__u32) (x))
-#define __be32_to_cpu(x) ((__force __u32) (__be32) (x))
-#define __cpu_to_be16(x) ((__force __be16) (__u16) (x))
-#define __be16_to_cpu(x) ((__force __u16) (__be16) (x))
+#define __constant_htonl(x) (( __be32) (__u32) (x))
+#define __constant_ntohl(x) (( __u32) (__be32) (x))
+#define __constant_htons(x) (( __be16) (__u16) (x))
+#define __constant_ntohs(x) (( __u16) (__be16) (x))
+#define __constant_cpu_to_le64(x) (( __le64) ___constant_swab64((x)))
+#define __constant_le64_to_cpu(x) ___constant_swab64(( __u64) (__le64) (x))
+#define __constant_cpu_to_le32(x) (( __le32) ___constant_swab32((x)))
+#define __constant_le32_to_cpu(x) ___constant_swab32(( __u32) (__le32) (x))
+#define __constant_cpu_to_le16(x) (( __le16) ___constant_swab16((x)))
+#define __constant_le16_to_cpu(x) ___constant_swab16(( __u16) (__le16) (x))
+#define __constant_cpu_to_be64(x) (( __be64) (__u64) (x))
+#define __constant_be64_to_cpu(x) (( __u64) (__be64) (x))
+#define __constant_cpu_to_be32(x) (( __be32) (__u32) (x))
+#define __constant_be32_to_cpu(x) (( __u32) (__be32) (x))
+#define __constant_cpu_to_be16(x) (( __be16) (__u16) (x))
+#define __constant_be16_to_cpu(x) (( __u16) (__be16) (x))
+#define __cpu_to_le64(x) (( __le64) __swab64((x)))
+#define __le64_to_cpu(x) __swab64(( __u64) (__le64) (x))
+#define __cpu_to_le32(x) (( __le32) __swab32((x)))
+#define __le32_to_cpu(x) __swab32(( __u32) (__le32) (x))
+#define __cpu_to_le16(x) (( __le16) __swab16((x)))
+#define __le16_to_cpu(x) __swab16(( __u16) (__le16) (x))
+#define __cpu_to_be64(x) (( __be64) (__u64) (x))
+#define __be64_to_cpu(x) (( __u64) (__be64) (x))
+#define __cpu_to_be32(x) (( __be32) (__u32) (x))
+#define __be32_to_cpu(x) (( __u32) (__be32) (x))
+#define __cpu_to_be16(x) (( __be16) (__u16) (x))
+#define __be16_to_cpu(x) (( __u16) (__be16) (x))
 #define __cpu_to_le64s(x) __swab64s((x))
 #define __le64_to_cpus(x) __swab64s((x))
 #define __cpu_to_le32s(x) __swab32s((x))
diff --git a/libc/kernel/uapi/linux/byteorder/little_endian.h b/libc/kernel/uapi/linux/byteorder/little_endian.h
index a272d4d..28155b5 100644
--- a/libc/kernel/uapi/linux/byteorder/little_endian.h
+++ b/libc/kernel/uapi/linux/byteorder/little_endian.h
@@ -27,34 +27,34 @@
 #include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/swab.h>
-#define __constant_htonl(x) ((__force __be32) ___constant_swab32((x)))
-#define __constant_ntohl(x) ___constant_swab32((__force __be32) (x))
-#define __constant_htons(x) ((__force __be16) ___constant_swab16((x)))
-#define __constant_ntohs(x) ___constant_swab16((__force __be16) (x))
-#define __constant_cpu_to_le64(x) ((__force __le64) (__u64) (x))
-#define __constant_le64_to_cpu(x) ((__force __u64) (__le64) (x))
-#define __constant_cpu_to_le32(x) ((__force __le32) (__u32) (x))
-#define __constant_le32_to_cpu(x) ((__force __u32) (__le32) (x))
-#define __constant_cpu_to_le16(x) ((__force __le16) (__u16) (x))
-#define __constant_le16_to_cpu(x) ((__force __u16) (__le16) (x))
-#define __constant_cpu_to_be64(x) ((__force __be64) ___constant_swab64((x)))
-#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64) (__be64) (x))
-#define __constant_cpu_to_be32(x) ((__force __be32) ___constant_swab32((x)))
-#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32) (__be32) (x))
-#define __constant_cpu_to_be16(x) ((__force __be16) ___constant_swab16((x)))
-#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16) (__be16) (x))
-#define __cpu_to_le64(x) ((__force __le64) (__u64) (x))
-#define __le64_to_cpu(x) ((__force __u64) (__le64) (x))
-#define __cpu_to_le32(x) ((__force __le32) (__u32) (x))
-#define __le32_to_cpu(x) ((__force __u32) (__le32) (x))
-#define __cpu_to_le16(x) ((__force __le16) (__u16) (x))
-#define __le16_to_cpu(x) ((__force __u16) (__le16) (x))
-#define __cpu_to_be64(x) ((__force __be64) __swab64((x)))
-#define __be64_to_cpu(x) __swab64((__force __u64) (__be64) (x))
-#define __cpu_to_be32(x) ((__force __be32) __swab32((x)))
-#define __be32_to_cpu(x) __swab32((__force __u32) (__be32) (x))
-#define __cpu_to_be16(x) ((__force __be16) __swab16((x)))
-#define __be16_to_cpu(x) __swab16((__force __u16) (__be16) (x))
+#define __constant_htonl(x) (( __be32) ___constant_swab32((x)))
+#define __constant_ntohl(x) ___constant_swab32(( __be32) (x))
+#define __constant_htons(x) (( __be16) ___constant_swab16((x)))
+#define __constant_ntohs(x) ___constant_swab16(( __be16) (x))
+#define __constant_cpu_to_le64(x) (( __le64) (__u64) (x))
+#define __constant_le64_to_cpu(x) (( __u64) (__le64) (x))
+#define __constant_cpu_to_le32(x) (( __le32) (__u32) (x))
+#define __constant_le32_to_cpu(x) (( __u32) (__le32) (x))
+#define __constant_cpu_to_le16(x) (( __le16) (__u16) (x))
+#define __constant_le16_to_cpu(x) (( __u16) (__le16) (x))
+#define __constant_cpu_to_be64(x) (( __be64) ___constant_swab64((x)))
+#define __constant_be64_to_cpu(x) ___constant_swab64(( __u64) (__be64) (x))
+#define __constant_cpu_to_be32(x) (( __be32) ___constant_swab32((x)))
+#define __constant_be32_to_cpu(x) ___constant_swab32(( __u32) (__be32) (x))
+#define __constant_cpu_to_be16(x) (( __be16) ___constant_swab16((x)))
+#define __constant_be16_to_cpu(x) ___constant_swab16(( __u16) (__be16) (x))
+#define __cpu_to_le64(x) (( __le64) (__u64) (x))
+#define __le64_to_cpu(x) (( __u64) (__le64) (x))
+#define __cpu_to_le32(x) (( __le32) (__u32) (x))
+#define __le32_to_cpu(x) (( __u32) (__le32) (x))
+#define __cpu_to_le16(x) (( __le16) (__u16) (x))
+#define __le16_to_cpu(x) (( __u16) (__le16) (x))
+#define __cpu_to_be64(x) (( __be64) __swab64((x)))
+#define __be64_to_cpu(x) __swab64(( __u64) (__be64) (x))
+#define __cpu_to_be32(x) (( __be32) __swab32((x)))
+#define __be32_to_cpu(x) __swab32(( __u32) (__be32) (x))
+#define __cpu_to_be16(x) (( __be16) __swab16((x)))
+#define __be16_to_cpu(x) __swab16(( __u16) (__be16) (x))
 #define __cpu_to_le64s(x) do { (void) (x); } while(0)
 #define __le64_to_cpus(x) do { (void) (x); } while(0)
 #define __cpu_to_le32s(x) do { (void) (x); } while(0)
diff --git a/libc/kernel/uapi/linux/capability.h b/libc/kernel/uapi/linux/capability.h
index c1b5dbf..8f3281e 100644
--- a/libc/kernel/uapi/linux/capability.h
+++ b/libc/kernel/uapi/linux/capability.h
@@ -28,12 +28,12 @@
 typedef struct __user_cap_header_struct {
   __u32 version;
   int pid;
-} __user * cap_user_header_t;
+}  * cap_user_header_t;
 typedef struct __user_cap_data_struct {
   __u32 effective;
   __u32 permitted;
   __u32 inheritable;
-} __user * cap_user_data_t;
+}  * cap_user_data_t;
 #define VFS_CAP_REVISION_MASK 0xFF000000
 #define VFS_CAP_REVISION_SHIFT 24
 #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
diff --git a/libc/kernel/uapi/linux/capi.h b/libc/kernel/uapi/linux/capi.h
index de2a839..a09f9bc 100644
--- a/libc/kernel/uapi/linux/capi.h
+++ b/libc/kernel/uapi/linux/capi.h
@@ -51,7 +51,7 @@
 #define CAPI_GET_PROFILE _IOWR('C', 0x09, struct capi_profile)
 typedef struct capi_manufacturer_cmd {
   unsigned long cmd;
-  void __user * data;
+  void  * data;
 } capi_manufacturer_cmd;
 #define CAPI_MANUFACTURER_CMD _IOWR('C', 0x20, struct capi_manufacturer_cmd)
 #define CAPI_GET_ERRCODE _IOR('C', 0x21, __u16)
diff --git a/libc/kernel/uapi/linux/cciss_ioctl.h b/libc/kernel/uapi/linux/cciss_ioctl.h
index 3e9bb3b..827e6a0 100644
--- a/libc/kernel/uapi/linux/cciss_ioctl.h
+++ b/libc/kernel/uapi/linux/cciss_ioctl.h
@@ -47,7 +47,7 @@
   RequestBlock_struct Request;
   ErrorInfo_struct error_info;
   WORD buf_size;
-  BYTE __user * buf;
+  BYTE  * buf;
 } IOCTL_Command_struct;
 typedef struct _BIG_IOCTL_Command_struct {
   LUNAddr_struct LUN_info;
@@ -55,7 +55,7 @@
   ErrorInfo_struct error_info;
   DWORD malloc_size;
   DWORD buf_size;
-  BYTE __user * buf;
+  BYTE  * buf;
 } BIG_IOCTL_Command_struct;
 typedef struct _LogvolInfo_struct {
   __u32 LunID;
diff --git a/libc/kernel/uapi/linux/cdrom.h b/libc/kernel/uapi/linux/cdrom.h
index 0fe0727..bd1d7df 100644
--- a/libc/kernel/uapi/linux/cdrom.h
+++ b/libc/kernel/uapi/linux/cdrom.h
@@ -128,7 +128,7 @@
   union cdrom_addr addr;
   __u8 addr_format;
   int nframes;
-  __u8 __user * buf;
+  __u8  * buf;
 };
 struct cdrom_multisession {
   union cdrom_addr addr;
@@ -149,16 +149,16 @@
 #define CGC_DATA_NONE 3
 struct cdrom_generic_command {
   unsigned char cmd[CDROM_PACKET_SIZE];
-  unsigned char __user * buffer;
+  unsigned char  * buffer;
   unsigned int buflen;
   int stat;
-  struct request_sense __user * sense;
+  struct request_sense  * sense;
   unsigned char data_direction;
   int quiet;
   int timeout;
   union {
-    void __user * reserved[1];
-    void __user * unused;
+    void  * reserved[1];
+    void  * unused;
   };
 };
 struct cdrom_timed_media_change_info {
diff --git a/libc/kernel/uapi/linux/chio.h b/libc/kernel/uapi/linux/chio.h
index 725e760..74f286f 100644
--- a/libc/kernel/uapi/linux/chio.h
+++ b/libc/kernel/uapi/linux/chio.h
@@ -71,7 +71,7 @@
 #define CP_INVERT 1
 struct changer_element_status {
   int ces_type;
-  unsigned char __user * ces_data;
+  unsigned char  * ces_data;
 };
 #define CESTATUS_FULL 0x01
 #define CESTATUS_IMPEXP 0x02
diff --git a/libc/kernel/uapi/linux/coda.h b/libc/kernel/uapi/linux/coda.h
index aad1b97..5795cdf 100644
--- a/libc/kernel/uapi/linux/coda.h
+++ b/libc/kernel/uapi/linux/coda.h
@@ -505,13 +505,13 @@
 };
 #define PIOCPARM_MASK 0x0000ffff
 struct ViceIoctl {
-  void __user * in;
-  void __user * out;
+  void  * in;
+  void  * out;
   u_short in_size;
   u_short out_size;
 };
 struct PioctlData {
-  const char __user * path;
+  const char  * path;
   int follow;
   struct ViceIoctl vi;
 };
diff --git a/libc/kernel/uapi/linux/comedi.h b/libc/kernel/uapi/linux/comedi.h
index e0d015a..465d1bf 100644
--- a/libc/kernel/uapi/linux/comedi.h
+++ b/libc/kernel/uapi/linux/comedi.h
@@ -244,14 +244,14 @@
 struct comedi_insn {
   unsigned int insn;
   unsigned int n;
-  unsigned int __user * data;
+  unsigned int  * data;
   unsigned int subdev;
   unsigned int chanspec;
   unsigned int unused[3];
 };
 struct comedi_insnlist {
   unsigned int n_insns;
-  struct comedi_insn __user * insns;
+  struct comedi_insn  * insns;
 };
 struct comedi_cmd {
   unsigned int subdev;
@@ -268,19 +268,19 @@
   unsigned int stop_arg;
   unsigned int * chanlist;
   unsigned int chanlist_len;
-  short __user * data;
+  short  * data;
   unsigned int data_len;
 };
 struct comedi_chaninfo {
   unsigned int subdev;
-  unsigned int __user * maxdata_list;
-  unsigned int __user * flaglist;
-  unsigned int __user * rangelist;
+  unsigned int  * maxdata_list;
+  unsigned int  * flaglist;
+  unsigned int  * rangelist;
   unsigned int unused[4];
 };
 struct comedi_rangeinfo {
   unsigned int range_type;
-  void __user * range_ptr;
+  void  * range_ptr;
 };
 struct comedi_krange {
   int min;
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 578cefd..c94af87 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -44,7 +44,7 @@
 struct cxl_mem_query_commands {
   __u32 n_commands;
   __u32 rsvd;
-  struct cxl_command_info __user commands[];
+  struct cxl_command_info  commands[];
 };
 struct cxl_send_command {
   __u32 id;
diff --git a/libc/kernel/uapi/linux/dlm_device.h b/libc/kernel/uapi/linux/dlm_device.h
index 5e54d2e..e1b0c6d 100644
--- a/libc/kernel/uapi/linux/dlm_device.h
+++ b/libc/kernel/uapi/linux/dlm_device.h
@@ -33,11 +33,11 @@
   __u32 parent;
   __u64 xid;
   __u64 timeout;
-  void __user * castparam;
-  void __user * castaddr;
-  void __user * bastparam;
-  void __user * bastaddr;
-  struct dlm_lksb __user * lksb;
+  void  * castparam;
+  void  * castaddr;
+  void  * bastparam;
+  void  * bastaddr;
+  struct dlm_lksb  * lksb;
   char lvb[DLM_USER_LVB_LEN];
   char name[];
 };
@@ -67,9 +67,9 @@
 struct dlm_lock_result {
   __u32 version[3];
   __u32 length;
-  void __user * user_astaddr;
-  void __user * user_astparam;
-  struct dlm_lksb __user * user_lksb;
+  void  * user_astaddr;
+  void  * user_astparam;
+  struct dlm_lksb  * user_lksb;
   struct dlm_lksb lksb;
   __u8 bast_mode;
   __u8 unused[3];
diff --git a/libc/kernel/uapi/linux/dvb/osd.h b/libc/kernel/uapi/linux/dvb/osd.h
index 84b268b..379294e 100644
--- a/libc/kernel/uapi/linux/dvb/osd.h
+++ b/libc/kernel/uapi/linux/dvb/osd.h
@@ -50,7 +50,7 @@
   int x1;
   int y1;
   int color;
-  void __user * data;
+  void  * data;
 } osd_cmd_t;
 typedef enum {
   OSD_BITMAP1,
diff --git a/libc/kernel/uapi/linux/dvb/video.h b/libc/kernel/uapi/linux/dvb/video.h
index 6577e1f..2458766 100644
--- a/libc/kernel/uapi/linux/dvb/video.h
+++ b/libc/kernel/uapi/linux/dvb/video.h
@@ -94,7 +94,7 @@
   video_displayformat_t display_format;
 };
 struct video_still_picture {
-  char __user * iFrame;
+  char  * iFrame;
   __s32 size;
 };
 typedef __u16 video_attributes_t;
diff --git a/libc/kernel/uapi/linux/eventpoll.h b/libc/kernel/uapi/linux/eventpoll.h
index 2a1a26a..de4c1f1 100644
--- a/libc/kernel/uapi/linux/eventpoll.h
+++ b/libc/kernel/uapi/linux/eventpoll.h
@@ -25,23 +25,23 @@
 #define EPOLL_CTL_ADD 1
 #define EPOLL_CTL_DEL 2
 #define EPOLL_CTL_MOD 3
-#define EPOLLIN (__force __poll_t) 0x00000001
-#define EPOLLPRI (__force __poll_t) 0x00000002
-#define EPOLLOUT (__force __poll_t) 0x00000004
-#define EPOLLERR (__force __poll_t) 0x00000008
-#define EPOLLHUP (__force __poll_t) 0x00000010
-#define EPOLLNVAL (__force __poll_t) 0x00000020
-#define EPOLLRDNORM (__force __poll_t) 0x00000040
-#define EPOLLRDBAND (__force __poll_t) 0x00000080
-#define EPOLLWRNORM (__force __poll_t) 0x00000100
-#define EPOLLWRBAND (__force __poll_t) 0x00000200
-#define EPOLLMSG (__force __poll_t) 0x00000400
-#define EPOLLRDHUP (__force __poll_t) 0x00002000
-#define EPOLL_URING_WAKE ((__force __poll_t) (1U << 27))
-#define EPOLLEXCLUSIVE ((__force __poll_t) (1U << 28))
-#define EPOLLWAKEUP ((__force __poll_t) (1U << 29))
-#define EPOLLONESHOT ((__force __poll_t) (1U << 30))
-#define EPOLLET ((__force __poll_t) (1U << 31))
+#define EPOLLIN ( __poll_t) 0x00000001
+#define EPOLLPRI ( __poll_t) 0x00000002
+#define EPOLLOUT ( __poll_t) 0x00000004
+#define EPOLLERR ( __poll_t) 0x00000008
+#define EPOLLHUP ( __poll_t) 0x00000010
+#define EPOLLNVAL ( __poll_t) 0x00000020
+#define EPOLLRDNORM ( __poll_t) 0x00000040
+#define EPOLLRDBAND ( __poll_t) 0x00000080
+#define EPOLLWRNORM ( __poll_t) 0x00000100
+#define EPOLLWRBAND ( __poll_t) 0x00000200
+#define EPOLLMSG ( __poll_t) 0x00000400
+#define EPOLLRDHUP ( __poll_t) 0x00002000
+#define EPOLL_URING_WAKE (( __poll_t) (1U << 27))
+#define EPOLLEXCLUSIVE (( __poll_t) (1U << 28))
+#define EPOLLWAKEUP (( __poll_t) (1U << 29))
+#define EPOLLONESHOT (( __poll_t) (1U << 30))
+#define EPOLLET (( __poll_t) (1U << 31))
 #ifdef __x86_64__
 #define EPOLL_PACKED __attribute__((packed))
 #else
diff --git a/libc/kernel/uapi/linux/fd.h b/libc/kernel/uapi/linux/fd.h
index 4d72d69..dc1d444 100644
--- a/libc/kernel/uapi/linux/fd.h
+++ b/libc/kernel/uapi/linux/fd.h
@@ -175,7 +175,7 @@
 #define FD_RAW_SOFTFAILURE 0x800
 #define FD_RAW_FAILURE 0x10000
 #define FD_RAW_HARDFAILURE 0x20000
-  void __user * data;
+  void  * data;
   char * kernel_data;
   struct floppy_raw_cmd * next;
   long length;
diff --git a/libc/kernel/uapi/linux/filter.h b/libc/kernel/uapi/linux/filter.h
index d13c59d..57fe2fb 100644
--- a/libc/kernel/uapi/linux/filter.h
+++ b/libc/kernel/uapi/linux/filter.h
@@ -31,7 +31,7 @@
 };
 struct sock_fprog {
   unsigned short len;
-  struct sock_filter __user * filter;
+  struct sock_filter  * filter;
 };
 #define BPF_RVAL(code) ((code) & 0x18)
 #define BPF_A 0x10
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 96f9181..b8bfaac 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -190,10 +190,10 @@
 #define SYNC_FILE_RANGE_WAIT_AFTER 4
 #define SYNC_FILE_RANGE_WRITE_AND_WAIT (SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WAIT_AFTER)
 typedef int __bitwise __kernel_rwf_t;
-#define RWF_HIPRI ((__force __kernel_rwf_t) 0x00000001)
-#define RWF_DSYNC ((__force __kernel_rwf_t) 0x00000002)
-#define RWF_SYNC ((__force __kernel_rwf_t) 0x00000004)
-#define RWF_NOWAIT ((__force __kernel_rwf_t) 0x00000008)
-#define RWF_APPEND ((__force __kernel_rwf_t) 0x00000010)
+#define RWF_HIPRI (( __kernel_rwf_t) 0x00000001)
+#define RWF_DSYNC (( __kernel_rwf_t) 0x00000002)
+#define RWF_SYNC (( __kernel_rwf_t) 0x00000004)
+#define RWF_NOWAIT (( __kernel_rwf_t) 0x00000008)
+#define RWF_APPEND (( __kernel_rwf_t) 0x00000010)
 #define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT | RWF_APPEND)
 #endif
diff --git a/libc/kernel/uapi/linux/futex.h b/libc/kernel/uapi/linux/futex.h
index c80b90c..8d1a2a4 100644
--- a/libc/kernel/uapi/linux/futex.h
+++ b/libc/kernel/uapi/linux/futex.h
@@ -59,12 +59,12 @@
   __u32 __reserved;
 };
 struct robust_list {
-  struct robust_list __user * next;
+  struct robust_list  * next;
 };
 struct robust_list_head {
   struct robust_list list;
   long futex_offset;
-  struct robust_list __user * list_op_pending;
+  struct robust_list  * list_op_pending;
 };
 #define FUTEX_WAITERS 0x80000000
 #define FUTEX_OWNER_DIED 0x40000000
diff --git a/libc/kernel/uapi/linux/i2c-dev.h b/libc/kernel/uapi/linux/i2c-dev.h
index 07fdda2..7a25e20 100644
--- a/libc/kernel/uapi/linux/i2c-dev.h
+++ b/libc/kernel/uapi/linux/i2c-dev.h
@@ -33,10 +33,10 @@
   __u8 read_write;
   __u8 command;
   __u32 size;
-  union i2c_smbus_data __user * data;
+  union i2c_smbus_data  * data;
 };
 struct i2c_rdwr_ioctl_data {
-  struct i2c_msg __user * msgs;
+  struct i2c_msg  * msgs;
   __u32 nmsgs;
 };
 #define I2C_RDWR_IOCTL_MAX_MSGS 42
diff --git a/libc/kernel/uapi/linux/i2o-dev.h b/libc/kernel/uapi/linux/i2o-dev.h
index fc8b26d..afaae74 100644
--- a/libc/kernel/uapi/linux/i2o-dev.h
+++ b/libc/kernel/uapi/linux/i2o-dev.h
@@ -42,38 +42,38 @@
 };
 struct i2o_cmd_passthru {
   unsigned int iop;
-  void __user * msg;
+  void  * msg;
 };
 struct i2o_cmd_hrtlct {
   unsigned int iop;
-  void __user * resbuf;
-  unsigned int __user * reslen;
+  void  * resbuf;
+  unsigned int  * reslen;
 };
 struct i2o_cmd_psetget {
   unsigned int iop;
   unsigned int tid;
-  void __user * opbuf;
+  void  * opbuf;
   unsigned int oplen;
-  void __user * resbuf;
-  unsigned int __user * reslen;
+  void  * resbuf;
+  unsigned int  * reslen;
 };
 struct i2o_sw_xfer {
   unsigned int iop;
   unsigned char flags;
   unsigned char sw_type;
   unsigned int sw_id;
-  void __user * buf;
-  unsigned int __user * swlen;
-  unsigned int __user * maxfrag;
-  unsigned int __user * curfrag;
+  void  * buf;
+  unsigned int  * swlen;
+  unsigned int  * maxfrag;
+  unsigned int  * curfrag;
 };
 struct i2o_html {
   unsigned int iop;
   unsigned int tid;
   unsigned int page;
-  void __user * resbuf;
-  unsigned int __user * reslen;
-  void __user * qbuf;
+  void  * resbuf;
+  unsigned int  * reslen;
+  void  * qbuf;
   unsigned int qlen;
 };
 #define I2O_EVT_Q_LEN 32
diff --git a/libc/kernel/uapi/linux/if.h b/libc/kernel/uapi/linux/if.h
index 63c77eb..fc6d20d 100644
--- a/libc/kernel/uapi/linux/if.h
+++ b/libc/kernel/uapi/linux/if.h
@@ -130,14 +130,14 @@
   unsigned int type;
   unsigned int size;
   union {
-    raw_hdlc_proto __user * raw_hdlc;
-    cisco_proto __user * cisco;
-    fr_proto __user * fr;
-    fr_proto_pvc __user * fr_pvc;
-    fr_proto_pvc_info __user * fr_pvc_info;
-    x25_hdlc_proto __user * x25;
-    sync_serial_settings __user * sync;
-    te1_settings __user * te1;
+    raw_hdlc_proto  * raw_hdlc;
+    cisco_proto  * cisco;
+    fr_proto  * fr;
+    fr_proto_pvc  * fr_pvc;
+    fr_proto_pvc_info  * fr_pvc_info;
+    x25_hdlc_proto  * x25;
+    sync_serial_settings  * sync;
+    te1_settings  * te1;
   } ifs_ifsu;
 };
 #if __UAPI_DEF_IF_IFREQ
@@ -158,7 +158,7 @@
     struct ifmap ifru_map;
     char ifru_slave[IFNAMSIZ];
     char ifru_newname[IFNAMSIZ];
-    void __user * ifru_data;
+    void  * ifru_data;
     struct if_settings ifru_settings;
   } ifr_ifru;
 };
@@ -184,8 +184,8 @@
 struct ifconf {
   int ifc_len;
   union {
-    char __user * ifcu_buf;
-    struct ifreq __user * ifcu_req;
+    char  * ifcu_buf;
+    struct ifreq  * ifcu_req;
   } ifc_ifcu;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index 01c2dc9..9b85568 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -142,7 +142,7 @@
   __IFLA_GRE_MAX,
 };
 #define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
-#define VTI_ISVTI ((__force __be16) 0x0001)
+#define VTI_ISVTI (( __be16) 0x0001)
 enum {
   IFLA_VTI_UNSPEC,
   IFLA_VTI_LINK,
diff --git a/libc/kernel/uapi/linux/input.h b/libc/kernel/uapi/linux/input.h
index 4858c81..1df1398 100644
--- a/libc/kernel/uapi/linux/input.h
+++ b/libc/kernel/uapi/linux/input.h
@@ -173,7 +173,7 @@
   __u16 phase;
   struct ff_envelope envelope;
   __u32 custom_len;
-  __s16 __user * custom_data;
+  __s16  * custom_data;
 };
 struct ff_rumble_effect {
   __u16 strong_magnitude;
diff --git a/libc/kernel/uapi/linux/ipc.h b/libc/kernel/uapi/linux/ipc.h
index a0699cf..4ca9ee1 100644
--- a/libc/kernel/uapi/linux/ipc.h
+++ b/libc/kernel/uapi/linux/ipc.h
@@ -42,7 +42,7 @@
 #define IPC_OLD 0
 #define IPC_64 0x0100
 struct ipc_kludge {
-  struct msgbuf __user * msgp;
+  struct msgbuf  * msgp;
   long msgtyp;
 };
 #define SEMOP 1
diff --git a/libc/kernel/uapi/linux/ipmi.h b/libc/kernel/uapi/linux/ipmi.h
index dd88f2f..bd73b3c 100644
--- a/libc/kernel/uapi/linux/ipmi.h
+++ b/libc/kernel/uapi/linux/ipmi.h
@@ -65,7 +65,7 @@
   unsigned char netfn;
   unsigned char cmd;
   unsigned short data_len;
-  unsigned char __user * data;
+  unsigned char  * data;
 };
 struct kernel_ipmi_msg {
   unsigned char netfn;
@@ -86,7 +86,7 @@
 #define IPMI_MAINTENANCE_MODE_ON 2
 #define IPMI_IOC_MAGIC 'i'
 struct ipmi_req {
-  unsigned char __user * addr;
+  unsigned char  * addr;
   unsigned int addr_len;
   long msgid;
   struct ipmi_msg msg;
@@ -100,7 +100,7 @@
 #define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, struct ipmi_req_settime)
 struct ipmi_recv {
   int recv_type;
-  unsigned char __user * addr;
+  unsigned char  * addr;
   unsigned int addr_len;
   long msgid;
   struct ipmi_msg msg;
diff --git a/libc/kernel/uapi/linux/ivtv.h b/libc/kernel/uapi/linux/ivtv.h
index 549d6a8..bdd526e 100644
--- a/libc/kernel/uapi/linux/ivtv.h
+++ b/libc/kernel/uapi/linux/ivtv.h
@@ -24,8 +24,8 @@
 struct ivtv_dma_frame {
   enum v4l2_buf_type type;
   __u32 pixelformat;
-  void __user * y_source;
-  void __user * uv_source;
+  void  * y_source;
+  void  * uv_source;
   struct v4l2_rect src;
   struct v4l2_rect dst;
   __u32 src_width;
diff --git a/libc/kernel/uapi/linux/ivtvfb.h b/libc/kernel/uapi/linux/ivtvfb.h
index 9addcbf..171be74 100644
--- a/libc/kernel/uapi/linux/ivtvfb.h
+++ b/libc/kernel/uapi/linux/ivtvfb.h
@@ -21,7 +21,7 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 struct ivtvfb_dma_frame {
-  void __user * source;
+  void  * source;
   unsigned long dest_offset;
   int count;
 };
diff --git a/libc/kernel/uapi/linux/kd.h b/libc/kernel/uapi/linux/kd.h
index 2385037..903681b 100644
--- a/libc/kernel/uapi/linux/kd.h
+++ b/libc/kernel/uapi/linux/kd.h
@@ -27,7 +27,7 @@
 struct consolefontdesc {
   unsigned short charcount;
   unsigned short charheight;
-  char __user * chardata;
+  char  * chardata;
 };
 #define PIO_FONTRESET 0x4B6D
 #define GIO_CMAP 0x4B70
@@ -68,7 +68,7 @@
 };
 struct unimapdesc {
   unsigned short entry_ct;
-  struct unipair __user * entries;
+  struct unipair  * entries;
 };
 #define PIO_UNIMAP 0x4B67
 #define PIO_UNIMAPCLR 0x4B68
@@ -147,7 +147,7 @@
   unsigned int flags;
   unsigned int width, height;
   unsigned int charcount;
-  unsigned char __user * data;
+  unsigned char  * data;
 };
 struct console_font {
   unsigned int width, height;
diff --git a/libc/kernel/uapi/linux/keyctl.h b/libc/kernel/uapi/linux/keyctl.h
index 01ea576..b534f5e 100644
--- a/libc/kernel/uapi/linux/keyctl.h
+++ b/libc/kernel/uapi/linux/keyctl.h
@@ -80,8 +80,8 @@
   __s32 base;
 };
 struct keyctl_kdf_params {
-  char __user * hashname;
-  char __user * otherinfo;
+  char  * hashname;
+  char  * otherinfo;
   __u32 otherinfolen;
   __u32 __spare[8];
 };
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 9566f01..9d33399 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -457,7 +457,7 @@
   __u32 slot;
   __u32 padding1;
   union {
-    void __user * dirty_bitmap;
+    void  * dirty_bitmap;
     __u64 padding2;
   };
 };
@@ -466,7 +466,7 @@
   __u32 num_pages;
   __u64 first_page;
   union {
-    void __user * dirty_bitmap;
+    void  * dirty_bitmap;
     __u64 padding2;
   };
 };
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index 869d47b..fe97e90 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -125,8 +125,8 @@
 };
 struct media_links_enum {
   __u32 entity;
-  struct media_pad_desc __user * pads;
-  struct media_link_desc __user * links;
+  struct media_pad_desc  * pads;
+  struct media_link_desc  * links;
   __u32 reserved[4];
 };
 #define MEDIA_INTF_T_DVB_BASE 0x00000100
diff --git a/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h b/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
index 862f514..b1fb537 100644
--- a/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_arp/arp_tables.h
@@ -98,7 +98,7 @@
   unsigned int hook_entry[NF_ARP_NUMHOOKS];
   unsigned int underflow[NF_ARP_NUMHOOKS];
   unsigned int num_counters;
-  struct xt_counters __user * counters;
+  struct xt_counters  * counters;
   struct arpt_entry entries[];
 };
 struct arpt_get_entries {
diff --git a/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h b/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
index 7c8f435..d87d65e 100644
--- a/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
+++ b/libc/kernel/uapi/linux/netfilter_bridge/ebtables.h
@@ -42,10 +42,10 @@
   unsigned int valid_hooks;
   unsigned int nentries;
   unsigned int entries_size;
-  struct ebt_entries __user * hook_entry[NF_BR_NUMHOOKS];
+  struct ebt_entries  * hook_entry[NF_BR_NUMHOOKS];
   unsigned int num_counters;
-  struct ebt_counter __user * counters;
-  char __user * entries;
+  struct ebt_counter  * counters;
+  char  * entries;
 };
 struct ebt_replace_kernel {
   char name[EBT_TABLE_MAXNAMELEN];
diff --git a/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h b/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
index 14a65ad..5179be4 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv4/ip_tables.h
@@ -112,7 +112,7 @@
   unsigned int hook_entry[NF_INET_NUMHOOKS];
   unsigned int underflow[NF_INET_NUMHOOKS];
   unsigned int num_counters;
-  struct xt_counters __user * counters;
+  struct xt_counters  * counters;
   struct ipt_entry entries[];
 };
 struct ipt_get_entries {
diff --git a/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h b/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
index 22071db..8c4ec88 100644
--- a/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
+++ b/libc/kernel/uapi/linux/netfilter_ipv6/ip6_tables.h
@@ -132,7 +132,7 @@
   unsigned int hook_entry[NF_INET_NUMHOOKS];
   unsigned int underflow[NF_INET_NUMHOOKS];
   unsigned int num_counters;
-  struct xt_counters __user * counters;
+  struct xt_counters  * counters;
   struct ip6t_entry entries[];
 };
 struct ip6t_get_entries {
diff --git a/libc/kernel/uapi/linux/nfs4_mount.h b/libc/kernel/uapi/linux/nfs4_mount.h
index 0f794dd..9b9c9f8 100644
--- a/libc/kernel/uapi/linux/nfs4_mount.h
+++ b/libc/kernel/uapi/linux/nfs4_mount.h
@@ -21,7 +21,7 @@
 #define NFS4_MOUNT_VERSION 1
 struct nfs_string {
   unsigned int len;
-  const char __user * data;
+  const char  * data;
 };
 struct nfs4_mount_data {
   int version;
@@ -38,10 +38,10 @@
   struct nfs_string mnt_path;
   struct nfs_string hostname;
   unsigned int host_addrlen;
-  struct sockaddr __user * host_addr;
+  struct sockaddr  * host_addr;
   int proto;
   int auth_flavourlen;
-  int __user * auth_flavours;
+  int  * auth_flavours;
 };
 #define NFS4_MOUNT_SOFT 0x0001
 #define NFS4_MOUNT_INTR 0x0002
diff --git a/libc/kernel/uapi/linux/omap3isp.h b/libc/kernel/uapi/linux/omap3isp.h
index 53345e3..1834658 100644
--- a/libc/kernel/uapi/linux/omap3isp.h
+++ b/libc/kernel/uapi/linux/omap3isp.h
@@ -88,7 +88,7 @@
 };
 struct omap3isp_stat_data {
   struct timeval ts;
-  void __user * buf;
+  void  * buf;
   __struct_group(, frame,, __u32 buf_size;
   __u16 frame_number;
   __u16 cur_frame;
@@ -224,12 +224,12 @@
   __u16 update;
   __u16 flag;
   enum omap3isp_alaw_ipwidth alawip;
-  struct omap3isp_ccdc_bclamp __user * bclamp;
-  struct omap3isp_ccdc_blcomp __user * blcomp;
-  struct omap3isp_ccdc_fpc __user * fpc;
-  struct omap3isp_ccdc_lsc_config __user * lsc_cfg;
-  struct omap3isp_ccdc_culling __user * cull;
-  __u8 __user * lsc;
+  struct omap3isp_ccdc_bclamp  * bclamp;
+  struct omap3isp_ccdc_blcomp  * blcomp;
+  struct omap3isp_ccdc_fpc  * fpc;
+  struct omap3isp_ccdc_lsc_config  * lsc_cfg;
+  struct omap3isp_ccdc_culling  * cull;
+  __u8  * lsc;
 };
 #define OMAP3ISP_PREV_LUMAENH (1 << 0)
 #define OMAP3ISP_PREV_INVALAW (1 << 1)
@@ -323,17 +323,17 @@
   __u32 update;
   __u32 flag;
   __u32 shading_shift;
-  struct omap3isp_prev_luma __user * luma;
-  struct omap3isp_prev_hmed __user * hmed;
-  struct omap3isp_prev_cfa __user * cfa;
-  struct omap3isp_prev_csup __user * csup;
-  struct omap3isp_prev_wbal __user * wbal;
-  struct omap3isp_prev_blkadj __user * blkadj;
-  struct omap3isp_prev_rgbtorgb __user * rgb2rgb;
-  struct omap3isp_prev_csc __user * csc;
-  struct omap3isp_prev_yclimit __user * yclimit;
-  struct omap3isp_prev_dcor __user * dcor;
-  struct omap3isp_prev_nf __user * nf;
-  struct omap3isp_prev_gtables __user * gamma;
+  struct omap3isp_prev_luma  * luma;
+  struct omap3isp_prev_hmed  * hmed;
+  struct omap3isp_prev_cfa  * cfa;
+  struct omap3isp_prev_csup  * csup;
+  struct omap3isp_prev_wbal  * wbal;
+  struct omap3isp_prev_blkadj  * blkadj;
+  struct omap3isp_prev_rgbtorgb  * rgb2rgb;
+  struct omap3isp_prev_csc  * csc;
+  struct omap3isp_prev_yclimit  * yclimit;
+  struct omap3isp_prev_dcor  * dcor;
+  struct omap3isp_prev_nf  * nf;
+  struct omap3isp_prev_gtables  * gamma;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/omapfb.h b/libc/kernel/uapi/linux/omapfb.h
index 6ebec08..632e468 100644
--- a/libc/kernel/uapi/linux/omapfb.h
+++ b/libc/kernel/uapi/linux/omapfb.h
@@ -153,7 +153,7 @@
   __u16 w;
   __u16 h;
   size_t buffer_size;
-  void __user * buffer;
+  void  * buffer;
 };
 struct omapfb_ovl_colormode {
   __u8 overlay_idx;
diff --git a/libc/kernel/uapi/linux/ppp-ioctl.h b/libc/kernel/uapi/linux/ppp-ioctl.h
index 69c6e6d..165d447 100644
--- a/libc/kernel/uapi/linux/ppp-ioctl.h
+++ b/libc/kernel/uapi/linux/ppp-ioctl.h
@@ -56,7 +56,7 @@
   enum NPmode mode;
 };
 struct ppp_option_data {
-  __u8 __user * ptr;
+  __u8  * ptr;
   __u32 length;
   int transmit;
 };
diff --git a/libc/kernel/uapi/linux/route.h b/libc/kernel/uapi/linux/route.h
index 4ba6023..f33327c 100644
--- a/libc/kernel/uapi/linux/route.h
+++ b/libc/kernel/uapi/linux/route.h
@@ -30,7 +30,7 @@
   unsigned long rt_pad3;
   void * rt_pad4;
   short rt_metric;
-  char __user * rt_dev;
+  char  * rt_dev;
   unsigned long rt_mtu;
 #define rt_mss rt_mtu
   unsigned long rt_window;
diff --git a/libc/kernel/uapi/linux/sem.h b/libc/kernel/uapi/linux/sem.h
index 98ed1bf..c2f25e7 100644
--- a/libc/kernel/uapi/linux/sem.h
+++ b/libc/kernel/uapi/linux/sem.h
@@ -48,10 +48,10 @@
 };
 union __kernel_legacy_semun {
   int val;
-  struct __kernel_legacy_semid_ds __user * buf;
-  unsigned short __user * array;
-  struct seminfo __user * __buf;
-  void __user * __pad;
+  struct __kernel_legacy_semid_ds  * buf;
+  unsigned short  * array;
+  struct seminfo  * __buf;
+  void  * __pad;
 };
 struct seminfo {
   int semmap;
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index ff17f7c..5714323 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -23,11 +23,11 @@
 #include <linux/compiler.h>
 #define CTL_MAXNAME 10
 struct __sysctl_args {
-  int __user * name;
+  int  * name;
   int nlen;
-  void __user * oldval;
-  size_t __user * oldlenp;
-  void __user * newval;
+  void  * oldval;
+  size_t  * oldlenp;
+  void  * newval;
   size_t newlen;
   unsigned long __linux_unused[4];
 };
diff --git a/libc/kernel/uapi/linux/time.h b/libc/kernel/uapi/linux/time.h
index df52295..55d0e6e 100644
--- a/libc/kernel/uapi/linux/time.h
+++ b/libc/kernel/uapi/linux/time.h
@@ -18,14 +18,11 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_TIME_H
 #define _UAPI_LINUX_TIME_H
+#include <bits/timespec.h>
 #include <linux/types.h>
 #include <linux/time_types.h>
 #ifndef _STRUCT_TIMESPEC
 #define _STRUCT_TIMESPEC
-struct timespec {
-  __kernel_old_time_t tv_sec;
-  long tv_nsec;
-};
 #endif
 struct timeval {
   __kernel_old_time_t tv_sec;
diff --git a/libc/kernel/uapi/linux/uhid.h b/libc/kernel/uapi/linux/uhid.h
index 228ee50..1d471f8 100644
--- a/libc/kernel/uapi/linux/uhid.h
+++ b/libc/kernel/uapi/linux/uhid.h
@@ -106,7 +106,7 @@
   __u8 name[128];
   __u8 phys[64];
   __u8 uniq[64];
-  __u8 __user * rd_data;
+  __u8  * rd_data;
   __u16 rd_size;
   __u16 bus;
   __u32 vendor;
diff --git a/libc/kernel/uapi/linux/uio.h b/libc/kernel/uapi/linux/uio.h
index fa955cd..04814c7 100644
--- a/libc/kernel/uapi/linux/uio.h
+++ b/libc/kernel/uapi/linux/uio.h
@@ -21,7 +21,7 @@
 #include <linux/compiler.h>
 #include <linux/types.h>
 struct iovec {
-  void __user * iov_base;
+  void  * iov_base;
   __kernel_size_t iov_len;
 };
 #define UIO_FASTIOV 8
diff --git a/libc/kernel/uapi/linux/usb/tmc.h b/libc/kernel/uapi/linux/usb/tmc.h
index 6d0add1..b267290 100644
--- a/libc/kernel/uapi/linux/usb/tmc.h
+++ b/libc/kernel/uapi/linux/usb/tmc.h
@@ -46,7 +46,7 @@
 } __attribute__((packed));
 struct usbtmc_ctrlrequest {
   struct usbtmc_request req;
-  void __user * data;
+  void  * data;
 } __attribute__((packed));
 struct usbtmc_termchar {
   __u8 term_char;
@@ -59,7 +59,7 @@
   __u32 transfer_size;
   __u32 transferred;
   __u32 flags;
-  void __user * message;
+  void  * message;
 } __attribute__((packed));
 #define USBTMC_IOC_NR 91
 #define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1)
diff --git a/libc/kernel/uapi/linux/usbdevice_fs.h b/libc/kernel/uapi/linux/usbdevice_fs.h
index 5fef522..af8681b 100644
--- a/libc/kernel/uapi/linux/usbdevice_fs.h
+++ b/libc/kernel/uapi/linux/usbdevice_fs.h
@@ -27,13 +27,13 @@
   __u16 wIndex;
   __u16 wLength;
   __u32 timeout;
-  void __user * data;
+  void  * data;
 };
 struct usbdevfs_bulktransfer {
   unsigned int ep;
   unsigned int len;
   unsigned int timeout;
-  void __user * data;
+  void  * data;
 };
 struct usbdevfs_setinterface {
   unsigned int interface;
@@ -41,7 +41,7 @@
 };
 struct usbdevfs_disconnectsignal {
   unsigned int signr;
-  void __user * context;
+  void  * context;
 };
 #define USBDEVFS_MAXDRIVERNAME 255
 struct usbdevfs_getdriver {
@@ -80,7 +80,7 @@
   unsigned char endpoint;
   int status;
   unsigned int flags;
-  void __user * buffer;
+  void  * buffer;
   int buffer_length;
   int actual_length;
   int start_frame;
@@ -90,13 +90,13 @@
   };
   int error_count;
   unsigned int signr;
-  void __user * usercontext;
+  void  * usercontext;
   struct usbdevfs_iso_packet_desc iso_frame_desc[];
 };
 struct usbdevfs_ioctl {
   int ifno;
   int ioctl_code;
-  void __user * data;
+  void  * data;
 };
 struct usbdevfs_hub_portinfo {
   char nports;
diff --git a/libc/kernel/uapi/linux/uvcvideo.h b/libc/kernel/uapi/linux/uvcvideo.h
index 46528a9..f15ed78 100644
--- a/libc/kernel/uapi/linux/uvcvideo.h
+++ b/libc/kernel/uapi/linux/uvcvideo.h
@@ -49,7 +49,7 @@
   __u8 offset;
   __u32 v4l2_type;
   __u32 data_type;
-  struct uvc_menu_info __user * menu_info;
+  struct uvc_menu_info  * menu_info;
   __u32 menu_count;
   __u32 reserved[4];
 };
@@ -58,7 +58,7 @@
   __u8 selector;
   __u8 query;
   __u16 size;
-  __u8 __user * data;
+  __u8  * data;
 };
 #define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping)
 #define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query)
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index 7dc3440..3c1821c 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -390,7 +390,7 @@
 struct vfio_bitmap {
   __u64 pgsize;
   __u64 size;
-  __u64 __user * data;
+  __u64  * data;
 };
 struct vfio_iommu_type1_dma_unmap {
   __u32 argsz;
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index d418fd2..4fb0a25 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -650,7 +650,7 @@
 #define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040
 struct v4l2_clip {
   struct v4l2_rect c;
-  struct v4l2_clip __user * next;
+  struct v4l2_clip  * next;
 };
 struct v4l2_window {
   struct v4l2_rect w;
@@ -658,7 +658,7 @@
   __u32 chromakey;
   struct v4l2_clip * clips;
   __u32 clipcount;
-  void __user * bitmap;
+  void  * bitmap;
   __u8 global_alpha;
 };
 struct v4l2_captureparm {
@@ -895,32 +895,32 @@
   union {
     __s32 value;
     __s64 value64;
-    char __user * string;
-    __u8 __user * p_u8;
-    __u16 __user * p_u16;
-    __u32 __user * p_u32;
-    __u32 __user * p_s32;
-    __u32 __user * p_s64;
-    struct v4l2_area __user * p_area;
-    struct v4l2_ctrl_h264_sps __user * p_h264_sps;
+    char  * string;
+    __u8  * p_u8;
+    __u16  * p_u16;
+    __u32  * p_u32;
+    __u32  * p_s32;
+    __u32  * p_s64;
+    struct v4l2_area  * p_area;
+    struct v4l2_ctrl_h264_sps  * p_h264_sps;
     struct v4l2_ctrl_h264_pps * p_h264_pps;
-    struct v4l2_ctrl_h264_scaling_matrix __user * p_h264_scaling_matrix;
-    struct v4l2_ctrl_h264_pred_weights __user * p_h264_pred_weights;
-    struct v4l2_ctrl_h264_slice_params __user * p_h264_slice_params;
-    struct v4l2_ctrl_h264_decode_params __user * p_h264_decode_params;
-    struct v4l2_ctrl_fwht_params __user * p_fwht_params;
-    struct v4l2_ctrl_vp8_frame __user * p_vp8_frame;
-    struct v4l2_ctrl_mpeg2_sequence __user * p_mpeg2_sequence;
-    struct v4l2_ctrl_mpeg2_picture __user * p_mpeg2_picture;
-    struct v4l2_ctrl_mpeg2_quantisation __user * p_mpeg2_quantisation;
-    struct v4l2_ctrl_vp9_compressed_hdr __user * p_vp9_compressed_hdr_probs;
-    struct v4l2_ctrl_vp9_frame __user * p_vp9_frame;
-    struct v4l2_ctrl_hevc_sps __user * p_hevc_sps;
-    struct v4l2_ctrl_hevc_pps __user * p_hevc_pps;
-    struct v4l2_ctrl_hevc_slice_params __user * p_hevc_slice_params;
-    struct v4l2_ctrl_hevc_scaling_matrix __user * p_hevc_scaling_matrix;
-    struct v4l2_ctrl_hevc_decode_params __user * p_hevc_decode_params;
-    void __user * ptr;
+    struct v4l2_ctrl_h264_scaling_matrix  * p_h264_scaling_matrix;
+    struct v4l2_ctrl_h264_pred_weights  * p_h264_pred_weights;
+    struct v4l2_ctrl_h264_slice_params  * p_h264_slice_params;
+    struct v4l2_ctrl_h264_decode_params  * p_h264_decode_params;
+    struct v4l2_ctrl_fwht_params  * p_fwht_params;
+    struct v4l2_ctrl_vp8_frame  * p_vp8_frame;
+    struct v4l2_ctrl_mpeg2_sequence  * p_mpeg2_sequence;
+    struct v4l2_ctrl_mpeg2_picture  * p_mpeg2_picture;
+    struct v4l2_ctrl_mpeg2_quantisation  * p_mpeg2_quantisation;
+    struct v4l2_ctrl_vp9_compressed_hdr  * p_vp9_compressed_hdr_probs;
+    struct v4l2_ctrl_vp9_frame  * p_vp9_frame;
+    struct v4l2_ctrl_hevc_sps  * p_hevc_sps;
+    struct v4l2_ctrl_hevc_pps  * p_hevc_pps;
+    struct v4l2_ctrl_hevc_slice_params  * p_hevc_slice_params;
+    struct v4l2_ctrl_hevc_scaling_matrix  * p_hevc_scaling_matrix;
+    struct v4l2_ctrl_hevc_decode_params  * p_hevc_decode_params;
+    void  * ptr;
   };
 } __attribute__((packed));
 struct v4l2_ext_controls {
diff --git a/libc/kernel/uapi/linux/wireless.h b/libc/kernel/uapi/linux/wireless.h
index ca31dd2..eb57fff 100644
--- a/libc/kernel/uapi/linux/wireless.h
+++ b/libc/kernel/uapi/linux/wireless.h
@@ -264,7 +264,7 @@
   __u16 flags;
 };
 struct iw_point {
-  void __user * pointer;
+  void  * pointer;
   __u16 length;
   __u16 flags;
 };
diff --git a/libc/kernel/uapi/mtd/mtd-abi.h b/libc/kernel/uapi/mtd/mtd-abi.h
index 6e26cae..aed2acc 100644
--- a/libc/kernel/uapi/mtd/mtd-abi.h
+++ b/libc/kernel/uapi/mtd/mtd-abi.h
@@ -30,7 +30,7 @@
 struct mtd_oob_buf {
   __u32 start;
   __u32 length;
-  unsigned char __user * ptr;
+  unsigned char  * ptr;
 };
 struct mtd_oob_buf64 {
   __u64 start;
diff --git a/libc/kernel/uapi/sound/asequencer.h b/libc/kernel/uapi/sound/asequencer.h
index 0076933..01a5058 100644
--- a/libc/kernel/uapi/sound/asequencer.h
+++ b/libc/kernel/uapi/sound/asequencer.h
@@ -209,9 +209,9 @@
 #define SNDRV_SEQ_CLIENT_DUMMY 14
 #define SNDRV_SEQ_CLIENT_OSS 15
 typedef int __bitwise snd_seq_client_type_t;
-#define NO_CLIENT ((__force snd_seq_client_type_t) 0)
-#define USER_CLIENT ((__force snd_seq_client_type_t) 1)
-#define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2)
+#define NO_CLIENT (( snd_seq_client_type_t) 0)
+#define USER_CLIENT (( snd_seq_client_type_t) 1)
+#define KERNEL_CLIENT (( snd_seq_client_type_t) 2)
 #define SNDRV_SEQ_FILTER_BROADCAST (1U << 0)
 #define SNDRV_SEQ_FILTER_MULTICAST (1U << 1)
 #define SNDRV_SEQ_FILTER_BOUNCE (1U << 2)
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 6e325e9..9c1a3ae 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -96,7 +96,7 @@
 struct snd_hwdep_dsp_image {
   unsigned int index;
   unsigned char name[64];
-  unsigned char __user * image;
+  unsigned char  * image;
   size_t length;
   unsigned long driver_data;
 };
@@ -125,64 +125,64 @@
   SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
 };
 typedef int __bitwise snd_pcm_access_t;
-#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0)
-#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1)
-#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2)
-#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3)
-#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4)
+#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED (( snd_pcm_access_t) 0)
+#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED (( snd_pcm_access_t) 1)
+#define SNDRV_PCM_ACCESS_MMAP_COMPLEX (( snd_pcm_access_t) 2)
+#define SNDRV_PCM_ACCESS_RW_INTERLEAVED (( snd_pcm_access_t) 3)
+#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED (( snd_pcm_access_t) 4)
 #define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
 typedef int __bitwise snd_pcm_format_t;
-#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0)
-#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1)
-#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2)
-#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3)
-#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4)
-#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5)
-#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6)
-#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7)
-#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8)
-#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9)
-#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10)
-#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11)
-#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12)
-#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13)
-#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14)
-#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15)
-#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16)
-#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17)
-#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18)
-#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19)
-#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20)
-#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21)
-#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22)
-#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23)
-#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24)
-#define SNDRV_PCM_FORMAT_S20_LE ((__force snd_pcm_format_t) 25)
-#define SNDRV_PCM_FORMAT_S20_BE ((__force snd_pcm_format_t) 26)
-#define SNDRV_PCM_FORMAT_U20_LE ((__force snd_pcm_format_t) 27)
-#define SNDRV_PCM_FORMAT_U20_BE ((__force snd_pcm_format_t) 28)
-#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31)
-#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32)
-#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33)
-#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34)
-#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35)
-#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36)
-#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37)
-#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38)
-#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39)
-#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40)
-#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41)
-#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42)
-#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43)
-#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44)
-#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45)
-#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46)
-#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47)
-#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48)
-#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49)
-#define SNDRV_PCM_FORMAT_DSD_U32_LE ((__force snd_pcm_format_t) 50)
-#define SNDRV_PCM_FORMAT_DSD_U16_BE ((__force snd_pcm_format_t) 51)
-#define SNDRV_PCM_FORMAT_DSD_U32_BE ((__force snd_pcm_format_t) 52)
+#define SNDRV_PCM_FORMAT_S8 (( snd_pcm_format_t) 0)
+#define SNDRV_PCM_FORMAT_U8 (( snd_pcm_format_t) 1)
+#define SNDRV_PCM_FORMAT_S16_LE (( snd_pcm_format_t) 2)
+#define SNDRV_PCM_FORMAT_S16_BE (( snd_pcm_format_t) 3)
+#define SNDRV_PCM_FORMAT_U16_LE (( snd_pcm_format_t) 4)
+#define SNDRV_PCM_FORMAT_U16_BE (( snd_pcm_format_t) 5)
+#define SNDRV_PCM_FORMAT_S24_LE (( snd_pcm_format_t) 6)
+#define SNDRV_PCM_FORMAT_S24_BE (( snd_pcm_format_t) 7)
+#define SNDRV_PCM_FORMAT_U24_LE (( snd_pcm_format_t) 8)
+#define SNDRV_PCM_FORMAT_U24_BE (( snd_pcm_format_t) 9)
+#define SNDRV_PCM_FORMAT_S32_LE (( snd_pcm_format_t) 10)
+#define SNDRV_PCM_FORMAT_S32_BE (( snd_pcm_format_t) 11)
+#define SNDRV_PCM_FORMAT_U32_LE (( snd_pcm_format_t) 12)
+#define SNDRV_PCM_FORMAT_U32_BE (( snd_pcm_format_t) 13)
+#define SNDRV_PCM_FORMAT_FLOAT_LE (( snd_pcm_format_t) 14)
+#define SNDRV_PCM_FORMAT_FLOAT_BE (( snd_pcm_format_t) 15)
+#define SNDRV_PCM_FORMAT_FLOAT64_LE (( snd_pcm_format_t) 16)
+#define SNDRV_PCM_FORMAT_FLOAT64_BE (( snd_pcm_format_t) 17)
+#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE (( snd_pcm_format_t) 18)
+#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE (( snd_pcm_format_t) 19)
+#define SNDRV_PCM_FORMAT_MU_LAW (( snd_pcm_format_t) 20)
+#define SNDRV_PCM_FORMAT_A_LAW (( snd_pcm_format_t) 21)
+#define SNDRV_PCM_FORMAT_IMA_ADPCM (( snd_pcm_format_t) 22)
+#define SNDRV_PCM_FORMAT_MPEG (( snd_pcm_format_t) 23)
+#define SNDRV_PCM_FORMAT_GSM (( snd_pcm_format_t) 24)
+#define SNDRV_PCM_FORMAT_S20_LE (( snd_pcm_format_t) 25)
+#define SNDRV_PCM_FORMAT_S20_BE (( snd_pcm_format_t) 26)
+#define SNDRV_PCM_FORMAT_U20_LE (( snd_pcm_format_t) 27)
+#define SNDRV_PCM_FORMAT_U20_BE (( snd_pcm_format_t) 28)
+#define SNDRV_PCM_FORMAT_SPECIAL (( snd_pcm_format_t) 31)
+#define SNDRV_PCM_FORMAT_S24_3LE (( snd_pcm_format_t) 32)
+#define SNDRV_PCM_FORMAT_S24_3BE (( snd_pcm_format_t) 33)
+#define SNDRV_PCM_FORMAT_U24_3LE (( snd_pcm_format_t) 34)
+#define SNDRV_PCM_FORMAT_U24_3BE (( snd_pcm_format_t) 35)
+#define SNDRV_PCM_FORMAT_S20_3LE (( snd_pcm_format_t) 36)
+#define SNDRV_PCM_FORMAT_S20_3BE (( snd_pcm_format_t) 37)
+#define SNDRV_PCM_FORMAT_U20_3LE (( snd_pcm_format_t) 38)
+#define SNDRV_PCM_FORMAT_U20_3BE (( snd_pcm_format_t) 39)
+#define SNDRV_PCM_FORMAT_S18_3LE (( snd_pcm_format_t) 40)
+#define SNDRV_PCM_FORMAT_S18_3BE (( snd_pcm_format_t) 41)
+#define SNDRV_PCM_FORMAT_U18_3LE (( snd_pcm_format_t) 42)
+#define SNDRV_PCM_FORMAT_U18_3BE (( snd_pcm_format_t) 43)
+#define SNDRV_PCM_FORMAT_G723_24 (( snd_pcm_format_t) 44)
+#define SNDRV_PCM_FORMAT_G723_24_1B (( snd_pcm_format_t) 45)
+#define SNDRV_PCM_FORMAT_G723_40 (( snd_pcm_format_t) 46)
+#define SNDRV_PCM_FORMAT_G723_40_1B (( snd_pcm_format_t) 47)
+#define SNDRV_PCM_FORMAT_DSD_U8 (( snd_pcm_format_t) 48)
+#define SNDRV_PCM_FORMAT_DSD_U16_LE (( snd_pcm_format_t) 49)
+#define SNDRV_PCM_FORMAT_DSD_U32_LE (( snd_pcm_format_t) 50)
+#define SNDRV_PCM_FORMAT_DSD_U16_BE (( snd_pcm_format_t) 51)
+#define SNDRV_PCM_FORMAT_DSD_U32_BE (( snd_pcm_format_t) 52)
 #define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U32_BE
 #define SNDRV_PCM_FORMAT_FIRST SNDRV_PCM_FORMAT_S8
 #ifdef SNDRV_LITTLE_ENDIAN
@@ -212,7 +212,7 @@
 #define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_BE
 #endif
 typedef int __bitwise snd_pcm_subformat_t;
-#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
+#define SNDRV_PCM_SUBFORMAT_STD (( snd_pcm_subformat_t) 0)
 #define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
 #define SNDRV_PCM_INFO_MMAP 0x00000001
 #define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
@@ -243,15 +243,15 @@
 #define __SND_STRUCT_TIME64
 #endif
 typedef int __bitwise snd_pcm_state_t;
-#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0)
-#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1)
-#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2)
-#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3)
-#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4)
-#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5)
-#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6)
-#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7)
-#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8)
+#define SNDRV_PCM_STATE_OPEN (( snd_pcm_state_t) 0)
+#define SNDRV_PCM_STATE_SETUP (( snd_pcm_state_t) 1)
+#define SNDRV_PCM_STATE_PREPARED (( snd_pcm_state_t) 2)
+#define SNDRV_PCM_STATE_RUNNING (( snd_pcm_state_t) 3)
+#define SNDRV_PCM_STATE_XRUN (( snd_pcm_state_t) 4)
+#define SNDRV_PCM_STATE_DRAINING (( snd_pcm_state_t) 5)
+#define SNDRV_PCM_STATE_PAUSED (( snd_pcm_state_t) 6)
+#define SNDRV_PCM_STATE_SUSPENDED (( snd_pcm_state_t) 7)
+#define SNDRV_PCM_STATE_DISCONNECTED (( snd_pcm_state_t) 8)
 #define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
 enum {
   SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
@@ -475,12 +475,12 @@
 };
 struct snd_xferi {
   snd_pcm_sframes_t result;
-  void __user * buf;
+  void  * buf;
   snd_pcm_uframes_t frames;
 };
 struct snd_xfern {
   snd_pcm_sframes_t result;
-  void __user * __user * bufs;
+  void  *  * bufs;
   snd_pcm_uframes_t frames;
 };
 enum {
@@ -776,22 +776,22 @@
   unsigned char components[128];
 };
 typedef int __bitwise snd_ctl_elem_type_t;
-#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0)
-#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1)
-#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2)
-#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3)
-#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4)
-#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5)
-#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6)
+#define SNDRV_CTL_ELEM_TYPE_NONE (( snd_ctl_elem_type_t) 0)
+#define SNDRV_CTL_ELEM_TYPE_BOOLEAN (( snd_ctl_elem_type_t) 1)
+#define SNDRV_CTL_ELEM_TYPE_INTEGER (( snd_ctl_elem_type_t) 2)
+#define SNDRV_CTL_ELEM_TYPE_ENUMERATED (( snd_ctl_elem_type_t) 3)
+#define SNDRV_CTL_ELEM_TYPE_BYTES (( snd_ctl_elem_type_t) 4)
+#define SNDRV_CTL_ELEM_TYPE_IEC958 (( snd_ctl_elem_type_t) 5)
+#define SNDRV_CTL_ELEM_TYPE_INTEGER64 (( snd_ctl_elem_type_t) 6)
 #define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64
 typedef int __bitwise snd_ctl_elem_iface_t;
-#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0)
-#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1)
-#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2)
-#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3)
-#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4)
-#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5)
-#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6)
+#define SNDRV_CTL_ELEM_IFACE_CARD (( snd_ctl_elem_iface_t) 0)
+#define SNDRV_CTL_ELEM_IFACE_HWDEP (( snd_ctl_elem_iface_t) 1)
+#define SNDRV_CTL_ELEM_IFACE_MIXER (( snd_ctl_elem_iface_t) 2)
+#define SNDRV_CTL_ELEM_IFACE_PCM (( snd_ctl_elem_iface_t) 3)
+#define SNDRV_CTL_ELEM_IFACE_RAWMIDI (( snd_ctl_elem_iface_t) 4)
+#define SNDRV_CTL_ELEM_IFACE_TIMER (( snd_ctl_elem_iface_t) 5)
+#define SNDRV_CTL_ELEM_IFACE_SEQUENCER (( snd_ctl_elem_iface_t) 6)
 #define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER
 #define SNDRV_CTL_ELEM_ACCESS_READ (1 << 0)
 #define SNDRV_CTL_ELEM_ACCESS_WRITE (1 << 1)
@@ -826,7 +826,7 @@
   unsigned int space;
   unsigned int used;
   unsigned int count;
-  struct snd_ctl_elem_id __user * pids;
+  struct snd_ctl_elem_id  * pids;
   unsigned char reserved[50];
 };
 struct snd_ctl_elem_info {
diff --git a/libc/kernel/uapi/xen/gntdev.h b/libc/kernel/uapi/xen/gntdev.h
index 1e78ac3..eada73c 100644
--- a/libc/kernel/uapi/xen/gntdev.h
+++ b/libc/kernel/uapi/xen/gntdev.h
@@ -55,7 +55,7 @@
 };
 struct gntdev_grant_copy_segment {
   union {
-    void __user * virt;
+    void  * virt;
     struct {
       grant_ref_t ref;
       __u16 offset;
@@ -69,7 +69,7 @@
 #define IOCTL_GNTDEV_GRANT_COPY _IOC(_IOC_NONE, 'G', 8, sizeof(struct ioctl_gntdev_grant_copy))
 struct ioctl_gntdev_grant_copy {
   unsigned int count;
-  struct gntdev_grant_copy_segment __user * segments;
+  struct gntdev_grant_copy_segment  * segments;
 };
 #define UNMAP_NOTIFY_CLEAR_BYTE 0x1
 #define UNMAP_NOTIFY_SEND_EVENT 0x2
diff --git a/libc/kernel/uapi/xen/privcmd.h b/libc/kernel/uapi/xen/privcmd.h
index 145446b..21d9f84 100644
--- a/libc/kernel/uapi/xen/privcmd.h
+++ b/libc/kernel/uapi/xen/privcmd.h
@@ -33,13 +33,13 @@
 struct privcmd_mmap {
   int num;
   domid_t dom;
-  struct privcmd_mmap_entry __user * entry;
+  struct privcmd_mmap_entry  * entry;
 };
 struct privcmd_mmapbatch {
   int num;
   domid_t dom;
   __u64 addr;
-  xen_pfn_t __user * arr;
+  xen_pfn_t  * arr;
 };
 #define PRIVCMD_MMAPBATCH_MFN_ERROR 0xf0000000U
 #define PRIVCMD_MMAPBATCH_PAGED_ERROR 0x80000000U
@@ -47,17 +47,17 @@
   unsigned int num;
   domid_t dom;
   __u64 addr;
-  const xen_pfn_t __user * arr;
-  int __user * err;
+  const xen_pfn_t  * arr;
+  int  * err;
 };
 struct privcmd_dm_op_buf {
-  void __user * uptr;
+  void  * uptr;
   size_t size;
 };
 struct privcmd_dm_op {
   domid_t dom;
   __u16 num;
-  const struct privcmd_dm_op_buf __user * ubufs;
+  const struct privcmd_dm_op_buf  * ubufs;
 };
 struct privcmd_mmap_resource {
   domid_t dom;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 4a4e607..c75b13a 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1580,6 +1580,8 @@
     close_range;
     copy_file_range;
     memset_explicit;
+    posix_spawn_file_actions_addchdir_np;
+    posix_spawn_file_actions_addfchdir_np;
 } LIBC_T;
 
 LIBC_PRIVATE {
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 7b0f599..b06ec9e 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -496,7 +496,7 @@
   g_dispatch->free(info);
   // Purge the memory that was freed since a significant amount of
   // memory could have been allocated and freed.
-  g_dispatch->mallopt(M_PURGE, 0);
+  g_dispatch->mallopt(M_PURGE_ALL, 0);
 }
 
 size_t debug_malloc_usable_size(void* pointer) {
@@ -1123,7 +1123,7 @@
 
   // Purge the memory that was allocated and freed during this operation
   // since it can be large enough to expand the RSS significantly.
-  g_dispatch->mallopt(M_PURGE, 0);
+  g_dispatch->mallopt(M_PURGE_ALL, 0);
 }
 
 bool debug_write_malloc_leak_info(FILE* fp) {
diff --git a/libc/private/bionic_constants.h b/libc/private/bionic_constants.h
index 09294b6..d7f4474 100644
--- a/libc/private/bionic_constants.h
+++ b/libc/private/bionic_constants.h
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-#ifndef _BIONIC_CONSTANTS_H_
-#define _BIONIC_CONSTANTS_H_
+#pragma once
 
 #define NS_PER_S 1000000000
 
-// Size of the shadow call stack. This must be a power of 2.
+// Size of the shadow call stack. This can be small because these stacks only
+// contain return addresses. This must be a power of 2 so the mask trick works.
+// See the SCS commentary in pthread_internal.h for more detail.
 #define SCS_SIZE (8 * 1024)
+#define SCS_MASK (SCS_SIZE - 1)
 
 // The shadow call stack is allocated at an aligned address within a guard region of this size. The
 // guard region must be large enough that we can allocate an SCS_SIZE-aligned SCS while ensuring
 // that there is at least one guard page after the SCS so that a stack overflow results in a SIGSEGV
 // instead of corrupting the allocation that comes after it.
 #define SCS_GUARD_REGION_SIZE (16 * 1024 * 1024)
-
-#endif // _BIONIC_CONSTANTS_H_
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index a525a98..558b004 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -93,7 +93,7 @@
     ret
 1:
     neg     a0, a0
-    j       __set_errno_internal
+    tail    __set_errno_internal
 END(%(func)s)
 """
 
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index fe9e10f..d31a501 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: strptime.c,v 1.30 2019/05/12 12:49:52 schwarze Exp $ */
+/*	$OpenBSD: strptime.c,v 1.31 2023/03/02 16:21:51 millert Exp $ */
 /*	$NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $	*/
 /*-
  * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
  */
 
 #include <ctype.h>
+#include <errno.h>
+#include <limits.h>
 #include <locale.h>
-#include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 #include <time.h>
 
@@ -43,6 +45,8 @@
 // Android: this code is not pointer-sign clean.
 #pragma clang diagnostic ignored "-Wpointer-sign"
 #pragma clang diagnostic ignored "-Wunused-function"
+// Android: clang thinks people don't know && has higher precedence than ||.
+#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
 
 #define	_ctloc(x)		(_CurrentTimeLocale->x)
 
@@ -78,8 +82,8 @@
         { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
 };
 
-static	int _conv_num64(const unsigned char **, int64_t *, int64_t, int64_t);
 static	int _conv_num(const unsigned char **, int *, int, int);
+static	int epoch_to_tm(const unsigned char **, struct tm *);
 static	int leaps_thru_end_of(const int y);
 static	char *_strptime(const char *, const char *, struct tm *, int);
 static	const u_char *_find_string(const u_char *, int *, const char * const *,
@@ -351,27 +355,10 @@
 			if (!(_conv_num(&bp, &tm->tm_sec, 0, 60)))
 				return (NULL);
 			break;
-		case 's':	/* Seconds since epoch */
-			{
-				// Android change based on FreeBSD's implementation.
-				int saved_errno = errno;
-				errno = 0;
-				const unsigned char* old_bp = bp;
-				long n = strtol((const char*) bp, (char**) &bp, 10);
-				errno = saved_errno;
-				time_t t = n;
-				if (bp == old_bp || errno == ERANGE ||
-				    ((long) t) != n) return NULL;
-
-				if (localtime_r(&t, tm) == NULL) return NULL;
-
-				//int64_t i64;
-				//if (!(_conv_num64(&bp, &i64, 0, INT64_MAX)))
-				//	return (NULL);
-				//if (!gmtime_r(&i64, tm))
-				//	return (NULL);
-				fields = 0xffff;	 /* everything */
-			}
+		case 's':	/* Seconds since epoch. */
+			if (!(epoch_to_tm(&bp, tm)))
+				return (NULL);
+			fields = 0xffff;	 /* everything */
 			break;
 		case 'U':	/* The week of year, beginning on sunday. */
 		case 'W':	/* The week of year, beginning on monday. */
@@ -635,26 +622,27 @@
 }
 
 static int
-_conv_num64(const unsigned char **buf, int64_t *dest, int64_t llim, int64_t ulim)
+epoch_to_tm(const unsigned char **buf, struct tm *tm)
 {
-	int result = 0;
-	int64_t rulim = ulim;
+	int saved_errno = errno;
+	int ret = 0;
+	time_t secs;
+	char *ep;
 
-	if (**buf < '0' || **buf > '9')
-		return (0);
-
-	/* we use rulim to break out of the loop when we run out of digits */
-	do {
-		result *= 10;
-		result += *(*buf)++ - '0';
-		rulim /= 10;
-	} while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
-
-	if (result < llim || result > ulim)
-		return (0);
-
-	*dest = result;
-	return (1);
+	errno = 0;
+	secs = strtoll(*buf, &ep, 10);
+	if (*buf == (unsigned char *)ep)
+		goto done;
+	if (secs < 0 ||
+	    secs == LLONG_MAX && errno == ERANGE)
+		goto done;
+	if (localtime_r(&secs, tm) == NULL)
+		goto done;
+	ret = 1;
+done:
+	*buf = ep;
+	errno = saved_errno;
+	return (ret);
 }
 
 static const u_char *
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
index 823f2a9..f853045 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
@@ -26,7 +26,7 @@
 
 ****************************************************************/
 
-/* This is a variation on dtoa.c that converts arbitary binary
+/* This is a variation on dtoa.c that converts arbitrary binary
    floating-point formats to and from decimal notation.  It uses
    double-precision arithmetic internally, so there are still
    various #ifdefs that adapt the calculations to the native
diff --git a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
index 9a08d13..74a1695 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: setvbuf.c,v 1.14 2016/09/21 04:38:56 guenther Exp $ */
+/*	$OpenBSD: setvbuf.c,v 1.15 2022/09/28 16:44:14 gnezdo Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,6 +31,7 @@
  * SUCH DAMAGE.
  */
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "local.h"
@@ -52,7 +53,7 @@
 	 * when setting _IONBF.
 	 */
 	if (mode != _IONBF)
-		if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
+		if ((mode != _IOFBF && mode != _IOLBF) || size > INT_MAX)
 			return (EOF);
 
 	/*
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/div.c b/libc/upstream-openbsd/lib/libc/stdlib/div.c
index beaa428..5e6164f 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/div.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/div.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: div.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */
+/*	$OpenBSD: div.c,v 1.7 2022/12/27 17:10:06 jmc Exp $ */
 /*
  * Copyright (c) 1990 Regents of the University of California.
  * All rights reserved.
@@ -46,7 +46,7 @@
 	 * words, we should always truncate the quotient towards
 	 * 0, never -infinity.
 	 *
-	 * Machine division and remainer may work either way when
+	 * Machine division and remainder may work either way when
 	 * one or both of n or d is negative.  If only one is
 	 * negative and r.quot has been truncated towards -inf,
 	 * r.rem will have the same sign as denom and the opposite
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
index 15c550b..fc8e5b6 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: setenv.c,v 1.19 2016/09/21 04:38:56 guenther Exp $ */
+/*	$OpenBSD: setenv.c,v 1.20 2022/08/08 22:40:03 millert Exp $ */
 /*
  * Copyright (c) 1987 Regents of the University of California.
  * All rights reserved.
@@ -48,9 +48,10 @@
 
 	for (cp = str; *cp && *cp != '='; ++cp)
 		;
-	if (*cp != '=') {
+	if (cp == str || *cp != '=') {
+		/* '=' is the first character of string or is missing. */
 		errno = EINVAL;
-		return (-1);			/* missing `=' in string */
+		return (-1);
 	}
 
 	if (__findenv(str, (int)(cp - str), &offset) != NULL) {
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 4cdec44..fde3dfc 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -244,7 +244,7 @@
 
 genrule {
     name: "libdl.arm.map",
-    out: ["libdl.arm.map"],
+    out: ["libdl.arm.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -252,7 +252,7 @@
 
 genrule {
     name: "libdl.arm64.map",
-    out: ["libdl.arm64.map"],
+    out: ["libdl.arm64.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -260,7 +260,7 @@
 
 genrule {
     name: "libdl.riscv64.map",
-    out: ["libdl.riscv64.map"],
+    out: ["libdl.riscv64.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -268,7 +268,7 @@
 
 genrule {
     name: "libdl.x86.map",
-    out: ["libdl.x86.map"],
+    out: ["libdl.x86.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -276,7 +276,7 @@
 
 genrule {
     name: "libdl.x86_64.map",
-    out: ["libdl.x86_64.map"],
+    out: ["libdl.x86_64.map.txt"],
     srcs: ["libdl.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/libm/Android.bp b/libm/Android.bp
index cc0d666..13fbf9a 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -94,8 +94,6 @@
         "upstream-freebsd/lib/msun/src/s_cbrtf.c",
         "upstream-freebsd/lib/msun/src/s_ccosh.c",
         "upstream-freebsd/lib/msun/src/s_ccoshf.c",
-        "upstream-freebsd/lib/msun/src/s_ceil.c",
-        "upstream-freebsd/lib/msun/src/s_ceilf.c",
         "upstream-freebsd/lib/msun/src/s_cexp.c",
         "upstream-freebsd/lib/msun/src/s_cexpf.c",
         "upstream-freebsd/lib/msun/src/s_cimag.c",
@@ -130,8 +128,6 @@
         "upstream-freebsd/lib/msun/src/s_fdim.c",
         "upstream-freebsd/lib/msun/src/s_finite.c",
         "upstream-freebsd/lib/msun/src/s_finitef.c",
-        "upstream-freebsd/lib/msun/src/s_floor.c",
-        "upstream-freebsd/lib/msun/src/s_floorf.c",
         "upstream-freebsd/lib/msun/src/s_fma.c",
         "upstream-freebsd/lib/msun/src/s_fmaf.c",
         "upstream-freebsd/lib/msun/src/s_fmax.c",
@@ -282,10 +278,8 @@
         arm: {
             srcs: [
                 "arm/fenv.c",
-            ],
-            exclude_srcs: [
-                "upstream-freebsd/lib/msun/src/s_floor.c",
-                "upstream-freebsd/lib/msun/src/s_floorf.c",
+                "upstream-freebsd/lib/msun/src/s_ceil.c",
+                "upstream-freebsd/lib/msun/src/s_ceilf.c",
             ],
             instruction_set: "arm",
             pack_relocations: false,
@@ -303,10 +297,6 @@
                 "arm64/fenv.c",
             ],
             exclude_srcs: [
-                "upstream-freebsd/lib/msun/src/s_ceil.c",
-                "upstream-freebsd/lib/msun/src/s_ceilf.c",
-                "upstream-freebsd/lib/msun/src/s_floor.c",
-                "upstream-freebsd/lib/msun/src/s_floorf.c",
                 "upstream-freebsd/lib/msun/src/s_fma.c",
                 "upstream-freebsd/lib/msun/src/s_fmaf.c",
                 "upstream-freebsd/lib/msun/src/s_fmax.c",
@@ -337,11 +327,6 @@
             ],
 
             exclude_srcs: [
-                // TODO: do the rest when our clang has https://reviews.llvm.org/D136508.
-                // TODO: "upstream-freebsd/lib/msun/src/s_ceil.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_ceilf.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_floor.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_floorf.c",
                 "upstream-freebsd/lib/msun/src/s_fma.c",
                 "upstream-freebsd/lib/msun/src/s_fmaf.c",
                 "upstream-freebsd/lib/msun/src/s_fmax.c",
@@ -356,12 +341,12 @@
                 "upstream-freebsd/lib/msun/src/s_lrintf.c",
                 "upstream-freebsd/lib/msun/src/s_lround.c",
                 "upstream-freebsd/lib/msun/src/s_lroundf.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_rint.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_rintf.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_round.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_roundf.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_trunc.c",
-                // TODO: "upstream-freebsd/lib/msun/src/s_truncf.c",
+                "upstream-freebsd/lib/msun/src/s_rint.c",
+                "upstream-freebsd/lib/msun/src/s_rintf.c",
+                "upstream-freebsd/lib/msun/src/s_round.c",
+                "upstream-freebsd/lib/msun/src/s_roundf.c",
+                "upstream-freebsd/lib/msun/src/s_trunc.c",
+                "upstream-freebsd/lib/msun/src/s_truncf.c",
             ],
             version_script: ":libm.riscv64.map",
         },
@@ -373,10 +358,6 @@
                 "x86/lrintf.S",
             ],
             exclude_srcs: [
-                "upstream-freebsd/lib/msun/src/s_ceil.c",
-                "upstream-freebsd/lib/msun/src/s_ceilf.c",
-                "upstream-freebsd/lib/msun/src/s_floor.c",
-                "upstream-freebsd/lib/msun/src/s_floorf.c",
                 "upstream-freebsd/lib/msun/src/s_lrint.c",
                 "upstream-freebsd/lib/msun/src/s_lrintf.c",
                 "upstream-freebsd/lib/msun/src/s_rint.c",
@@ -400,10 +381,6 @@
                 "x86_64/lrintf.S",
             ],
             exclude_srcs: [
-                "upstream-freebsd/lib/msun/src/s_ceil.c",
-                "upstream-freebsd/lib/msun/src/s_ceilf.c",
-                "upstream-freebsd/lib/msun/src/s_floor.c",
-                "upstream-freebsd/lib/msun/src/s_floorf.c",
                 "upstream-freebsd/lib/msun/src/s_llrint.c",
                 "upstream-freebsd/lib/msun/src/s_llrintf.c",
                 "upstream-freebsd/lib/msun/src/s_lrint.c",
@@ -496,7 +473,7 @@
 
 genrule {
     name: "libm.arm.map",
-    out: ["libm.arm.map"],
+    out: ["libm.arm.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -504,7 +481,7 @@
 
 genrule {
     name: "libm.arm64.map",
-    out: ["libm.arm64.map"],
+    out: ["libm.arm64.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -512,7 +489,7 @@
 
 genrule {
     name: "libm.riscv64.map",
-    out: ["libm.riscv64.map"],
+    out: ["libm.riscv64.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -520,7 +497,7 @@
 
 genrule {
     name: "libm.x86.map",
-    out: ["libm.x86.map"],
+    out: ["libm.x86.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -528,7 +505,7 @@
 
 genrule {
     name: "libm.x86_64.map",
-    out: ["libm.x86_64.map"],
+    out: ["libm.x86_64.map.txt"],
     srcs: ["libm.map.txt"],
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 96c006d..41e145b 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -22,7 +22,7 @@
 float fabsf(float x) { return __builtin_fabsf(x); }
 long double fabsl(long double x) { return __builtin_fabsl(x); }
 
-#if defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
 float ceilf(float x) { return __builtin_ceilf(x); }
 double ceil(double x) { return __builtin_ceil(x); }
 #if defined(__ILP32__)
@@ -46,7 +46,7 @@
 }
 float floorf(float x) { return s_floorf::floorf(x); }
 double floor(double x) { return s_floor::floor(x); }
-#elif defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#else
 float floorf(float x) { return __builtin_floorf(x); }
 double floor(double x) { return __builtin_floor(x); }
 #if defined(__ILP32__)
@@ -79,7 +79,7 @@
 long long llroundf(float x) { return __builtin_llroundf(x); }
 #endif
 
-#if defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
 float rintf(float x) { return __builtin_rintf(x); }
 double rint(double x) { return __builtin_rint(x); }
 #if defined(__ILP32__)
@@ -87,7 +87,7 @@
 #endif
 #endif
 
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__riscv)
 float roundf(float x) { return __builtin_roundf(x); }
 double round(double x) { return __builtin_round(x); }
 #endif
@@ -98,7 +98,7 @@
 __weak_reference(sqrt, sqrtl);
 #endif
 
-#if defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__aarch64__) || defined(__riscv) || defined(__i386__) || defined(__x86_64__)
 float truncf(float x) { return __builtin_truncf(x); }
 double trunc(double x) { return __builtin_trunc(x); }
 #if defined(__ILP32__)
diff --git a/linker/Android.bp b/linker/Android.bp
index 83077c6..020bd7d 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -374,6 +374,11 @@
     ],
 
     symlinks: ["linker_asan"],
+    arch: {
+        arm64: {
+            symlinks: ["linker_hwasan"],
+        },
+    },
     multilib: {
         lib64: {
             suffix: "64",
diff --git a/linker/arch/arm64/tlsdesc_resolver.S b/linker/arch/arm64/tlsdesc_resolver.S
index 96eff8e..ad155e2 100644
--- a/linker/arch/arm64/tlsdesc_resolver.S
+++ b/linker/arch/arm64/tlsdesc_resolver.S
@@ -58,9 +58,9 @@
   cmp x21, x22
   b.lo .fallback
 
-  ldr x21, [x0, #8]             // TlsIndex::module
+  ldr x21, [x0, #8]             // TlsIndex::module_id
   ldr x22, [x0, #16]            // TlsIndex::offset
-  ldr x21, [x20, x21, lsl #3]   // TlsDtv::modules[module]
+  ldr x21, [x20, x21, lsl #3]   // TlsDtv::modules[module_id]
   cbz x21, .fallback
   add x0, x21, x22
   sub x0, x0, x19
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 6246f8c..17b574f 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/auxv.h>
 #include <sys/mman.h>
 #include <sys/param.h>
 #include <sys/vfs.h>
@@ -133,6 +134,36 @@
   nullptr
 };
 
+#if defined(__aarch64__)
+static const char* const kHwasanSystemLibDir  = "/system/lib64/hwasan";
+static const char* const kHwasanOdmLibDir     = "/odm/lib64/hwasan";
+static const char* const kHwasanVendorLibDir  = "/vendor/lib64/hwasan";
+
+// HWASan is only supported on aarch64.
+static const char* const kHwsanDefaultLdPaths[] = {
+  kHwasanSystemLibDir,
+  kSystemLibDir,
+  kHwasanOdmLibDir,
+  kOdmLibDir,
+  kHwasanVendorLibDir,
+  kVendorLibDir,
+  nullptr
+};
+
+// Is HWASAN enabled?
+static bool g_is_hwasan = false;
+#else
+static const char* const kHwsanDefaultLdPaths[] = {
+  kSystemLibDir,
+  kOdmLibDir,
+  kVendorLibDir,
+  nullptr
+};
+
+// Never any HWASan. Help the compiler remove the code we don't need.
+constexpr bool g_is_hwasan = false;
+#endif
+
 // Is ASAN enabled?
 static bool g_is_asan = false;
 
@@ -2134,26 +2165,46 @@
   }
   // End Workaround for dlopen(/system/lib/<soname>) when .so is in /apex.
 
-  std::string asan_name_holder;
+  std::string translated_name_holder;
 
+  assert(!g_is_hwasan || !g_is_asan);
   const char* translated_name = name;
   if (g_is_asan && translated_name != nullptr && translated_name[0] == '/') {
     char original_path[PATH_MAX];
     if (realpath(name, original_path) != nullptr) {
-      asan_name_holder = std::string(kAsanLibDirPrefix) + original_path;
-      if (file_exists(asan_name_holder.c_str())) {
+      translated_name_holder = std::string(kAsanLibDirPrefix) + original_path;
+      if (file_exists(translated_name_holder.c_str())) {
         soinfo* si = nullptr;
         if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
           PRINT("linker_asan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
-                asan_name_holder.c_str());
+                translated_name_holder.c_str());
         } else {
           PRINT("linker_asan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
-          translated_name = asan_name_holder.c_str();
+          translated_name = translated_name_holder.c_str();
+        }
+      }
+    }
+  } else if (g_is_hwasan && translated_name != nullptr && translated_name[0] == '/') {
+    char original_path[PATH_MAX];
+    if (realpath(name, original_path) != nullptr) {
+      // Keep this the same as CreateHwasanPath in system/linkerconfig/modules/namespace.cc.
+      std::string path(original_path);
+      auto slash = path.rfind('/');
+      if (slash != std::string::npos || slash != path.size() - 1) {
+        translated_name_holder = path.substr(0, slash) + "/hwasan" + path.substr(slash);
+      }
+      if (!translated_name_holder.empty() && file_exists(translated_name_holder.c_str())) {
+        soinfo* si = nullptr;
+        if (find_loaded_library_by_realpath(ns, original_path, true, &si)) {
+          PRINT("linker_hwasan dlopen NOT translating \"%s\" -> \"%s\": library already loaded", name,
+                translated_name_holder.c_str());
+        } else {
+          PRINT("linker_hwasan dlopen translating \"%s\" -> \"%s\"", name, translated_name);
+          translated_name = translated_name_holder.c_str();
         }
       }
     }
   }
-
   ProtectedDataGuard guard;
   soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
   loading_trace.End();
@@ -3142,6 +3193,14 @@
       case DT_AARCH64_VARIANT_PCS:
         // Ignored: AArch64 processor-specific dynamic array tags.
         break;
+      // TODO(mitchp): Add support to libc_init_mte to use these dynamic array entries instead of
+      // the Android-specific ELF note.
+      case DT_AARCH64_MEMTAG_MODE:
+      case DT_AARCH64_MEMTAG_HEAP:
+      case DT_AARCH64_MEMTAG_STACK:
+      case DT_AARCH64_MEMTAG_GLOBALS:
+      case DT_AARCH64_MEMTAG_GLOBALSSZ:
+        break;
 #endif
 
       default:
@@ -3327,9 +3386,10 @@
   return true;
 }
 
-static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan) {
+static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan, bool is_hwasan) {
   g_default_namespace.set_isolated(false);
-  auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : kDefaultLdPaths;
+  auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : (
+    is_hwasan ? kHwsanDefaultLdPaths : kDefaultLdPaths);
 
   char real_path[PATH_MAX];
   std::vector<std::string> ld_default_paths;
@@ -3433,6 +3493,7 @@
   return kLdConfigFilePath;
 }
 
+
 std::vector<android_namespace_t*> init_default_namespaces(const char* executable_path) {
   g_default_namespace.set_name("(default)");
 
@@ -3446,6 +3507,16 @@
               (strcmp(bname, "linker_asan") == 0 ||
                strcmp(bname, "linker_asan64") == 0);
 
+#if defined(__aarch64__)
+  // HWASan is only supported on AArch64.
+  // The AT_SECURE restriction is because this is a debug feature that does
+  // not need to work on secure binaries, it doesn't hurt to disallow the
+  // environment variable for them, as it impacts the program execution.
+  char* hwasan_env = getenv("LD_HWASAN");
+  g_is_hwasan = (bname != nullptr &&
+              strcmp(bname, "linker_hwasan64") == 0) ||
+              (hwasan_env != nullptr && !getauxval(AT_SECURE) && strcmp(hwasan_env, "1") == 0);
+#endif
   const Config* config = nullptr;
 
   {
@@ -3453,7 +3524,7 @@
     INFO("[ Reading linker config \"%s\" ]", ld_config_file_path.c_str());
     ScopedTrace trace(("linker config " + ld_config_file_path).c_str());
     std::string error_msg;
-    if (!Config::read_binary_config(ld_config_file_path.c_str(), executable_path, g_is_asan,
+    if (!Config::read_binary_config(ld_config_file_path.c_str(), executable_path, g_is_asan, g_is_hwasan,
                                     &config, &error_msg)) {
       if (!error_msg.empty()) {
         DL_WARN("Warning: couldn't read '%s' for '%s' (using default configuration instead): %s",
@@ -3464,7 +3535,7 @@
   }
 
   if (config == nullptr) {
-    return init_default_namespace_no_config(g_is_asan);
+    return init_default_namespace_no_config(g_is_asan, g_is_hwasan);
   }
 
   const auto& namespace_configs = config->namespace_configs();
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 1771e87..ad40c50 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -463,6 +463,7 @@
 bool Config::read_binary_config(const char* ld_config_file_path,
                                       const char* binary_realpath,
                                       bool is_asan,
+                                      bool is_hwasan,
                                       const Config** config,
                                       std::string* error_msg) {
   g_config.clear();
@@ -579,6 +580,8 @@
     // these are affected by is_asan flag
     if (is_asan) {
       property_name_prefix += ".asan";
+    } else if (is_hwasan) {
+      property_name_prefix += ".hwasan";
     }
 
     // search paths are resolved (canonicalized). This is required mainly for
diff --git a/linker/linker_config.h b/linker/linker_config.h
index fe23ec1..09fea45 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -166,6 +166,7 @@
   static bool read_binary_config(const char* ld_config_file_path,
                                  const char* binary_realpath,
                                  bool is_asan,
+                                 bool is_hwasan,
                                  const Config** config,
                                  std::string* error_msg);
 
diff --git a/linker/linker_config_test.cpp b/linker/linker_config_test.cpp
index acdf641..7e947f3 100644
--- a/linker/linker_config_test.cpp
+++ b/linker/linker_config_test.cpp
@@ -40,6 +40,7 @@
 #include <android-base/file.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
+#include <vector>
 
 #if defined(__LP64__)
 #define ARCH_SUFFIX "64"
@@ -64,6 +65,10 @@
   "namespace.default.asan.search.paths = /data\n"
   "namespace.default.asan.search.paths += /vendor/${LIB}\n"
   "namespace.default.asan.permitted.paths = /data:/vendor\n"
+  "namespace.default.hwasan.search.paths = /vendor/${LIB}/hwasan\n"
+  "namespace.default.hwasan.search.paths += /vendor/${LIB}\n"
+  "namespace.default.hwasan.permitted.paths = /vendor/${LIB}/hwasan\n"
+  "namespace.default.hwasan.permitted.paths += /vendor/${LIB}\n"
   "namespace.default.links = system\n"
   "namespace.default.links += vndk\n"
   // irregular whitespaces are added intentionally for testing purpose
@@ -77,11 +82,17 @@
   "namespace.system.permitted.paths = /system/${LIB}\n"
   "namespace.system.asan.search.paths = /data:/system/${LIB}\n"
   "namespace.system.asan.permitted.paths = /data:/system\n"
+  "namespace.system.hwasan.search.paths = /system/${LIB}/hwasan\n"
+  "namespace.system.hwasan.search.paths += /system/${LIB}\n"
+  "namespace.system.hwasan.permitted.paths = /system/${LIB}/hwasan\n"
+  "namespace.system.hwasan.permitted.paths += /system/${LIB}\n"
   "namespace.vndk.isolated = tr\n"
   "namespace.vndk.isolated += ue\n" // should be ignored and return as 'false'.
   "namespace.vndk.search.paths = /system/${LIB}/vndk\n"
   "namespace.vndk.asan.search.paths = /data\n"
   "namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
+  "namespace.vndk.hwasan.search.paths = /system/${LIB}/vndk/hwasan\n"
+  "namespace.vndk.hwasan.search.paths += /system/${LIB}/vndk\n"
   "namespace.vndk.links = default\n"
   "namespace.vndk.link.default.allow_all_shared_libs = true\n"
   "namespace.vndk.link.vndk_in_system.allow_all_shared_libs = true\n"
@@ -107,26 +118,50 @@
   return resolved_paths;
 }
 
-static void run_linker_config_smoke_test(bool is_asan) {
-  const std::vector<std::string> kExpectedDefaultSearchPath =
-      resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/vendor/lib" ARCH_SUFFIX }) :
-                              std::vector<std::string>({ "/vendor/lib" ARCH_SUFFIX }));
+enum class SmokeTestType {
+  None,
+  Asan,
+  Hwasan,
+};
 
-  const std::vector<std::string> kExpectedDefaultPermittedPath =
-      resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/vendor" }) :
-                              std::vector<std::string>({ "/vendor/lib" ARCH_SUFFIX }));
+static void run_linker_config_smoke_test(SmokeTestType type) {
+  std::vector<std::string> expected_default_search_path;
+  std::vector<std::string> expected_default_permitted_path;
+  std::vector<std::string> expected_system_search_path;
+  std::vector<std::string> expected_system_permitted_path;
+  std::vector<std::string> expected_vndk_search_path;
 
-  const std::vector<std::string> kExpectedSystemSearchPath =
-      resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system/lib" ARCH_SUFFIX }) :
-                              std::vector<std::string>({ "/system/lib" ARCH_SUFFIX }));
+  switch (type) {
+    case SmokeTestType::None:
+      expected_default_search_path = { "/vendor/lib" ARCH_SUFFIX };
+      expected_default_permitted_path = { "/vendor/lib" ARCH_SUFFIX };
+      expected_system_search_path = { "/system/lib" ARCH_SUFFIX };
+      expected_system_permitted_path = { "/system/lib" ARCH_SUFFIX };
+      expected_vndk_search_path = { "/system/lib" ARCH_SUFFIX "/vndk" };
+      break;
+    case SmokeTestType::Asan:
+      expected_default_search_path = { "/data", "/vendor/lib" ARCH_SUFFIX };
+      expected_default_permitted_path = { "/data", "/vendor" };
+      expected_system_search_path = { "/data", "/system/lib" ARCH_SUFFIX };
+      expected_system_permitted_path = { "/data", "/system" };
+      expected_vndk_search_path = { "/data", "/system/lib" ARCH_SUFFIX "/vndk" };
+      break;
+    case SmokeTestType::Hwasan:
+      expected_default_search_path = { "/vendor/lib" ARCH_SUFFIX "/hwasan", "/vendor/lib" ARCH_SUFFIX };
+      expected_default_permitted_path = { "/vendor/lib" ARCH_SUFFIX "/hwasan", "/vendor/lib" ARCH_SUFFIX };
+      expected_system_search_path = { "/system/lib" ARCH_SUFFIX "/hwasan" , "/system/lib" ARCH_SUFFIX };
+      expected_system_permitted_path = { "/system/lib" ARCH_SUFFIX "/hwasan", "/system/lib" ARCH_SUFFIX };
+      expected_vndk_search_path = { "/system/lib" ARCH_SUFFIX "/vndk/hwasan", "/system/lib" ARCH_SUFFIX "/vndk" };
+      break;
+  }
 
-  const std::vector<std::string> kExpectedSystemPermittedPath =
-      resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system" }) :
-                              std::vector<std::string>({ "/system/lib" ARCH_SUFFIX }));
-
-  const std::vector<std::string> kExpectedVndkSearchPath =
-      resolve_paths(is_asan ? std::vector<std::string>({ "/data", "/system/lib" ARCH_SUFFIX "/vndk"}) :
-                              std::vector<std::string>({ "/system/lib" ARCH_SUFFIX "/vndk"}));
+  expected_default_search_path = resolve_paths(expected_default_search_path);
+  // expected_default_permitted_path is skipped on purpose, permitted paths
+  // do not get resolved in linker_config.cpp
+  expected_system_search_path = resolve_paths(expected_system_search_path);
+  // expected_system_permitted_path is skipped on purpose, permitted paths
+  // do not get resolved in linker_config.cpp
+  expected_vndk_search_path = resolve_paths(expected_vndk_search_path);
 
   TemporaryFile tmp_file;
   close(tmp_file.fd);
@@ -149,7 +184,8 @@
   std::string error_msg;
   ASSERT_TRUE(Config::read_binary_config(tmp_file.path,
                                          executable_path.c_str(),
-                                         is_asan,
+                                         type == SmokeTestType::Asan,
+                                         type == SmokeTestType::Hwasan,
                                          &config,
                                          &error_msg)) << error_msg;
   ASSERT_TRUE(config != nullptr);
@@ -162,8 +198,8 @@
 
   ASSERT_TRUE(default_ns_config->isolated());
   ASSERT_FALSE(default_ns_config->visible());
-  ASSERT_EQ(kExpectedDefaultSearchPath, default_ns_config->search_paths());
-  ASSERT_EQ(kExpectedDefaultPermittedPath, default_ns_config->permitted_paths());
+  ASSERT_EQ(expected_default_search_path, default_ns_config->search_paths());
+  ASSERT_EQ(expected_default_permitted_path, default_ns_config->permitted_paths());
 
   const auto& default_ns_links = default_ns_config->links();
   ASSERT_EQ(2U, default_ns_links.size());
@@ -202,14 +238,14 @@
 
   ASSERT_TRUE(ns_system->isolated());
   ASSERT_TRUE(ns_system->visible());
-  ASSERT_EQ(kExpectedSystemSearchPath, ns_system->search_paths());
-  ASSERT_EQ(kExpectedSystemPermittedPath, ns_system->permitted_paths());
+  ASSERT_EQ(expected_system_search_path, ns_system->search_paths());
+  ASSERT_EQ(expected_system_permitted_path, ns_system->permitted_paths());
 
   ASSERT_TRUE(ns_vndk != nullptr) << "vndk namespace was not found";
 
   ASSERT_FALSE(ns_vndk->isolated()); // malformed bool property
   ASSERT_FALSE(ns_vndk->visible()); // undefined bool property
-  ASSERT_EQ(kExpectedVndkSearchPath, ns_vndk->search_paths());
+  ASSERT_EQ(expected_vndk_search_path, ns_vndk->search_paths());
 
   const auto& ns_vndk_links = ns_vndk->links();
   ASSERT_EQ(1U, ns_vndk_links.size());
@@ -223,11 +259,15 @@
 }
 
 TEST(linker_config, smoke) {
-  run_linker_config_smoke_test(false);
+  run_linker_config_smoke_test(SmokeTestType::None);
 }
 
 TEST(linker_config, asan_smoke) {
-  run_linker_config_smoke_test(true);
+  run_linker_config_smoke_test(SmokeTestType::Asan);
+}
+
+TEST(linker_config, hwasan_smoke) {
+  run_linker_config_smoke_test(SmokeTestType::Hwasan);
 }
 
 TEST(linker_config, ns_link_shared_libs_invalid_settings) {
@@ -259,6 +299,7 @@
   ASSERT_FALSE(Config::read_binary_config(tmp_file.path,
                                           executable_path.c_str(),
                                           false,
+                                          false,
                                           &config,
                                           &error_msg));
   ASSERT_TRUE(config == nullptr);
@@ -304,6 +345,7 @@
   ASSERT_TRUE(Config::read_binary_config(tmp_file.path,
                                          executable_path.c_str(),
                                          false,
+                                         false,
                                          &config,
                                          &error_msg)) << error_msg;
 
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 833157e..26e2228 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -43,7 +43,6 @@
 #include "linker_tls.h"
 #include "linker_utils.h"
 
-#include "private/bionic_auxv.h"
 #include "private/bionic_call_ifunc_resolver.h"
 #include "private/bionic_globals.h"
 #include "private/bionic_tls.h"
diff --git a/tests/Android.bp b/tests/Android.bp
index 8c6057f..1be1ec3 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -66,18 +66,20 @@
         "libcutils_headers",
         "gwp_asan_headers"
     ],
-    // Ensure that the tests exercise shadow call stack support and
-    // the hint space PAC/BTI instructions.
+    stl: "libc++",
+
+    // Ensure that the tests exercise shadow call stack support.
+    // We don't use `scs: true` here because that would give us a second
+    // variant of this library where we actually just want to say "this
+    // library should always be built this way".
     arch: {
         arm64: {
-            cflags: [
-                "-fsanitize=shadow-call-stack",
-                // Disable this option for now: see b/151372823
-                //"-mbranch-protection=standard",
-            ],
+            cflags: ["-fsanitize=shadow-call-stack"],
+        },
+        riscv64: {
+            cflags: ["-fsanitize=shadow-call-stack"],
         },
     },
-    stl: "libc++",
     sanitize: {
         address: false,
     },
@@ -512,6 +514,7 @@
         "unistd_test.cpp",
         "utils.cpp",
         "utmp_test.cpp",
+        "utmpx_test.cpp",
         "wchar_test.cpp",
         "wctype_test.cpp",
     ],
@@ -538,6 +541,10 @@
 
                 // unsupported relocation type 37
                 "ifunc_test.cpp",
+
+                // musl #defines utmp to utmpx, causing a collision with
+                // utmpx_test.cpp
+                "utmp_test.cpp",
             ],
         },
     },
@@ -1109,6 +1116,30 @@
 }
 
 cc_test {
+    name: "hwasan_test",
+    enabled: false,
+    // This does not use bionic_tests_defaults because it is not supported on
+    // host.
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+    sanitize: {
+        hwaddress: true,
+    },
+    srcs: [
+        "hwasan_test.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+    ],
+    data_libs: ["libtest_simple_hwasan", "libtest_simple_hwasan_nohwasan"],
+    header_libs: ["bionic_libc_platform_headers"],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
     name: "bionic-stress-tests",
     defaults: [
         "bionic_tests_defaults",
diff --git a/tests/NOTICE b/tests/NOTICE
index 167f90b..cc99d20 100644
--- a/tests/NOTICE
+++ b/tests/NOTICE
@@ -426,3 +426,31 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2023 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.
+
+-------------------------------------------------------------------
+
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index f52387e..dc4db07 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -16,6 +16,8 @@
 
 #include <gtest/gtest.h>
 
+#include <errno.h>
+
 #if defined(__BIONIC__)
 #include <async_safe/log.h>
 #endif // __BIONIC__
@@ -227,3 +229,19 @@
   GTEST_SKIP() << "bionic-only test";
 #endif // __BIONIC__
 }
+
+// Verify that using %m is never cut off.
+TEST(async_safe_format_buffer, percent_m_fits_in_buffer) {
+#if defined(__BIONIC__)
+  for (int i = 0; i < 256; i++) {
+    errno = i;
+    char async_buf[256];
+    async_safe_format_buffer(async_buf, sizeof(async_buf), "%m");
+    char strerror_buf[1024];
+    strerror_r(errno, strerror_buf, sizeof(strerror_buf));
+    ASSERT_STREQ(strerror_buf, async_buf);
+  }
+#else   // __BIONIC__
+  GTEST_SKIP() << "bionic-only test";
+#endif  // __BIONIC__
+}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 3f70279..b68ee7b 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -971,9 +971,15 @@
 }
 
 #define ALTERNATE_PATH_TO_SYSTEM_LIB "/system/lib64/" ABI_STRING "/"
+#if __has_feature(hwaddress_sanitizer)
+#define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "hwasan/libc.so"
+#define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/hwasan/libc.so"
+#define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "hwasan/libc.so"
+#else
 #define PATH_TO_LIBC PATH_TO_SYSTEM_LIB "libc.so"
 #define PATH_TO_BOOTSTRAP_LIBC PATH_TO_SYSTEM_LIB "bootstrap/libc.so"
 #define ALTERNATE_PATH_TO_LIBC ALTERNATE_PATH_TO_SYSTEM_LIB "libc.so"
+#endif
 
 TEST(dlfcn, dladdr_libc) {
 #if defined(__GLIBC__)
@@ -981,24 +987,25 @@
 #endif
 
   Dl_info info;
-  void* addr = reinterpret_cast<void*>(puts); // well-known libc function
+  void* addr = reinterpret_cast<void*>(puts);  // An arbitrary libc function.
   ASSERT_TRUE(dladdr(addr, &info) != 0);
 
-  char libc_realpath[PATH_MAX];
-
   // Check if libc is in canonical path or in alternate path.
+  const char* expected_path;
   if (strncmp(ALTERNATE_PATH_TO_SYSTEM_LIB,
               info.dli_fname,
               sizeof(ALTERNATE_PATH_TO_SYSTEM_LIB) - 1) == 0) {
     // Platform with emulated architecture.  Symlink on ARC++.
-    ASSERT_TRUE(realpath(ALTERNATE_PATH_TO_LIBC, libc_realpath) == libc_realpath);
+    expected_path = ALTERNATE_PATH_TO_LIBC;
   } else if (strncmp(PATH_TO_BOOTSTRAP_LIBC, info.dli_fname,
                      sizeof(PATH_TO_BOOTSTRAP_LIBC) - 1) == 0) {
-    ASSERT_TRUE(realpath(PATH_TO_BOOTSTRAP_LIBC, libc_realpath) == libc_realpath);
+    expected_path = PATH_TO_BOOTSTRAP_LIBC;
   } else {
     // /system/lib is symlink when this test is executed on host.
-    ASSERT_TRUE(realpath(PATH_TO_LIBC, libc_realpath) == libc_realpath);
+    expected_path = PATH_TO_LIBC;
   }
+  char libc_realpath[PATH_MAX];
+  ASSERT_TRUE(realpath(expected_path, libc_realpath) != nullptr) << strerror(errno);
 
   ASSERT_STREQ(libc_realpath, info.dli_fname);
   // TODO: add check for dfi_fbase
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index 8b12bec..c31f48c 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -143,6 +143,16 @@
   EXPECT_DEATH({ *x = 7; }, "");
 }
 
+// A weaker version of the above tests, only checking that GWP-ASan is enabled
+// for any pointer, not *our* pointer. This allows us to test the system_default
+// sysprops without potentially OOM-ing other random processes:
+// b/273904016#comment5
+TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled_weaker) {
+  std::string maps;
+  EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
+  EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
+}
+
 TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_disabled) {
   std::string maps;
   EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
@@ -184,32 +194,6 @@
   RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
 }
 
-TEST(gwp_asan_integration, sysprops_system) {
-  // Do not override HWASan with GWP ASan.
-  SKIP_WITH_HWASAN;
-
-  SyspropRestorer restorer;
-
-  __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
-  __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
-  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
-
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
-}
-
-TEST(gwp_asan_integration, sysprops_persist_system) {
-  // Do not override HWASan with GWP ASan.
-  SKIP_WITH_HWASAN;
-
-  SyspropRestorer restorer;
-
-  __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "1");
-  __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "1");
-  __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "40000");
-
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
-}
-
 TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
   // Do not override HWASan with GWP ASan.
   SKIP_WITH_HWASAN;
@@ -218,13 +202,18 @@
 
   __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
   __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "1");
-  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "40000");
+  // Note, any processes launched elsewhere on the system right now will have
+  // GWP-ASan enabled. Make sure that we only use a single slot, otherwise we
+  // could end up causing said badly-timed processes to use up to 163MiB extra
+  // penalty that 40,000 allocs would cause. See b/273904016#comment5 for more
+  // context.
+  __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "1");
 
   __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "0");
   __system_property_set("persist.libc.debug.gwp_asan.process_sampling.system_default", "0");
   __system_property_set("persist.libc.debug.gwp_asan.max_allocs.system_default", "0");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled_weaker");
 }
 
 TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
diff --git a/tests/headers/posix/utmpx_h.c b/tests/headers/posix/utmpx_h.c
new file mode 100644
index 0000000..44dfac9
--- /dev/null
+++ b/tests/headers/posix/utmpx_h.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <utmpx.h>
+
+#include "header_checks.h"
+
+static void utmpx_h() {
+  TYPE(struct utmpx);
+  STRUCT_MEMBER_ARRAY(struct utmpx, char/*[]*/, ut_user);
+  STRUCT_MEMBER_ARRAY(struct utmpx, char/*[]*/, ut_id);
+  STRUCT_MEMBER_ARRAY(struct utmpx, char/*[]*/, ut_line);
+  STRUCT_MEMBER(struct utmpx, pid_t, ut_pid);
+  STRUCT_MEMBER(struct utmpx, short, ut_type);
+#if !defined(__GLIBC__)
+  // POSIX says struct timeval, but glibc has an anonymous struct.
+  STRUCT_MEMBER(struct utmpx, struct timeval, ut_tv);
+#endif
+
+  TYPE(pid_t);
+  TYPE(struct timeval);
+
+  MACRO(EMPTY);
+  MACRO(BOOT_TIME);
+  MACRO(OLD_TIME);
+  MACRO(NEW_TIME);
+  MACRO(USER_PROCESS);
+  MACRO(INIT_PROCESS);
+  MACRO(LOGIN_PROCESS);
+  MACRO(DEAD_PROCESS);
+
+  FUNCTION(endutxent, void (*f)(void));
+  FUNCTION(getutxent, struct utmpx* (*f)(void));
+  FUNCTION(getutxid, struct utmpx* (*f)(const struct utmpx*));
+  FUNCTION(getutxline, struct utmpx* (*f)(const struct utmpx*));
+  FUNCTION(pututxline, struct utmpx* (*f)(const struct utmpx*));
+  FUNCTION(setutxent, void (*f)(void));
+}
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index ae678b7..917be37 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -26,6 +26,7 @@
 
 #include "SignalUtils.h"
 
+#include <android-base/properties.h>
 #include <android-base/test_utils.h>
 #include <bionic/malloc_tagged_pointers.h>
 
@@ -223,6 +224,9 @@
 TEST_P(MemtagNoteTest, SEGV) {
 #if defined(__BIONIC__) && defined(__aarch64__)
   SKIP_WITH_NATIVE_BRIDGE;  // http://b/242170715
+  if (android::base::GetProperty("persist.arm64.memtag.default", "") != "") {
+    GTEST_SKIP() << "not supported when overriding memtag mode with property";
+  }
   // Note that we do not check running_with_hwasan() - what matters here is whether the test binary
   // itself is built with HWASan.
   bool withHWASAN = __has_feature(hwaddress_sanitizer);
diff --git a/tests/hwasan_test.cpp b/tests/hwasan_test.cpp
new file mode 100644
index 0000000..5c21495
--- /dev/null
+++ b/tests/hwasan_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 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 <dlfcn.h>
+#include <stdlib.h>
+
+#include <gtest/gtest.h>
+
+#include <android-base/silent_death_test.h>
+#include <android-base/test_utils.h>
+
+using HwasanDeathTest = SilentDeathTest;
+
+TEST_F(HwasanDeathTest, UseAfterFree) {
+  EXPECT_DEATH(
+      {
+        void* m = malloc(1);
+        volatile char* x = const_cast<volatile char*>(reinterpret_cast<char*>(m));
+        *x = 1;
+        free(m);
+        *x = 2;
+      },
+      "use-after-free");
+}
+
+TEST_F(HwasanDeathTest, OutOfBounds) {
+  EXPECT_DEATH(
+      {
+        void* m = malloc(1);
+        volatile char* x = const_cast<volatile char*>(reinterpret_cast<char*>(m));
+        x[1] = 1;
+      },
+      "buffer-overflow");
+}
+
+// Check whether dlopen of /foo/bar.so checks /foo/hwasan/bar.so first.
+TEST(HwasanTest, DlopenAbsolutePath) {
+  std::string path = android::base::GetExecutableDirectory() + "/libtest_simple_hwasan.so";
+  ASSERT_EQ(0, access(path.c_str(), F_OK));  // Verify test setup.
+  std::string hwasan_path =
+      android::base::GetExecutableDirectory() + "/hwasan/libtest_simple_hwasan.so";
+  ASSERT_EQ(0, access(hwasan_path.c_str(), F_OK));  // Verify test setup.
+
+  void* handle = dlopen(path.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr);
+  uint32_t* compiled_with_hwasan =
+      reinterpret_cast<uint32_t*>(dlsym(handle, "dlopen_testlib_compiled_with_hwasan"));
+  EXPECT_TRUE(*compiled_with_hwasan);
+  dlclose(handle);
+}
+
+TEST(HwasanTest, IsRunningWithHWasan) {
+  EXPECT_TRUE(running_with_hwasan());
+}
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 8ae2257..a2fbe55 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -243,6 +243,38 @@
 }
 
 // -----------------------------------------------------------------------------
+// Libraries used by hwasan_test
+// -----------------------------------------------------------------------------
+cc_test_library {
+    name: "libtest_simple_hwasan",
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+    sanitize: {
+        hwaddress: true,
+    },
+    relative_install_path: "hwasan",
+    enabled: false,
+    srcs: ["dlopen_testlib_simple_hwasan.cpp"],
+}
+
+cc_test_library {
+    // A weird name. This is the vanilla (non-HWASan) copy of the library that
+    // is used for the hwasan test.
+    name: "libtest_simple_hwasan_nohwasan",
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+    stem: "libtest_simple_hwasan",
+    enabled: false,
+    srcs: ["dlopen_testlib_simple_hwasan.cpp"],
+}
+
+// -----------------------------------------------------------------------------
 // Library used by dlext direct unload on the namespace boundary tests
 // -----------------------------------------------------------------------------
 cc_test_library {
diff --git a/tests/libs/dlopen_testlib_simple_hwasan.cpp b/tests/libs/dlopen_testlib_simple_hwasan.cpp
new file mode 100644
index 0000000..b92e05f
--- /dev/null
+++ b/tests/libs/dlopen_testlib_simple_hwasan.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 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 <stdint.h>
+
+#if __has_feature(hwaddress_sanitizer)
+extern "C" uint32_t dlopen_testlib_compiled_with_hwasan = true;
+#else
+extern "C" uint32_t dlopen_testlib_compiled_with_hwasan = false;
+#endif
+
+extern "C" bool dlopen_testlib_simple_hwasan_func() {
+  return true;
+}
diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp
index b4da6de..a220c83 100644
--- a/tests/locale_test.cpp
+++ b/tests/locale_test.cpp
@@ -79,9 +79,12 @@
 }
 
 TEST(locale, newlocale_NULL_locale_name) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   errno = 0;
   EXPECT_EQ(nullptr, newlocale(LC_ALL, nullptr, nullptr));
   EXPECT_EQ(EINVAL, errno);
+#pragma clang diagnostic pop
 }
 
 TEST(locale, newlocale_bad_locale_name) {
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 63ad99d..22905f4 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -36,7 +36,10 @@
 #include <algorithm>
 #include <atomic>
 #include <functional>
+#include <string>
 #include <thread>
+#include <unordered_map>
+#include <utility>
 #include <vector>
 
 #include <tinyxml2.h>
@@ -695,6 +698,44 @@
 #endif
 }
 
+TEST(malloc, mallopt_purge_all) {
+#if defined(__BIONIC__)
+  SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
+  errno = 0;
+  ASSERT_EQ(1, mallopt(M_PURGE_ALL, 0));
+#else
+  GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
+// Verify that all of the mallopt values are unique.
+TEST(malloc, mallopt_unique_params) {
+#if defined(__BIONIC__)
+  std::vector<std::pair<int, std::string>> params{
+      std::make_pair(M_DECAY_TIME, "M_DECAY_TIME"),
+      std::make_pair(M_PURGE, "M_PURGE"),
+      std::make_pair(M_PURGE_ALL, "M_PURGE_ALL"),
+      std::make_pair(M_MEMTAG_TUNING, "M_MEMTAG_TUNING"),
+      std::make_pair(M_THREAD_DISABLE_MEM_INIT, "M_THREAD_DISABLE_MEM_INIT"),
+      std::make_pair(M_CACHE_COUNT_MAX, "M_CACHE_COUNT_MAX"),
+      std::make_pair(M_CACHE_SIZE_MAX, "M_CACHE_SIZE_MAX"),
+      std::make_pair(M_TSDS_COUNT_MAX, "M_TSDS_COUNT_MAX"),
+      std::make_pair(M_BIONIC_ZERO_INIT, "M_BIONIC_ZERO_INIT"),
+      std::make_pair(M_BIONIC_SET_HEAP_TAGGING_LEVEL, "M_BIONIC_SET_HEAP_TAGGING_LEVEL"),
+  };
+
+  std::unordered_map<int, std::string> all_params;
+  for (const auto& param : params) {
+    EXPECT_TRUE(all_params.count(param.first) == 0)
+        << "mallopt params " << all_params[param.first] << " and " << param.second
+        << " have the same value " << param.first;
+    all_params.insert(param);
+  }
+#else
+  GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
 #if defined(__BIONIC__)
 static void GetAllocatorVersion(bool* allocator_scudo) {
   TemporaryFile tf;
@@ -1572,6 +1613,7 @@
 }
 
 // Verify that small and medium allocations are always zero.
+// @CddTest = 9.7/C-4-1
 TEST(malloc, zeroed_allocations_small_medium_sizes) {
 #if !defined(__BIONIC__)
   GTEST_SKIP() << "Only valid on bionic";
@@ -1601,6 +1643,7 @@
 }
 
 // Verify that large allocations are always zero.
+// @CddTest = 9.7/C-4-1
 TEST(malloc, zeroed_allocations_large_sizes) {
 #if !defined(__BIONIC__)
   GTEST_SKIP() << "Only valid on bionic";
@@ -1629,6 +1672,8 @@
       "posix_memalign", test_sizes, kMaxAllocations);
 }
 
+// Verify that reallocs are zeroed when expanded.
+// @CddTest = 9.7/C-4-1
 TEST(malloc, zeroed_allocations_realloc) {
 #if !defined(__BIONIC__)
   GTEST_SKIP() << "Only valid on bionic";
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 03e8062..fa1a07f 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -303,5 +303,8 @@
 }
 
 TEST(sched, sched_getaffinity_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   ASSERT_EQ(-1, sched_getaffinity(getpid(), 0, nullptr));
+#pragma clang diagnostic pop
 }
diff --git a/tests/scs_test.cpp b/tests/scs_test.cpp
index 24cb347..0776a43 100644
--- a/tests/scs_test.cpp
+++ b/tests/scs_test.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#if __has_feature(shadow_call_stack)
-
 #include <gtest/gtest.h>
 
 #include "private/bionic_constants.h"
@@ -33,7 +31,9 @@
 }
 
 TEST(scs_test, stack_overflow) {
+#if defined(__aarch64__) || defined(__riscv)
   ASSERT_EXIT(recurse1(SCS_SIZE), testing::KilledBySignal(SIGSEGV), "");
-}
-
+#else
+  GTEST_SKIP() << "no SCS on this architecture";
 #endif
+}
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index f3f6020..6f8797f 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -165,8 +165,10 @@
 TEST_F(semaphore_DeathTest, sem_timedwait_null_timeout) {
   sem_t s;
   ASSERT_EQ(0, sem_init(&s, 0, 0));
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
+#pragma clang diagnostic pop
 }
 
 TEST(semaphore, sem_getvalue) {
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index 2f891ec..6ae8bfd 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -278,7 +278,6 @@
 }
 
 TEST(setjmp, bug_152210274) {
-  SKIP_WITH_HWASAN; // b/227390656
   // Ensure that we never have a mangled value in the stack pointer.
 #if defined(__BIONIC__)
   struct sigaction sa = {.sa_flags = SA_SIGINFO, .sa_sigaction = [](int, siginfo_t*, void*) {}};
@@ -299,15 +298,19 @@
         perror("setjmp");
         abort();
       }
-      if (*static_cast<pid_t*>(arg) == 100) longjmp(buf, 1);
+      // This will never be true, but the compiler doesn't know that, so the
+      // setjmp won't be removed by DCE. With HWASan/MTE this also acts as a
+      // kind of enforcement that the threads are done before leaving the test.
+      if (*static_cast<size_t*>(arg) != 123) longjmp(buf, 1);
     }
     return nullptr;
   };
+  pthread_t threads[kNumThreads];
   pid_t tids[kNumThreads] = {};
+  size_t var = 123;
   for (size_t i = 0; i < kNumThreads; ++i) {
-    pthread_t t;
-    ASSERT_EQ(0, pthread_create(&t, nullptr, jumper, &tids[i]));
-    tids[i] = pthread_gettid_np(t);
+    ASSERT_EQ(0, pthread_create(&threads[i], nullptr, jumper, &var));
+    tids[i] = pthread_gettid_np(threads[i]);
   }
 
   // Start the interrupter thread.
@@ -327,6 +330,9 @@
   pthread_t t;
   ASSERT_EQ(0, pthread_create(&t, nullptr, interrupter, tids));
   pthread_join(t, nullptr);
+  for (size_t i = 0; i < kNumThreads; i++) {
+    pthread_join(threads[i], nullptr);
+  }
 #else
   GTEST_SKIP() << "tests uses functions not in glibc";
 #endif
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index a9563b8..ab3e877 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -232,18 +232,28 @@
 }
 
 TEST(spawn, posix_spawn_file_actions) {
+#if !defined(__GLIBC__)
   int fds[2];
   ASSERT_NE(-1, pipe(fds));
 
   posix_spawn_file_actions_t fa;
   ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
 
+  // Test addclose and adddup2 by redirecting output to the pipe created above.
   ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
   ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
   ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
   // Check that close(2) failures are ignored by closing the same fd again.
   ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[1]));
+  // Open a file directly, to test addopen.
   ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 56, "/proc/version", O_RDONLY, 0));
+  // Test addfchdir by opening the same file a second way...
+  ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 57, "/proc", O_PATH, 0));
+  ASSERT_EQ(0, posix_spawn_file_actions_addfchdir_np(&fa, 57));
+  ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 58, "version", O_RDONLY, 0));
+  // Test addchdir by opening the same file a third way...
+  ASSERT_EQ(0, posix_spawn_file_actions_addchdir_np(&fa, "/"));
+  ASSERT_EQ(0, posix_spawn_file_actions_addopen(&fa, 59, "proc/version", O_RDONLY, 0));
 
   ExecTestHelper eth;
   eth.SetArgs({"ls", "-l", "/proc/self/fd", nullptr});
@@ -259,12 +269,21 @@
   AssertChildExited(pid, 0);
 
   // We'll know the dup2 worked if we see any ls(1) output in our pipe.
-  // The open we can check manually...
+  // The opens we can check manually (and they implicitly check the chdirs)...
   bool open_to_fd_56_worked = false;
+  bool open_to_fd_58_worked = false;
+  bool open_to_fd_59_worked = false;
   for (const auto& line : android::base::Split(content, "\n")) {
     if (line.find(" 56 -> /proc/version") != std::string::npos) open_to_fd_56_worked = true;
+    if (line.find(" 58 -> /proc/version") != std::string::npos) open_to_fd_58_worked = true;
+    if (line.find(" 59 -> /proc/version") != std::string::npos) open_to_fd_59_worked = true;
   }
-  ASSERT_TRUE(open_to_fd_56_worked);
+  ASSERT_TRUE(open_to_fd_56_worked) << content;
+  ASSERT_TRUE(open_to_fd_58_worked) << content;
+  ASSERT_TRUE(open_to_fd_59_worked) << content;
+#else
+  GTEST_SKIP() << "our old glibc doesn't have the chdirs; newer versions and musl do.";
+#endif
 }
 
 static void CatFileToString(posix_spawnattr_t* sa, const char* path, std::string* content) {
diff --git a/tests/stack_protector_test_helper.cpp b/tests/stack_protector_test_helper.cpp
index eddd940..69b3c5d 100644
--- a/tests/stack_protector_test_helper.cpp
+++ b/tests/stack_protector_test_helper.cpp
@@ -15,12 +15,11 @@
  */
 
 // Deliberately overwrite the stack canary.
-__attribute__((noinline)) void modify_stack_protector_test() {
+__attribute__((noinline, optnone)) void modify_stack_protector_test() {
   // We can't use memset here because it's fortified, and we want to test
   // the line of defense *after* that.
-  // Without volatile, the generic x86/x86-64 targets don't write to the stack.
   // We can't make a constant change, since the existing byte might already have
   // had that value.
-  volatile char* p = reinterpret_cast<volatile char*>(&p + 1);
+  char* p = reinterpret_cast<char*>(&p + 1);
   *p = ~*p;
 }
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index acc7ccd..c5ffe24 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -36,6 +36,7 @@
 
 #include <android-base/file.h>
 #include <android-base/silent_death_test.h>
+#include <android-base/strings.h>
 #include <android-base/test_utils.h>
 #include <android-base/unique_fd.h>
 
@@ -140,6 +141,22 @@
   fclose(fp);
 }
 
+TEST(STDIO_TEST, tmpfile_TMPDIR) {
+  TemporaryDir td;
+  setenv("TMPDIR", td.path, 1);
+
+  FILE* fp = tmpfile();
+  ASSERT_TRUE(fp != nullptr);
+
+  std::string fd_path = android::base::StringPrintf("/proc/self/fd/%d", fileno(fp));
+  char path[PATH_MAX];
+  ASSERT_GT(readlink(fd_path.c_str(), path, sizeof(path)), 0);
+  // $TMPDIR influenced where our temporary file ended up?
+  ASSERT_TRUE(android::base::StartsWith(path, td.path)) << path;
+  // And we used O_TMPFILE, right?
+  ASSERT_TRUE(android::base::EndsWith(path, " (deleted)")) << path;
+}
+
 TEST(STDIO_TEST, dprintf) {
   TemporaryFile tf;
 
@@ -190,6 +207,8 @@
 }
 
 TEST(STDIO_TEST, getdelim_invalid) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != nullptr);
 
@@ -206,6 +225,7 @@
   ASSERT_EQ(getdelim(&buffer, nullptr, ' ', fp), -1);
   ASSERT_EQ(EINVAL, errno);
   fclose(fp);
+#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, getdelim_directory) {
@@ -260,6 +280,8 @@
 }
 
 TEST(STDIO_TEST, getline_invalid) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   FILE* fp = tmpfile();
   ASSERT_TRUE(fp != nullptr);
 
@@ -276,6 +298,7 @@
   ASSERT_EQ(getline(&buffer, nullptr, fp), -1);
   ASSERT_EQ(EINVAL, errno);
   fclose(fp);
+#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, printf_ssize_t) {
@@ -1944,6 +1967,8 @@
 
 TEST(STDIO_TEST, open_memstream_EINVAL) {
 #if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   char* p;
   size_t size;
 
@@ -1956,6 +1981,7 @@
   errno = 0;
   ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
   ASSERT_EQ(EINVAL, errno);
+#pragma clang diagnostic pop
 #else
   GTEST_SKIP() << "glibc is broken";
 #endif
@@ -2975,9 +3001,6 @@
 }
 
 TEST(STDIO_TEST, snprintf_b) {
-  // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   char buf[BUFSIZ];
   EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%b>", 5));
   EXPECT_STREQ("<101>", buf);
@@ -2989,13 +3012,9 @@
   EXPECT_STREQ("<0b10101010101010101010101010101010>", buf);
   EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#b>", 0));
   EXPECT_STREQ("<0>", buf);
-#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, snprintf_B) {
-  // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   char buf[BUFSIZ];
   EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%B>", 5));
   EXPECT_STREQ("<101>", buf);
@@ -3007,13 +3026,9 @@
   EXPECT_STREQ("<0B10101010101010101010101010101010>", buf);
   EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#B>", 0));
   EXPECT_STREQ("<0>", buf);
-#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, swprintf_b) {
-  // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   wchar_t buf[BUFSIZ];
   EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%b>", 5));
   EXPECT_EQ(std::wstring(L"<101>"), buf);
@@ -3025,13 +3040,9 @@
   EXPECT_EQ(std::wstring(L"<0b10101010101010101010101010101010>"), buf);
   EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#b>", 0));
   EXPECT_EQ(std::wstring(L"<0>"), buf);
-#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, swprintf_B) {
-  // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   wchar_t buf[BUFSIZ];
   EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%B>", 5));
   EXPECT_EQ(std::wstring(L"<101>"), buf);
@@ -3043,7 +3054,6 @@
   EXPECT_EQ(std::wstring(L"<0B10101010101010101010101010101010>"), buf);
   EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#B>", 0));
   EXPECT_EQ(std::wstring(L"<0>"), buf);
-#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, scanf_i_decimal) {
@@ -3143,10 +3153,6 @@
 }
 
 TEST(STDIO_TEST, scanf_b) {
-  // Our clang doesn't know about %b yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat"
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   int i;
   char ch;
   EXPECT_EQ(2, sscanf("<1012>", "<%b%c>", &i, &ch));
@@ -3159,14 +3165,9 @@
   EXPECT_EQ(2, sscanf("-0b", "%i%c", &i, &ch));
   EXPECT_EQ(0, i);
   EXPECT_EQ('b', ch);
-#pragma clang diagnostic pop
 }
 
 TEST(STDIO_TEST, swscanf_b) {
-  // Our clang doesn't know about %b yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat"
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   int i;
   char ch;
   EXPECT_EQ(2, swscanf(L"<1012>", L"<%b%c>", &i, &ch));
@@ -3179,5 +3180,4 @@
   EXPECT_EQ(2, swscanf(L"-0b", L"%i%c", &i, &ch));
   EXPECT_EQ(0, i);
   EXPECT_EQ('b', ch);
-#pragma clang diagnostic pop
 }
diff --git a/tests/sys_msg_test.cpp b/tests/sys_msg_test.cpp
index 200f654..da45087 100644
--- a/tests/sys_msg_test.cpp
+++ b/tests/sys_msg_test.cpp
@@ -74,9 +74,12 @@
 }
 
 TEST(sys_msg, msgctl_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   errno = 0;
   ASSERT_EQ(-1, msgctl(-1, IPC_STAT, nullptr));
   ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
 }
 
 TEST(sys_msg, msgget_failure) {
@@ -86,9 +89,12 @@
 }
 
 TEST(sys_msg, msgrcv_failure) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   errno = 0;
   ASSERT_EQ(-1, msgrcv(-1, nullptr, 0, 0, 0));
   ASSERT_TRUE(errno == EINVAL || errno == ENOSYS);
+#pragma clang diagnostic pop
 }
 
 TEST(sys_msg, msgsnd_failure) {
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
index 2e2665b..e0cbf78 100644
--- a/tests/sys_random_test.cpp
+++ b/tests/sys_random_test.cpp
@@ -48,6 +48,8 @@
 }
 
 TEST(sys_random, getentropy_EFAULT) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
 #if defined(HAVE_SYS_RANDOM)
   errno = 0;
   ASSERT_EQ(-1, getentropy(nullptr, 1));
@@ -55,6 +57,7 @@
 #else
   GTEST_SKIP() << "<sys/random.h> not available";
 #endif
+#pragma clang diagnostic pop
 }
 
 TEST(sys_random, getentropy_EIO) {
@@ -84,6 +87,8 @@
 }
 
 TEST(sys_random, getrandom_EFAULT) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
 #if defined(HAVE_SYS_RANDOM)
   errno = 0;
   ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
@@ -91,6 +96,7 @@
 #else
   GTEST_SKIP() << "<sys/random.h> not available";
 #endif
+#pragma clang diagnostic pop
 }
 
 TEST(sys_random, getrandom_EINVAL) {
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 2a36460..4c21627 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -589,9 +589,10 @@
   TestGetTidCachingWithFork(CloneAndSetTid, exit);
 }
 
+__attribute__((no_sanitize("hwaddress", "memtag")))
 static int CloneStartRoutine(int (*start_routine)(void*)) {
   void* child_stack[1024];
-  return clone(start_routine, untag_address(&child_stack[1024]), SIGCHLD, nullptr);
+  return clone(start_routine, &child_stack[1024], SIGCHLD, nullptr);
 }
 
 static int GetPidCachingCloneStartRoutine(void*) {
diff --git a/tests/utmp_test.cpp b/tests/utmp_test.cpp
index b024818..459f9c3 100644
--- a/tests/utmp_test.cpp
+++ b/tests/utmp_test.cpp
@@ -25,6 +25,7 @@
 }
 
 TEST(utmp, smoke) {
+  // The rest of <utmp.h> is just no-op implementations, so testing is trivial.
   ASSERT_EQ(-1, utmpname("hello"));
   setutent();
   ASSERT_EQ(NULL, getutent());
diff --git a/tests/utmpx_test.cpp b/tests/utmpx_test.cpp
new file mode 100644
index 0000000..55427a6
--- /dev/null
+++ b/tests/utmpx_test.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <utmpx.h>
+
+TEST(utmpx, smoke) {
+  // Our utmpx "implementation" just calls the utmp no-op functions.
+  setutxent();
+  utmpx empty = {.ut_type = EMPTY};
+  ASSERT_EQ(NULL, getutxent());
+  ASSERT_EQ(NULL, getutxid(&empty));
+  ASSERT_EQ(NULL, getutxline(&empty));
+  endutxent();
+  ASSERT_EQ(NULL, pututxline(&empty));
+}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 16d4348..8716810 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -714,7 +714,8 @@
 #if defined(__BIONIC__)
   wchar_t* p;
   size_t size;
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   // Invalid buffer.
   errno = 0;
   ASSERT_EQ(nullptr, open_wmemstream(nullptr, &size));
@@ -724,6 +725,7 @@
   errno = 0;
   ASSERT_EQ(nullptr, open_wmemstream(&p, nullptr));
   ASSERT_EQ(EINVAL, errno);
+#pragma clang diagnostic pop
 #else
   GTEST_SKIP() << "This test is bionic-specific";
 #endif