Merge "[MTE] do not use ldg in linker if MTE is off for process" into main
diff --git a/OWNERS b/OWNERS
index 1859b9e..7455fd7 100644
--- a/OWNERS
+++ b/OWNERS
@@ -6,4 +6,4 @@
 [email protected]
 [email protected]
 
-per-file docs/[email protected],[email protected],[email protected]
+per-file docs/[email protected],[email protected]
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index e9cfbac..2430447 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -47,10 +47,12 @@
 dynamic linker's caching code cached failures too, so it was necessary
 to topologically sort your libraries and load them in reverse order.
 
-If you need to support Android devices running OS versions older than
+This issue is no longer relevant to most developers,
+but if you need to support Android devices running OS versions older than
 API level 23, you might want to consider
-[ReLinker](https://github.com/KeepSafe/ReLinker) which claims to solve
-these and other problems automatically.
+[ReLinker](https://github.com/KeepSafe/ReLinker) or
+[SoLoader](https://github.com/facebook/SoLoader),
+which claim to solve these problems automatically.
 
 Alternatively, if you don't have too many dependencies, it can be easiest to
 simply link all of your code into one big library and sidestep the details of
@@ -76,6 +78,17 @@
 the local group. This allows ASAN, for example, to ensure that it can
 intercept any symbol.
 
+This issue is no longer relevant to most developers,
+but if you need to support Android devices running OS versions older than
+API level 23, you might want to consider
+[ReLinker](https://github.com/KeepSafe/ReLinker) or
+[SoLoader](https://github.com/facebook/SoLoader),
+which claim to solve these problems automatically.
+
+Alternatively, if you don't have too many dependencies, it can be easiest to
+simply link all of your code into one big library and sidestep the details of
+library and symbol lookup changes on all past (and future) Android versions.
+
 
 ## LD_PRELOAD and 32/64 bit
 
@@ -521,3 +534,13 @@
 `libc.so`. This ensures that executables built with newer `crtbegin_dynamic.o`
 (in NDK >= r27) work with older `libc.so` (in Android <= API level 34), and
 vice versa.
+
+
+## Only files named `lib*.so` are copied by `extractNativeLibs` (Enforced for API level <= 35)
+
+Until API level 36, PackageManager would only install files whose names match
+the glob `lib*.so` when extracting native libraries _for non-debuggable apps_.
+This was especially confusing (and hard to debug) because the restriction did
+_not_ apply if your app was debuggable. To be compatible with all API levels,
+always give files that need to be extracted a "lib" prefix and ".so" suffix,
+or avoid using `extractNativeLibs`.
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 03f3f29..f9ceb4c 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -38,6 +38,13 @@
 void ReadWriteTest(benchmark::State& state, Fn f, bool buffered) {
   size_t chunk_size = state.range(0);
 
+  // /dev/zero copies zeroes if you read from it and discards writes.
+  //
+  // This is fine for the purpose of measuring stdio overhead
+  // rather than kernel/fs performance.
+  // (Old versions of stdio would copy reads/writes larger than
+  // the stdio buffer through the stdio buffer in chunks,
+  // rather than directly to the user's destination.)
   FILE* fp = fopen("/dev/zero", "r+e");
   __fsetlocking(fp, FSETLOCKING_BYCALLER);
   char* buf = new char[chunk_size];
diff --git a/docs/README.md b/docs/README.md
index 2825eac..d66fa68 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -17,6 +17,7 @@
   which detects use-after-close() bugs.
 * [fdtrack](fdtrack.md) - bionic's file descriptor tracker,
   which helps debug file descriptor leaks.
+* [C23](c23.md) - dealing with C23's breaking changes.
 
 ## Maintainer documentation
 
diff --git a/docs/c23.md b/docs/c23.md
new file mode 100644
index 0000000..9ed570d
--- /dev/null
+++ b/docs/c23.md
@@ -0,0 +1,97 @@
+# C23 language changes
+
+## Breaking changes
+
+### `void foo()` now means `void foo(void)`
+In C17 and earlier, `void foo()` means "I haven't yet told you how many
+arguments this function has". In C23, it's equivalent to C++ and means "this
+function has no arguments". This may surface as a function pointer type
+mismatch, because previously `()` matched functions taking any arguments,
+whereas in C23 it only matches functions taking no arguments.
+
+Fix: in cases where your function does have arguments, declare them.
+
+### Undeclared identifiers are now errors
+In C17 and earlier, calling `foo(123)` without a declaration for `foo()`
+produced a warning. In C23 this is an error instead. One common special case of
+this is code that's explicitly ignoring such warnings to call functions that are
+GNU extensions; such code should be fixed to ensure that `_GNU_SOURCE` is
+defined before any header is included instead (often by adding `-D_GNU_SOURCE`
+to the cflags in the build file).
+
+Fix: add the missing forward declaration or `#include` (or `-D_GNU_SOURCE`).
+
+### `bool`/`true`/`false` are now keywords
+In C17 and earlier, only code that included `<stdbool.h>` would have standard
+definitions for these (typically macros for `_Bool`/`1`/`0`). In C23 these are
+keywords and should no longer be defined in your code.
+
+Fix: delete any definitions of `bool`/`true`/`false` if you only need to build
+as C23, or switch to `#include <stdbool.h>` for compatibility back to C99.
+
+### `false` is no longer `0`
+In C17 and earlier, it was common for true and false to be defined as 1 and 0
+(either by `<stdbool.h>` or by user-provided `#define`/`enum`). This meant that
+`false` (as 0) could be implicitly converted to `NULL`. In C23, a function that
+returns (or takes) a pointer can no longer return `false` (or be passed
+`false`).
+
+Fix: return/pass `NULL` (or `nullptr` for C23-only code) instead of `false`
+in pointer contexts.
+
+### `unreachable()` is now a predefined function-like macro in `<stddef.h>`
+In C17 and earlier, `unreachable()` was available for your own macros/functions.
+In C23 there's a standard definition.
+
+Fix: delete your `unreachable()` if it was just equivalent to
+`__builtin_unreachable()` or rename it if it had different behavior.
+
+### K&R prototypes are no longer valid
+In C17 and earlier, K&R function prototypes were deprecated but still allowed.
+In C23 K&R prototypes are no longer allowed.
+
+Fix: rewrite any K&R prototypes as ANSI/ISO prototypes.
+
+
+## Non-breaking changes
+
+### Unused function parameters can now be anonymous
+In C17 and earlier you'd have to use `__attribute__((unused))` on an unused
+function parameter. In C23 you can just omit the parameter name instead,
+like `void* pthread_callback_fn(void*) {` (as in C++).
+
+### New standard attributes
+C23 adds `[[deprecated("reason")]]`, `[[fallthrough]]`, `[[nodiscard]]` (the
+equivalent of the clang attribute `warn_unused_result`),
+`[[maybe_unused]]` (the equivalent of the clang attribute `unused`),
+and `[[noreturn]]` (equivalent to C11 `_Noreturn`).
+Most of these have been available before via `__attribute__` or other syntax,
+but are now standard.
+
+### `#embed`
+You can now include binary data directly into an array or string: https://en.cppreference.com/w/c/preprocessor/embed
+
+### `void foo(...)` is now allowed
+In C17 and earlier, a varargs function needed a non-varargs argument.
+In C23 this is allowed (as in C++).
+
+### `enum` base types
+You can now say `enum E : long { ... }` to explicitly choose the base type of
+your enum (as in C++, and already supported by clang as an extension).
+
+### `nullptr` constant
+There is now a `nullptr` constant (as in C++),
+and a corresponding `nullptr_t` type for that constant.
+
+### `constexpr`
+There is now a limited form of `constexpr` for defining `const` variables
+(similar to, but much more limited than C++ constexpr).
+
+
+## Library changes
+
+Library changes are not covered here because bionic does not make library
+functionality available based on target C version, since the target API level
+distinctions are confusing enough already.
+
+See [status.md](status.md) for what functionality went into which API level.
diff --git a/docs/native_allocator.md b/docs/native_allocator.md
index 13d9738..a97e705 100644
--- a/docs/native_allocator.md
+++ b/docs/native_allocator.md
@@ -9,9 +9,14 @@
 
 It is important to note that there are two modes for a native allocator
 to run in on Android. The first is the normal allocator, the second is
-called the svelte config, which is designed to run on memory constrained
-systems and be a bit slower, but take less RSS. To enable the svelte config,
-add this line to the `BoardConfig.mk` for the given target:
+called the low memory config, which is designed to run on memory constrained
+systems and be a bit slower, but take less RSS. To enable the low memory
+config, add this line to the `BoardConfig.mk` for the given target:
+
+    MALLOC_LOW_MEMORY := true
+
+This is valid starting with Android V (API level 35), before that the
+way to enable the low memory config is:
 
     MALLOC_SVELTE := true
 
diff --git a/libc/Android.bp b/libc/Android.bp
index 5d1a2f2..794ccc7 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -104,8 +104,6 @@
     },
 
     apex_available: ["com.android.runtime"],
-
-    tidy_disabled_srcs: ["upstream-*/**/*.c"],
 }
 
 // Workaround for b/24465209.
@@ -622,7 +620,6 @@
     arch: {
         arm: {
             srcs: [
-                "upstream-openbsd/lib/libc/string/memchr.c",
                 "upstream-openbsd/lib/libc/string/stpncpy.c",
                 "upstream-openbsd/lib/libc/string/strncat.c",
                 "upstream-openbsd/lib/libc/string/strncmp.c",
@@ -1083,9 +1080,6 @@
                 "arch-arm/krait/bionic/memset.S",
 
                 "arch-arm/kryo/bionic/memcpy.S",
-
-                "bionic/strchr.cpp",
-                "bionic/strnlen.cpp",
             ],
         },
         arm64: {
@@ -1123,22 +1117,6 @@
                 "arch-riscv64/string/strncmp_v.S",
                 "arch-riscv64/string/strncpy_v.S",
                 "arch-riscv64/string/strnlen_v.S",
-
-                "arch-riscv64/string/memchr.c",
-                "arch-riscv64/string/memcmp.c",
-                "arch-riscv64/string/memcpy.c",
-                "arch-riscv64/string/memmove.c",
-                "arch-riscv64/string/memset.c",
-                "arch-riscv64/string/stpcpy.c",
-                "arch-riscv64/string/strcat.c",
-                "arch-riscv64/string/strchr.c",
-                "arch-riscv64/string/strcmp.c",
-                "arch-riscv64/string/strcpy.c",
-                "arch-riscv64/string/strlen.c",
-                "arch-riscv64/string/strncat.c",
-                "arch-riscv64/string/strncmp.c",
-                "arch-riscv64/string/strncpy.c",
-                "arch-riscv64/string/strnlen.c",
             ],
         },
 
@@ -1152,16 +1130,13 @@
                 "arch-x86/bionic/vfork.S",
                 "arch-x86/bionic/__x86.get_pc_thunk.S",
 
-                "arch-x86/string/sse2-memchr-atom.S",
                 "arch-x86/string/sse2-memmove-slm.S",
                 "arch-x86/string/sse2-memset-slm.S",
                 "arch-x86/string/sse2-stpcpy-slm.S",
                 "arch-x86/string/sse2-stpncpy-slm.S",
-                "arch-x86/string/sse2-strchr-atom.S",
                 "arch-x86/string/sse2-strcpy-slm.S",
                 "arch-x86/string/sse2-strlen-slm.S",
                 "arch-x86/string/sse2-strncpy-slm.S",
-                "arch-x86/string/sse2-strnlen-atom.S",
 
                 "arch-x86/string/ssse3-memcmp-atom.S",
                 "arch-x86/string/ssse3-strcat-atom.S",
@@ -1369,9 +1344,6 @@
         arm64: {
             srcs: ["arch-arm64/dynamic_function_dispatch.cpp"],
         },
-        riscv64: {
-            srcs: ["arch-riscv64/dynamic_function_dispatch.cpp"],
-        },
     },
     // Prevent the compiler from inserting calls to libc/taking the address of
     // a jump table from within an ifunc (or, in the static case, code that
@@ -1655,9 +1627,7 @@
     // which is default module for soong-defined system image.
     visibility: [
         "//bionic/apex",
-        "//build/make/target/product/generic",
-        //TODO(b/381985636) : Remove visibility to Soong-defined GSI once resolved
-        "//build/make/target/product/gsi",
+        "//visibility:any_system_partition",
     ],
 }
 
@@ -2296,6 +2266,9 @@
         "-E",
         "-Wall",
         "-Werror",
+        // Soong implicitly adds a -c argument that we override with -E.
+        // Suppress Clang's error about the unused -c argument.
+        "-Wno-unused-command-line-argument",
         "-nostdinc",
     ],
 }
diff --git a/libc/NOTICE b/libc/NOTICE
index bca4891..c52a102 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -891,6 +891,22 @@
 -------------------------------------------------------------------
 
 Copyright (C) 2024 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2024 The Android Open Source Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -4714,40 +4730,6 @@
 
 SPDX-License-Identifier: BSD-3-Clause
 
-Copyright (c) 1990, 1993
-   The Regents of the University of California.  All rights reserved.
-
-This code is derived from software contributed to Berkeley by
-Mike Hibler and Chris Torek.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
--------------------------------------------------------------------
-
-SPDX-License-Identifier: BSD-3-Clause
-
 Copyright (c) 1992, 1993
    The Regents of the University of California.  All rights reserved.
 
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
deleted file mode 100644
index ce6c028..0000000
--- a/libc/arch-riscv64/dynamic_function_dispatch.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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 <fcntl.h>
-#include <private/bionic_ifuncs.h>
-#include <stddef.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-extern "C" {
-
-static inline __always_inline int ifunc_faccessat(int dir_fd, const char* path, int mode) {
-  register long a0 __asm__("a0") = dir_fd;
-  register long a1 __asm__("a1") = reinterpret_cast<long>(path);
-  register long a2 __asm__("a2") = mode;
-  register long a7 __asm__("a7") = __NR_faccessat;
-  __asm__("ecall" : "=r"(a0) : "r"(a0), "r"(a1), "r"(a2), "r"(a7) : "memory");
-  return a0;
-}
-
-static bool have_fast_v() {
-  static bool result = []() {
-    // We don't want to do a full "bogomips" test, so just check for the
-    // presence of a file that would indicate that we're running in qemu.
-    return ifunc_faccessat(AT_FDCWD, "/dev/hvc0", F_OK) != 0;
-  }();
-  return result;
-}
-
-DEFINE_IFUNC_FOR(memchr) {
-  if (have_fast_v()) RETURN_FUNC(memchr_func_t, memchr_v);
-  RETURN_FUNC(memchr_func_t, memchr_gc);
-}
-MEMCHR_SHIM()
-
-DEFINE_IFUNC_FOR(memcmp) {
-  if (have_fast_v()) RETURN_FUNC(memcmp_func_t, memcmp_v);
-  RETURN_FUNC(memcmp_func_t, memcmp_gc);
-}
-MEMCMP_SHIM()
-
-DEFINE_IFUNC_FOR(memcpy) {
-  if (have_fast_v()) RETURN_FUNC(memcpy_func_t, memcpy_v);
-  RETURN_FUNC(memcpy_func_t, memcpy_gc);
-}
-MEMCPY_SHIM()
-
-DEFINE_IFUNC_FOR(memmove) {
-  if (have_fast_v()) RETURN_FUNC(memmove_func_t, memmove_v);
-  RETURN_FUNC(memmove_func_t, memmove_gc);
-}
-MEMMOVE_SHIM()
-
-DEFINE_IFUNC_FOR(memset) {
-  if (have_fast_v()) RETURN_FUNC(memset_func_t, memset_v);
-  RETURN_FUNC(memset_func_t, memset_gc);
-}
-MEMSET_SHIM()
-
-DEFINE_IFUNC_FOR(stpcpy) {
-  if (have_fast_v()) RETURN_FUNC(stpcpy_func_t, stpcpy_v);
-  RETURN_FUNC(stpcpy_func_t, stpcpy_gc);
-}
-STPCPY_SHIM()
-
-DEFINE_IFUNC_FOR(strcat) {
-  if (have_fast_v()) RETURN_FUNC(strcat_func_t, strcat_v);
-  RETURN_FUNC(strcat_func_t, strcat_gc);
-}
-STRCAT_SHIM()
-
-DEFINE_IFUNC_FOR(strchr) {
-  if (have_fast_v()) RETURN_FUNC(strchr_func_t, strchr_v);
-  RETURN_FUNC(strchr_func_t, strchr_gc);
-}
-STRCHR_SHIM()
-
-DEFINE_IFUNC_FOR(strcmp) {
-  if (have_fast_v()) RETURN_FUNC(strcmp_func_t, strcmp_v);
-  RETURN_FUNC(strcmp_func_t, strcmp_gc);
-}
-STRCMP_SHIM()
-
-DEFINE_IFUNC_FOR(strcpy) {
-  if (have_fast_v()) RETURN_FUNC(strcpy_func_t, strcpy_v);
-  RETURN_FUNC(strcpy_func_t, strcpy_gc);
-}
-STRCPY_SHIM()
-
-DEFINE_IFUNC_FOR(strlen) {
-  if (have_fast_v()) RETURN_FUNC(strlen_func_t, strlen_v);
-  RETURN_FUNC(strlen_func_t, strlen_gc);
-}
-STRLEN_SHIM()
-
-DEFINE_IFUNC_FOR(strncat) {
-  if (have_fast_v()) RETURN_FUNC(strncat_func_t, strncat_v);
-  RETURN_FUNC(strncat_func_t, strncat_gc);
-}
-STRNCAT_SHIM()
-
-DEFINE_IFUNC_FOR(strncmp) {
-  if (have_fast_v()) RETURN_FUNC(strncmp_func_t, strncmp_v);
-  RETURN_FUNC(strncmp_func_t, strncmp_gc);
-}
-STRNCMP_SHIM()
-
-DEFINE_IFUNC_FOR(strncpy) {
-  if (have_fast_v()) RETURN_FUNC(strncpy_func_t, strncpy_v);
-  RETURN_FUNC(strncpy_func_t, strncpy_gc);
-}
-STRNCPY_SHIM()
-
-DEFINE_IFUNC_FOR(strnlen) {
-  if (have_fast_v()) RETURN_FUNC(strnlen_func_t, strnlen_v);
-  RETURN_FUNC(strnlen_func_t, strnlen_gc);
-}
-STRNLEN_SHIM()
-
-}  // extern "C"
diff --git a/libc/arch-riscv64/string/memchr.c b/libc/arch-riscv64/string/memchr.c
deleted file mode 100644
index 34eb6d7..0000000
--- a/libc/arch-riscv64/string/memchr.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define memchr memchr_gc
-#include <upstream-openbsd/lib/libc/string/memchr.c>
diff --git a/libc/arch-riscv64/string/memchr_v.S b/libc/arch-riscv64/string/memchr_v.S
index d4999c3..8833436 100644
--- a/libc/arch-riscv64/string/memchr_v.S
+++ b/libc/arch-riscv64/string/memchr_v.S
@@ -68,7 +68,7 @@
 #define vData v0
 #define vMask v8
 
-ENTRY(memchr_v)
+ENTRY(memchr)
 
 L(loop):
     vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -93,4 +93,4 @@
     add iResult, pSrc, iTemp
     ret
 
-END(memchr_v)
+END(memchr)
diff --git a/libc/arch-riscv64/string/memcmp.c b/libc/arch-riscv64/string/memcmp.c
deleted file mode 100644
index 2d7335a..0000000
--- a/libc/arch-riscv64/string/memcmp.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-/*
- * Compare memory regions.
- */
-int
-memcmp_gc(const void *s1, const void *s2, size_t n)
-{
-	if (n != 0) {
-		const unsigned char *p1 = s1, *p2 = s2;
-
-		do {
-			if (*p1++ != *p2++)
-				return (*--p1 - *--p2);
-		} while (--n != 0);
-	}
-	return (0);
-}
diff --git a/libc/arch-riscv64/string/memcmp_v.S b/libc/arch-riscv64/string/memcmp_v.S
index 55e08db..9c1ecdc 100644
--- a/libc/arch-riscv64/string/memcmp_v.S
+++ b/libc/arch-riscv64/string/memcmp_v.S
@@ -71,7 +71,7 @@
 #define vData2 v8
 #define vMask v16
 
-ENTRY(memcmp_v)
+ENTRY(memcmp)
 
 L(loop):
     vsetvli iVL, iNum, e8, ELEM_LMUL_SETTING, ta, ma
@@ -103,4 +103,4 @@
     sub iResult, iTemp1, iTemp2
     ret
 
-END(memcmp_v)
+END(memcmp)
diff --git a/libc/arch-riscv64/string/memcpy.c b/libc/arch-riscv64/string/memcpy.c
deleted file mode 100644
index ee11504..0000000
--- a/libc/arch-riscv64/string/memcpy.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define	MEMCOPY
-#include "bcopy.c"
diff --git a/libc/arch-riscv64/string/memcpy_v.S b/libc/arch-riscv64/string/memcpy_v.S
index 93ec60f..def1d9b 100644
--- a/libc/arch-riscv64/string/memcpy_v.S
+++ b/libc/arch-riscv64/string/memcpy_v.S
@@ -65,7 +65,7 @@
 #define ELEM_LMUL_SETTING m8
 #define vData v0
 
-ENTRY(memcpy_v)
+ENTRY(memcpy)
 
     mv pDstPtr, pDst
 
@@ -82,4 +82,4 @@
 
     ret
 
-END(memcpy_v)
+END(memcpy)
diff --git a/libc/arch-riscv64/string/memmove.c b/libc/arch-riscv64/string/memmove.c
deleted file mode 100644
index e9bb2c2..0000000
--- a/libc/arch-riscv64/string/memmove.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define	MEMMOVE
-#include "bcopy.c"
diff --git a/libc/arch-riscv64/string/memmove_v.S b/libc/arch-riscv64/string/memmove_v.S
index cad2b05..fa70f76 100644
--- a/libc/arch-riscv64/string/memmove_v.S
+++ b/libc/arch-riscv64/string/memmove_v.S
@@ -67,7 +67,7 @@
 #define ELEM_LMUL_SETTING m8
 #define vData v0
 
-ENTRY(memmove_v)
+ENTRY(memmove)
 
     mv pDstPtr, pDst
 
@@ -99,4 +99,4 @@
     bnez iNum, L(backward_copy_loop)
     ret
 
-END(memmove_v)
+END(memmove)
diff --git a/libc/arch-riscv64/string/memset.c b/libc/arch-riscv64/string/memset.c
deleted file mode 100644
index d51cbf9..0000000
--- a/libc/arch-riscv64/string/memset.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Hibler and Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-
-#include <limits.h>
-
-#define	wsize	sizeof(u_long)
-#define	wmask	(wsize - 1)
-
-#include <string.h>
-
-#define	RETURN	return (dst0)
-#define	VAL	c0
-#define	WIDEVAL	c
-
-void *
-memset_gc(void *dst0, int c0, size_t length)
-{
-	size_t t;
-	u_long c;
-	u_char *dst;
-
-	dst = dst0;
-	/*
-	 * If not enough words, just fill bytes.  A length >= 2 words
-	 * guarantees that at least one of them is `complete' after
-	 * any necessary alignment.  For instance:
-	 *
-	 *	|-----------|-----------|-----------|
-	 *	|00|01|02|03|04|05|06|07|08|09|0A|00|
-	 *	          ^---------------------^
-	 *		 dst		 dst+length-1
-	 *
-	 * but we use a minimum of 3 here since the overhead of the code
-	 * to do word writes is substantial.
-	 *
-	 * TODO: This threshold might not be sensible for 64-bit u_long.
-	 * We should benchmark and revisit this decision.
-	 */
-	if (length < 3 * wsize) {
-		while (length != 0) {
-			*dst++ = VAL;
-			--length;
-		}
-		RETURN;
-	}
-
-	if ((c = (u_char)c0) != 0) {	/* Fill the word. */
-		c = (c << 8) | c;	/* u_long is 16 bits. */
-		c = (c << 16) | c;	/* u_long is 32 bits. */
-		c = (c << 32) | c;	/* u_long is 64 bits. */
-	}
-	/* Align destination by filling in bytes. */
-	if ((t = (long)dst & wmask) != 0) {
-		t = wsize - t;
-		length -= t;
-		do {
-			*dst++ = VAL;
-		} while (--t != 0);
-	}
-
-	/* Fill words.  Length was >= 2*words so we know t >= 1 here. */
-	t = length / wsize;
-	do {
-		*(u_long *)(void *)dst = WIDEVAL;
-		dst += wsize;
-	} while (--t != 0);
-
-	/* Mop up trailing bytes, if any. */
-	t = length & wmask;
-	if (t != 0)
-		do {
-			*dst++ = VAL;
-		} while (--t != 0);
-	RETURN;
-}
diff --git a/libc/arch-riscv64/string/memset_v.S b/libc/arch-riscv64/string/memset_v.S
index 06a2c6a..5aa525e 100644
--- a/libc/arch-riscv64/string/memset_v.S
+++ b/libc/arch-riscv64/string/memset_v.S
@@ -66,7 +66,7 @@
 #define ELEM_LMUL_SETTING m8
 #define vData v0
 
-ENTRY(memset_v)
+ENTRY(memset)
 
     mv pDstPtr, pDst
 
@@ -82,4 +82,4 @@
 
     ret
 
-END(memset_v)
+END(memset)
diff --git a/libc/arch-riscv64/string/stpcpy.c b/libc/arch-riscv64/string/stpcpy.c
deleted file mode 100644
index 2afcf99..0000000
--- a/libc/arch-riscv64/string/stpcpy.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define stpcpy stpcpy_gc
-#include <upstream-openbsd/lib/libc/string/stpcpy.c>
diff --git a/libc/arch-riscv64/string/stpcpy_v.S b/libc/arch-riscv64/string/stpcpy_v.S
index 6a853ec..c5d0945 100644
--- a/libc/arch-riscv64/string/stpcpy_v.S
+++ b/libc/arch-riscv64/string/stpcpy_v.S
@@ -68,7 +68,7 @@
 #define vStr1 v8
 #define vStr2 v16
 
-ENTRY(stpcpy_v)
+ENTRY(stpcpy)
 L(stpcpy_loop):
     vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
     vle8ff.v vStr1, (pSrc)
@@ -85,4 +85,4 @@
     sub pDstPtr, pDstPtr, iCurrentVL
     add pDstPtr, pDstPtr, iActiveElemPos
     ret
-END(stpcpy_v)
+END(stpcpy)
diff --git a/libc/arch-riscv64/string/strcat.c b/libc/arch-riscv64/string/strcat.c
deleted file mode 100644
index 5fb1621..0000000
--- a/libc/arch-riscv64/string/strcat.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strcat strcat_gc
-#include <upstream-openbsd/lib/libc/string/strcat.c>
diff --git a/libc/arch-riscv64/string/strcat_v.S b/libc/arch-riscv64/string/strcat_v.S
index 3d348e7..5abf295 100644
--- a/libc/arch-riscv64/string/strcat_v.S
+++ b/libc/arch-riscv64/string/strcat_v.S
@@ -69,7 +69,7 @@
 #define vStr1 v8
 #define vStr2 v16
 
-ENTRY(strcat_v)
+ENTRY(strcat)
 
     mv pDstPtr, pDst
 
@@ -104,4 +104,4 @@
 
     ret
 
-END(strcat_v)
+END(strcat)
diff --git a/libc/arch-riscv64/string/strchr.c b/libc/arch-riscv64/string/strchr.c
deleted file mode 100644
index dc07766..0000000
--- a/libc/arch-riscv64/string/strchr.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*	$OpenBSD: strchr.c,v 1.4 2018/10/01 06:37:37 martijn Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char *
-strchr_gc(const char *p, int ch)
-{
-	for (;; ++p) {
-		if (*p == (char) ch)
-			return((char *)p);
-		if (!*p)
-			return((char *)NULL);
-	}
-	/* NOTREACHED */
-}
diff --git a/libc/arch-riscv64/string/strchr_v.S b/libc/arch-riscv64/string/strchr_v.S
index bc7b58a..ea13c5d 100644
--- a/libc/arch-riscv64/string/strchr_v.S
+++ b/libc/arch-riscv64/string/strchr_v.S
@@ -69,7 +69,7 @@
 #define vMaskEnd v8
 #define vMaskCh v9
 
-ENTRY(strchr_v)
+ENTRY(strchr)
 
 L(strchr_loop):
     vsetvli iVL, zero, e8, ELEM_LMUL_SETTING, ta, ma
@@ -91,4 +91,4 @@
     add pStr, pStr, iChOffset
     ret
 
-END(strchr_v)
+END(strchr)
diff --git a/libc/arch-riscv64/string/strcmp.c b/libc/arch-riscv64/string/strcmp.c
deleted file mode 100644
index 7a1fefe..0000000
--- a/libc/arch-riscv64/string/strcmp.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*	$OpenBSD: strcmp.c,v 1.9 2015/08/31 02:53:57 guenther Exp $	*/
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-/*
- * Compare strings.
- */
-int
-strcmp_gc(const char *s1, const char *s2)
-{
-	while (*s1 == *s2++)
-		if (*s1++ == 0)
-			return (0);
-	return (*(unsigned char *)s1 - *(unsigned char *)--s2);
-}
diff --git a/libc/arch-riscv64/string/strcmp_v.S b/libc/arch-riscv64/string/strcmp_v.S
index 01e72b1..3332c83 100644
--- a/libc/arch-riscv64/string/strcmp_v.S
+++ b/libc/arch-riscv64/string/strcmp_v.S
@@ -74,7 +74,7 @@
 #define vMask1 v16
 #define vMask2 v17
 
-ENTRY(strcmp_v)
+ENTRY(strcmp)
 
     # increase the lmul using the following sequences:
     # 1/2, 1/2, 1, 2, 4, 4, 4, ...
@@ -166,4 +166,4 @@
     sub iResult, iTemp1, iTemp2
     ret
 
-END(strcmp_v)
+END(strcmp)
diff --git a/libc/arch-riscv64/string/strcpy.c b/libc/arch-riscv64/string/strcpy.c
deleted file mode 100644
index a624541..0000000
--- a/libc/arch-riscv64/string/strcpy.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*	$OpenBSD: strcpy.c,v 1.10 2017/11/28 06:55:49 tb Exp $	*/
-
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char *
-strcpy_gc(char *to, const char *from)
-{
-	char *save = to;
-
-	for (; (*to = *from) != '\0'; ++from, ++to);
-	return(save);
-}
diff --git a/libc/arch-riscv64/string/strcpy_v.S b/libc/arch-riscv64/string/strcpy_v.S
index 084b3a5..b89b1a8 100644
--- a/libc/arch-riscv64/string/strcpy_v.S
+++ b/libc/arch-riscv64/string/strcpy_v.S
@@ -69,7 +69,7 @@
 #define vStr1 v8
 #define vStr2 v16
 
-ENTRY(strcpy_v)
+ENTRY(strcpy)
 
     mv pDstPtr, pDst
 
@@ -88,4 +88,4 @@
 
     ret
 
-END(strcpy_v)
+END(strcpy)
diff --git a/libc/arch-riscv64/string/strlen.c b/libc/arch-riscv64/string/strlen.c
deleted file mode 100644
index ac8d27f..0000000
--- a/libc/arch-riscv64/string/strlen.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*	$OpenBSD: strlen.c,v 1.9 2015/08/31 02:53:57 guenther Exp $	*/
-
-/*-
- * Copyright (c) 1990, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-size_t
-strlen_gc(const char *str)
-{
-	const char *s;
-
-	for (s = str; *s; ++s)
-		;
-	return (s - str);
-}
diff --git a/libc/arch-riscv64/string/strlen_v.S b/libc/arch-riscv64/string/strlen_v.S
index c284021..7f7d2dd 100644
--- a/libc/arch-riscv64/string/strlen_v.S
+++ b/libc/arch-riscv64/string/strlen_v.S
@@ -66,7 +66,7 @@
 #define vStr v0
 #define vMaskEnd v2
 
-ENTRY(strlen_v)
+ENTRY(strlen)
 
     mv pCopyStr, pStr
 L(loop):
@@ -84,4 +84,4 @@
 
     ret
 
-END(strlen_v)
+END(strlen)
diff --git a/libc/arch-riscv64/string/strncat.c b/libc/arch-riscv64/string/strncat.c
deleted file mode 100644
index 8c26b95..0000000
--- a/libc/arch-riscv64/string/strncat.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncat strncat_gc
-#include <upstream-openbsd/lib/libc/string/strncat.c>
diff --git a/libc/arch-riscv64/string/strncat_v.S b/libc/arch-riscv64/string/strncat_v.S
index adc768d..01cb14f 100644
--- a/libc/arch-riscv64/string/strncat_v.S
+++ b/libc/arch-riscv64/string/strncat_v.S
@@ -70,7 +70,7 @@
 #define vStr1 v8
 #define vStr2 v16
 
-ENTRY(strncat_v)
+ENTRY(strncat)
 
     mv pDstPtr, pDst
 
@@ -114,4 +114,4 @@
 L(fill_zero_end):
     ret
 
-END(strncat_v)
+END(strncat)
diff --git a/libc/arch-riscv64/string/strncmp.c b/libc/arch-riscv64/string/strncmp.c
deleted file mode 100644
index ebc5357..0000000
--- a/libc/arch-riscv64/string/strncmp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncmp strncmp_gc
-#include <upstream-openbsd/lib/libc/string/strncmp.c>
diff --git a/libc/arch-riscv64/string/strncmp_v.S b/libc/arch-riscv64/string/strncmp_v.S
index 1ce4817..b9e6ee2 100644
--- a/libc/arch-riscv64/string/strncmp_v.S
+++ b/libc/arch-riscv64/string/strncmp_v.S
@@ -71,7 +71,7 @@
 #define vMask1 v8
 #define vMask2 v9
 
-ENTRY(strncmp_v)
+ENTRY(strncmp)
 
     beqz iLength, L(zero_length)
 
@@ -116,4 +116,4 @@
     li iResult, 0
     ret
 
-END(strncmp_v)
+END(strncmp)
diff --git a/libc/arch-riscv64/string/strncpy.c b/libc/arch-riscv64/string/strncpy.c
deleted file mode 100644
index bbd1bd7..0000000
--- a/libc/arch-riscv64/string/strncpy.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncpy strncpy_gc
-#include <upstream-openbsd/lib/libc/string/strncpy.c>
diff --git a/libc/arch-riscv64/string/strncpy_v.S b/libc/arch-riscv64/string/strncpy_v.S
index f133f28..651a064 100644
--- a/libc/arch-riscv64/string/strncpy_v.S
+++ b/libc/arch-riscv64/string/strncpy_v.S
@@ -71,7 +71,7 @@
 #define vStr1 v8
 #define vStr2 v16
 
-ENTRY(strncpy_v)
+ENTRY(strncpy)
 
     mv pDstPtr, pDst
 
@@ -111,4 +111,4 @@
 
     ret
 
-END(strncpy_v)
+END(strncpy)
diff --git a/libc/arch-riscv64/string/strnlen.c b/libc/arch-riscv64/string/strnlen.c
deleted file mode 100644
index 0e31c3b..0000000
--- a/libc/arch-riscv64/string/strnlen.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*	$OpenBSD: strnlen.c,v 1.9 2019/01/25 00:19:25 millert Exp $	*/
-
-/*
- * Copyright (c) 2010 Todd C. Miller <[email protected]>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-
-#include <string.h>
-
-size_t
-strnlen_gc(const char *str, size_t maxlen)
-{
-	const char *cp;
-
-	for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
-		;
-
-	return (size_t)(cp - str);
-}
diff --git a/libc/arch-riscv64/string/strnlen_v.S b/libc/arch-riscv64/string/strnlen_v.S
index bd1bb9a..66366f0 100644
--- a/libc/arch-riscv64/string/strnlen_v.S
+++ b/libc/arch-riscv64/string/strnlen_v.S
@@ -66,7 +66,7 @@
 #define vStr v0
 #define vMaskEnd v8
 
-ENTRY(strnlen_v)
+ENTRY(strnlen)
 
     mv pCopyStr, pStr
     mv iRetValue, iMaxlen
@@ -86,4 +86,4 @@
 L(end_strnlen_loop):
     ret
 
-END(strnlen_v)
+END(strnlen)
diff --git a/libc/arch-x86/string/sse2-memchr-atom.S b/libc/arch-x86/string/sse2-memchr-atom.S
deleted file mode 100644
index 013af9b..0000000
--- a/libc/arch-x86/string/sse2-memchr-atom.S
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
-    * Neither the name of Intel Corporation nor the names of its contributors
-    * may be used to endorse or promote products derived from this software
-    * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef L
-# define L(label)	.L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc	.cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc	.cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg)	.cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name)	\
-	.type name,  @function;	\
-	.globl name;	\
-	.p2align 4;	\
-name:	\
-	cfi_startproc
-#endif
-
-#ifndef END
-# define END(name)	\
-	cfi_endproc;	\
-	.size name,	.-name
-#endif
-
-#define CFI_PUSH(REG)	\
-	cfi_adjust_cfa_offset (4);	\
-	cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG)	\
-	cfi_adjust_cfa_offset (-4);	\
-	cfi_restore (REG)
-
-#define PUSH(REG) pushl REG; CFI_PUSH (REG)
-#define POP(REG) popl REG; CFI_POP (REG)
-
-#define ENTRANCE PUSH (%edi);
-#define PARMS  8
-#define RETURN  POP (%edi); ret; CFI_PUSH (%edi);
-
-#define STR1  PARMS
-#define STR2  STR1+4
-#define LEN   STR2+4
-
-	.text
-ENTRY (memchr)
-	ENTRANCE
-	mov	STR1(%esp), %ecx
-	movd	STR2(%esp), %xmm1
-	mov	LEN(%esp), %edx
-	test	%edx, %edx
-	jz	L(return_null)
-
-	punpcklbw %xmm1, %xmm1
-	mov	%ecx, %edi
-	punpcklbw %xmm1, %xmm1
-
-	and	$63, %ecx
-	pshufd	$0, %xmm1, %xmm1
-	cmp	$48, %ecx
-	ja	L(crosscache)
-
-	movdqu	(%edi), %xmm0
-	pcmpeqb	%xmm1, %xmm0
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(match_case2_prolog)
-
-	sub	$16, %edx
-	jbe	L(return_null)
-	lea	16(%edi), %edi
-	and	$15, %ecx
-	and	$-16, %edi
-	add	%ecx, %edx
-	sub	$64, %edx
-	jbe	L(exit_loop)
-	jmp	L(loop_prolog)
-
-	.p2align 4
-L(crosscache):
-	and	$15, %ecx
-	and	$-16, %edi
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm1, %xmm0
-	pmovmskb %xmm0, %eax
-	sar	%cl, %eax
-	test	%eax, %eax
-
-	jnz	L(match_case2_prolog1)
-	lea	-16(%edx), %edx
-	add	%ecx, %edx
-	jle	L(return_null)
-	lea	16(%edi), %edi
-	sub	$64, %edx
-	jbe	L(exit_loop)
-
-	.p2align 4
-L(loop_prolog):
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm1, %xmm0
-	xor	%ecx, %ecx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	16(%edi), %xmm2
-	pcmpeqb	%xmm1, %xmm2
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm2, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	32(%edi), %xmm3
-	pcmpeqb	%xmm1, %xmm3
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm3, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	48(%edi), %xmm4
-	pcmpeqb	%xmm1, %xmm4
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm4, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	lea	64(%edi), %edi
-	sub	$64, %edx
-	jbe	L(exit_loop)
-
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm1, %xmm0
-	xor	%ecx, %ecx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	16(%edi), %xmm2
-	pcmpeqb	%xmm1, %xmm2
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm2, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	32(%edi), %xmm3
-	pcmpeqb	%xmm1, %xmm3
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm3, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	48(%edi), %xmm4
-	pcmpeqb	%xmm1, %xmm4
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm4, %eax
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	lea	64(%edi), %edi
-	mov	%edi, %ecx
-	and	$-64, %edi
-	and	$63, %ecx
-	add	%ecx, %edx
-
-	.p2align 4
-L(align64_loop):
-	sub	$64, %edx
-	jbe	L(exit_loop)
-	movdqa	(%edi), %xmm0
-	movdqa	16(%edi), %xmm2
-	movdqa	32(%edi), %xmm3
-	movdqa	48(%edi), %xmm4
-	pcmpeqb	%xmm1, %xmm0
-	pcmpeqb	%xmm1, %xmm2
-	pcmpeqb	%xmm1, %xmm3
-	pcmpeqb	%xmm1, %xmm4
-
-	pmaxub	%xmm0, %xmm3
-	pmaxub	%xmm2, %xmm4
-	pmaxub	%xmm3, %xmm4
-	add	$64, %edi
-	pmovmskb %xmm4, %eax
-
-	test	%eax, %eax
-	jz	L(align64_loop)
-
-	sub	$64, %edi
-
-	pmovmskb %xmm0, %eax
-	xor	%ecx, %ecx
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	pmovmskb %xmm2, %eax
-	lea	16(%ecx), %ecx
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	movdqa	32(%edi), %xmm3
-	pcmpeqb	%xmm1, %xmm3
-	pmovmskb %xmm3, %eax
-	lea	16(%ecx), %ecx
-	test	%eax, %eax
-	jnz	L(match_case1)
-
-	pcmpeqb	48(%edi), %xmm1
-	pmovmskb %xmm1, %eax
-	lea	16(%ecx), %ecx
-
-	.p2align 4
-L(match_case1):
-	add	%ecx, %edi
-	test	%al, %al
-	jz	L(match_case1_high)
-	mov	%al, %cl
-	and	$15, %cl
-	jz	L(match_case1_8)
-	test	$0x01, %al
-	jnz	L(exit_case1_1)
-	test	$0x02, %al
-	jnz	L(exit_case1_2)
-	test	$0x04, %al
-	jnz	L(exit_case1_3)
-	lea	3(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case1_8):
-	test	$0x10, %al
-	jnz	L(exit_case1_5)
-	test	$0x20, %al
-	jnz	L(exit_case1_6)
-	test	$0x40, %al
-	jnz	L(exit_case1_7)
-	lea	7(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case1_high):
-	mov	%ah, %ch
-	and	$15, %ch
-	jz	L(match_case1_high_8)
-	test	$0x01, %ah
-	jnz	L(exit_case1_9)
-	test	$0x02, %ah
-	jnz	L(exit_case1_10)
-	test	$0x04, %ah
-	jnz	L(exit_case1_11)
-	lea	11(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case1_high_8):
-	test	$0x10, %ah
-	jnz	L(exit_case1_13)
-	test	$0x20, %ah
-	jnz	L(exit_case1_14)
-	test	$0x40, %ah
-	jnz	L(exit_case1_15)
-	lea	15(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_loop):
-	add	$64, %edx
-
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm1, %xmm0
-	xor	%ecx, %ecx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(match_case2)
-	cmp	$16, %edx
-	jbe	L(return_null)
-
-	movdqa	16(%edi), %xmm2
-	pcmpeqb	%xmm1, %xmm2
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm2, %eax
-	test	%eax, %eax
-	jnz	L(match_case2)
-	cmp	$32, %edx
-	jbe	L(return_null)
-
-	movdqa	32(%edi), %xmm3
-	pcmpeqb	%xmm1, %xmm3
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm3, %eax
-	test	%eax, %eax
-	jnz	L(match_case2)
-	cmp	$48, %edx
-	jbe	L(return_null)
-
-	pcmpeqb	48(%edi), %xmm1
-	lea	16(%ecx), %ecx
-	pmovmskb %xmm1, %eax
-	test	%eax, %eax
-	jnz	L(match_case2)
-
-	xor	%eax, %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_1):
-	mov	%edi, %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_2):
-	lea	1(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_3):
-	lea	2(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_5):
-	lea	4(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_6):
-	lea	5(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_7):
-	lea	6(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_9):
-	lea	8(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_10):
-	lea	9(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_11):
-	lea	10(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_13):
-	lea	12(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_14):
-	lea	13(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case1_15):
-	lea	14(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case2):
-	sub	%ecx, %edx
-L(match_case2_prolog1):
-	add	%ecx, %edi
-L(match_case2_prolog):
-	test	%al, %al
-	jz	L(match_case2_high)
-	mov	%al, %cl
-	and	$15, %cl
-	jz	L(match_case2_8)
-	test	$0x01, %al
-	jnz	L(exit_case2_1)
-	test	$0x02, %al
-	jnz	L(exit_case2_2)
-	test	$0x04, %al
-	jnz	L(exit_case2_3)
-	sub	$4, %edx
-	jb	L(return_null)
-	lea	3(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case2_8):
-	test	$0x10, %al
-	jnz	L(exit_case2_5)
-	test	$0x20, %al
-	jnz	L(exit_case2_6)
-	test	$0x40, %al
-	jnz	L(exit_case2_7)
-	sub	$8, %edx
-	jb	L(return_null)
-	lea	7(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case2_high):
-	mov	%ah, %ch
-	and	$15, %ch
-	jz	L(match_case2_high_8)
-	test	$0x01, %ah
-	jnz	L(exit_case2_9)
-	test	$0x02, %ah
-	jnz	L(exit_case2_10)
-	test	$0x04, %ah
-	jnz	L(exit_case2_11)
-	sub	$12, %edx
-	jb	L(return_null)
-	lea	11(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case2_high_8):
-	test	$0x10, %ah
-	jnz	L(exit_case2_13)
-	test	$0x20, %ah
-	jnz	L(exit_case2_14)
-	test	$0x40, %ah
-	jnz	L(exit_case2_15)
-	sub	$16, %edx
-	jb	L(return_null)
-	lea	15(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_1):
-	mov	%edi, %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_2):
-	sub	$2, %edx
-	jb	L(return_null)
-	lea	1(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_3):
-	sub	$3, %edx
-	jb	L(return_null)
-	lea	2(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_5):
-	sub	$5, %edx
-	jb	L(return_null)
-	lea	4(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_6):
-	sub	$6, %edx
-	jb	L(return_null)
-	lea	5(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_7):
-	sub	$7, %edx
-	jb	L(return_null)
-	lea	6(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_9):
-	sub	$9, %edx
-	jb	L(return_null)
-	lea	8(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_10):
-	sub	$10, %edx
-	jb	L(return_null)
-	lea	9(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_11):
-	sub	$11, %edx
-	jb	L(return_null)
-	lea	10(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_13):
-	sub	$13, %edx
-	jb	L(return_null)
-	lea	12(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_14):
-	sub	$14, %edx
-	jb	L(return_null)
-	lea	13(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(exit_case2_15):
-	sub	$15, %edx
-	jb	L(return_null)
-	lea	14(%edi), %eax
-	RETURN
-	.p2align 4
-L(return_null):
-	xor	%eax, %eax
-	RETURN
-END (memchr)
diff --git a/libc/arch-x86/string/sse2-strchr-atom.S b/libc/arch-x86/string/sse2-strchr-atom.S
deleted file mode 100644
index e325181..0000000
--- a/libc/arch-x86/string/sse2-strchr-atom.S
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
-    * Neither the name of Intel Corporation nor the names of its contributors
-    * may be used to endorse or promote products derived from this software
-    * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef L
-# define L(label)	.L##label
-#endif
-
-#ifndef cfi_startproc
-# define cfi_startproc	.cfi_startproc
-#endif
-
-#ifndef cfi_endproc
-# define cfi_endproc	.cfi_endproc
-#endif
-
-#ifndef cfi_rel_offset
-# define cfi_rel_offset(reg, off)	.cfi_rel_offset reg, off
-#endif
-
-#ifndef cfi_restore
-# define cfi_restore(reg)	.cfi_restore reg
-#endif
-
-#ifndef cfi_adjust_cfa_offset
-# define cfi_adjust_cfa_offset(off)	.cfi_adjust_cfa_offset off
-#endif
-
-#ifndef ENTRY
-# define ENTRY(name)	\
-	.type name,  @function;	\
-	.globl name;	\
-	.p2align 4;	\
-name:	\
-	cfi_startproc
-#endif
-
-#ifndef END
-# define END(name)	\
-	cfi_endproc;	\
-	.size name,	.-name
-#endif
-
-#define CFI_PUSH(REG)	\
-	cfi_adjust_cfa_offset (4);	\
-	cfi_rel_offset (REG, 0)
-
-#define CFI_POP(REG)	\
-	cfi_adjust_cfa_offset (-4);	\
-	cfi_restore (REG)
-
-#define PUSH(REG)	pushl REG;	CFI_PUSH (REG)
-#define POP(REG)	popl REG;	CFI_POP (REG)
-
-#define PARMS	8
-#define ENTRANCE	PUSH(%edi)
-#define RETURN	POP (%edi); ret; CFI_PUSH (%edi);
-
-
-#define STR1	PARMS
-#define STR2	STR1+4
-
-	.text
-ENTRY (strchr)
-
-	ENTRANCE
-	mov	STR1(%esp), %ecx
-	movd	STR2(%esp), %xmm1
-
-	pxor	%xmm2, %xmm2
-	mov	%ecx, %edi
-	punpcklbw %xmm1, %xmm1
-	punpcklbw %xmm1, %xmm1
-	/* ECX has OFFSET. */
-	and	$15, %ecx
-	pshufd	$0, %xmm1, %xmm1
-	je	L(loop)
-
-/* Handle unaligned string.  */
-	and	$-16, %edi
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm0, %xmm2
-	pcmpeqb	%xmm1, %xmm0
-	/* Find where NULL is.  */
-	pmovmskb %xmm2, %edx
-	/* Check if there is a match.  */
-	pmovmskb %xmm0, %eax
-	/* Remove the leading bytes.  */
-	sarl	%cl, %edx
-	sarl	%cl, %eax
-	test	%eax, %eax
-	jz	L(unaligned_no_match)
-	add	%ecx, %edi
-	test	%edx, %edx
-	jz	L(match_case1)
-	jmp	L(match_case2)
-
-	.p2align 4
-L(unaligned_no_match):
-	test	%edx, %edx
-	jne	L(return_null)
-
-	pxor	%xmm2, %xmm2
-	add	$16, %edi
-
-	.p2align 4
-/* Loop start on aligned string.  */
-L(loop):
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm0, %xmm2
-	pcmpeqb	%xmm1, %xmm0
-	pmovmskb %xmm2, %edx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(matches)
-	test	%edx, %edx
-	jnz	L(return_null)
-	add	$16, %edi
-
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm0, %xmm2
-	pcmpeqb	%xmm1, %xmm0
-	pmovmskb %xmm2, %edx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(matches)
-	test	%edx, %edx
-	jnz	L(return_null)
-	add	$16, %edi
-
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm0, %xmm2
-	pcmpeqb	%xmm1, %xmm0
-	pmovmskb %xmm2, %edx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(matches)
-	test	%edx, %edx
-	jnz	L(return_null)
-	add	$16, %edi
-
-	movdqa	(%edi), %xmm0
-	pcmpeqb	%xmm0, %xmm2
-	pcmpeqb	%xmm1, %xmm0
-	pmovmskb %xmm2, %edx
-	pmovmskb %xmm0, %eax
-	test	%eax, %eax
-	jnz	L(matches)
-	test	%edx, %edx
-	jnz	L(return_null)
-	add	$16, %edi
-	jmp	L(loop)
-
-L(matches):
-	/* There is a match.  First find where NULL is.  */
-	test	%edx, %edx
-	jz	L(match_case1)
-
-	.p2align 4
-L(match_case2):
-	test	%al, %al
-	jz	L(match_higth_case2)
-
-	mov	%al, %cl
-	and	$15, %cl
-	jnz	L(match_case2_4)
-
-	mov	%dl, %ch
-	and	$15, %ch
-	jnz	L(return_null)
-
-	test	$0x10, %al
-	jnz	L(Exit5)
-	test	$0x10, %dl
-	jnz	L(return_null)
-	test	$0x20, %al
-	jnz	L(Exit6)
-	test	$0x20, %dl
-	jnz	L(return_null)
-	test	$0x40, %al
-	jnz	L(Exit7)
-	test	$0x40, %dl
-	jnz	L(return_null)
-	lea	7(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case2_4):
-	test	$0x01, %al
-	jnz	L(Exit1)
-	test	$0x01, %dl
-	jnz	L(return_null)
-	test	$0x02, %al
-	jnz	L(Exit2)
-	test	$0x02, %dl
-	jnz	L(return_null)
-	test	$0x04, %al
-	jnz	L(Exit3)
-	test	$0x04, %dl
-	jnz	L(return_null)
-	lea	3(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_higth_case2):
-	test	%dl, %dl
-	jnz	L(return_null)
-
-	mov	%ah, %cl
-	and	$15, %cl
-	jnz	L(match_case2_12)
-
-	mov	%dh, %ch
-	and	$15, %ch
-	jnz	L(return_null)
-
-	test	$0x10, %ah
-	jnz	L(Exit13)
-	test	$0x10, %dh
-	jnz	L(return_null)
-	test	$0x20, %ah
-	jnz	L(Exit14)
-	test	$0x20, %dh
-	jnz	L(return_null)
-	test	$0x40, %ah
-	jnz	L(Exit15)
-	test	$0x40, %dh
-	jnz	L(return_null)
-	lea	15(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case2_12):
-	test	$0x01, %ah
-	jnz	L(Exit9)
-	test	$0x01, %dh
-	jnz	L(return_null)
-	test	$0x02, %ah
-	jnz	L(Exit10)
-	test	$0x02, %dh
-	jnz	L(return_null)
-	test	$0x04, %ah
-	jnz	L(Exit11)
-	test	$0x04, %dh
-	jnz	L(return_null)
-	lea	11(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_case1):
-	test	%al, %al
-	jz	L(match_higth_case1)
-
-	test	$0x01, %al
-	jnz	L(Exit1)
-	test	$0x02, %al
-	jnz	L(Exit2)
-	test	$0x04, %al
-	jnz	L(Exit3)
-	test	$0x08, %al
-	jnz	L(Exit4)
-	test	$0x10, %al
-	jnz	L(Exit5)
-	test	$0x20, %al
-	jnz	L(Exit6)
-	test	$0x40, %al
-	jnz	L(Exit7)
-	lea	7(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(match_higth_case1):
-	test	$0x01, %ah
-	jnz	L(Exit9)
-	test	$0x02, %ah
-	jnz	L(Exit10)
-	test	$0x04, %ah
-	jnz	L(Exit11)
-	test	$0x08, %ah
-	jnz	L(Exit12)
-	test	$0x10, %ah
-	jnz	L(Exit13)
-	test	$0x20, %ah
-	jnz	L(Exit14)
-	test	$0x40, %ah
-	jnz	L(Exit15)
-	lea	15(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit1):
-	lea	(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit2):
-	lea	1(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit3):
-	lea	2(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit4):
-	lea	3(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit5):
-	lea	4(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit6):
-	lea	5(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit7):
-	lea	6(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit9):
-	lea	8(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit10):
-	lea	9(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit11):
-	lea	10(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit12):
-	lea	11(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit13):
-	lea	12(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit14):
-	lea	13(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(Exit15):
-	lea	14(%edi), %eax
-	RETURN
-
-	.p2align 4
-L(return_null):
-	xor	%eax, %eax
-	RETURN
-
-END (strchr)
diff --git a/libc/arch-x86/string/sse2-strnlen-atom.S b/libc/arch-x86/string/sse2-strnlen-atom.S
deleted file mode 100644
index 1f89b4e..0000000
--- a/libc/arch-x86/string/sse2-strnlen-atom.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-Copyright (c) 2011, Intel Corporation
-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.
-
-    * Neither the name of Intel Corporation nor the names of its contributors
-    * may be used to endorse or promote products derived from this software
-    * without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE 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.
-*/
-
-#define USE_AS_STRNLEN 1
-#define STRLEN  strnlen
-#include "sse2-strlen-atom.S"
diff --git a/libc/arch-x86_64/string/sse2-memmove-slm.S b/libc/arch-x86_64/string/sse2-memmove-slm.S
index 8b32680..b787385 100644
--- a/libc/arch-x86_64/string/sse2-memmove-slm.S
+++ b/libc/arch-x86_64/string/sse2-memmove-slm.S
@@ -79,18 +79,23 @@
 #endif
 
 #define CFI_PUSH(REG)		\
-	cfi_adjust_cfa_offset (4);		\
+	cfi_adjust_cfa_offset (8);		\
 	cfi_rel_offset (REG, 0)
 
 #define CFI_POP(REG)		\
-	cfi_adjust_cfa_offset (-4);		\
+	cfi_adjust_cfa_offset (-8);		\
 	cfi_restore (REG)
 
 #define PUSH(REG)	push REG;
 #define POP(REG)	pop REG;
 
-#define ENTRANCE	PUSH (%rbx);
-#define RETURN_END	POP (%rbx); ret
+#define ENTRANCE	\
+    PUSH (%rbx);    \
+    CFI_PUSH (%rbx);
+#define RETURN_END	\
+    POP (%rbx);     \
+    CFI_POP (%rbx); \
+    ret
 #define RETURN		RETURN_END;
 
 	.section .text.sse2,"ax",@progbits
diff --git a/libc/bionic/elf_note.cpp b/libc/bionic/elf_note.cpp
index 9cc6b21..28a400a 100644
--- a/libc/bionic/elf_note.cpp
+++ b/libc/bionic/elf_note.cpp
@@ -42,16 +42,18 @@
 
   ElfW(Addr) p = note_addr;
   ElfW(Addr) note_end = p + phdr_note->p_memsz;
-  while (p + sizeof(ElfW(Nhdr)) <= note_end) {
+  while (p < note_end) {
     // Parse the note and check it's structurally valid.
     const ElfW(Nhdr)* note = reinterpret_cast<const ElfW(Nhdr)*>(p);
-    p += sizeof(ElfW(Nhdr));
+    if (__builtin_add_overflow(p, sizeof(ElfW(Nhdr)), &p) || p >= note_end) {
+      return false;
+    }
     const char* name = reinterpret_cast<const char*>(p);
-    if (__builtin_add_overflow(p, align_up(note->n_namesz, 4), &p)) {
+    if (__builtin_add_overflow(p, __builtin_align_up(note->n_namesz, 4), &p)) {
       return false;
     }
     const char* desc = reinterpret_cast<const char*>(p);
-    if (__builtin_add_overflow(p, align_up(note->n_descsz, 4), &p)) {
+    if (__builtin_add_overflow(p, __builtin_align_up(note->n_descsz, 4), &p)) {
       return false;
     }
     if (p > note_end) {
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 126f002..9e15811 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -44,10 +44,12 @@
   size_t fini_array_count;
 } structors_array_t;
 
-__BEGIN_DECLS
-
+// The main function must not be declared with a linkage-specification
+// ('extern "C"' or 'extern "C++"'), so declare it before __BEGIN_DECLS.
 extern int main(int argc, char** argv, char** env);
 
+__BEGIN_DECLS
+
 __noreturn void __libc_init(void* raw_args,
                             void (*onexit)(void),
                             int (*slingshot)(int, char**, char**),
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 3fa8ee6..1bd2da7 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -129,7 +129,7 @@
   // Align the address to SCS_SIZE so that we only need to store the lower log2(SCS_SIZE) bits
   // 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));
+      reinterpret_cast<char*>(__builtin_align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
 
   // We need to ensure that [scs_offset,scs_offset+SCS_SIZE) is in the guard region and that there
   // is at least one unmapped page after the shadow call stack (to catch stack overflows). We can't
@@ -296,7 +296,7 @@
   // memory isn't counted in pthread_attr_getstacksize.
 
   // To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary.
-  stack_top = align_down(stack_top - sizeof(pthread_internal_t), 16);
+  stack_top = __builtin_align_down(stack_top - sizeof(pthread_internal_t), 16);
 
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
   if (!stack_clean) {
diff --git a/libc/bionic/strchr.cpp b/libc/bionic/strchr.cpp
deleted file mode 100644
index fd8a924..0000000
--- a/libc/bionic/strchr.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-char* strchr(const char* p, int ch) {
-  return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
-}
diff --git a/libc/include/bits/sockaddr_storage.h b/libc/include/bits/sockaddr_storage.h
index effafab..4b3bfb6 100644
--- a/libc/include/bits/sockaddr_storage.h
+++ b/libc/include/bits/sockaddr_storage.h
@@ -40,7 +40,7 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wnullability-completeness"
 /**
- * [sockaddr_storage](https://man7.org/linux/man-pages/man3/sockaddr.3type.html)
+ * [sockaddr_storage](https://man7.org/linux/man-pages/man3/sockaddr_storage.3type.html)
  * is a structure large enough to contain any other `sockaddr_*` type, used to
  * pass socket addresses without needing to know what kind of socket address
  * you're passing.
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 8058cfb..af22fb3 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -87,7 +87,7 @@
 
 #define d_fileno d_ino
 
-/** The structure returned by opendir()/fopendir(). */
+/** The structure returned by opendir()/fdopendir(). */
 typedef struct DIR DIR;
 
 /**
@@ -99,7 +99,7 @@
 DIR* _Nullable opendir(const char* _Nonnull __path);
 
 /**
- * [fopendir(3)](https://man7.org/linux/man-pages/man3/opendir.3.html)
+ * [fdopendir(3)](https://man7.org/linux/man-pages/man3/fdopendir.3.html)
  * opens a directory stream for the directory at `__dir_fd`.
  *
  * Returns null and sets `errno` on failure.
@@ -176,13 +176,13 @@
 int dirfd(DIR* _Nonnull __dir);
 
 /**
- * [alphasort](https://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * [alphasort(3)](https://man7.org/linux/man-pages/man3/alphasort.3.html) is a
  * comparator for use with scandir() that uses strcoll().
  */
 int alphasort(const struct dirent* _Nonnull * _Nonnull __lhs, const struct dirent* _Nonnull * _Nonnull __rhs);
 
 /**
- * [alphasort64](https://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * [alphasort64(3)](https://man7.org/linux/man-pages/man3/alphasort.3.html) is a
  * comparator for use with scandir64() that uses strcmp().
  */
 int alphasort64(const struct dirent64* _Nonnull * _Nonnull __lhs, const struct dirent64* _Nonnull * _Nonnull __rhs);
diff --git a/libc/include/err.h b/libc/include/err.h
index 4a1841b..81b11e3 100644
--- a/libc/include/err.h
+++ b/libc/include/err.h
@@ -74,7 +74,7 @@
 __noreturn void errx(int __status, const char* _Nullable __fmt, ...) __printflike(2, 3);
 
 /**
- * [verrx(3)](https://man7.org/linux/man-pages/man3/err.3.html) outputs the program name, and
+ * [verrx(3)](https://man7.org/linux/man-pages/man3/verrx.3.html) outputs the program name, and
  * the vprintf()-like formatted message.
  *
  * Calls exit() with `__status`.
@@ -108,7 +108,7 @@
 void warnx(const char* _Nullable __fmt, ...) __printflike(1, 2);
 
 /**
- * [vwarnx(3)](https://man7.org/linux/man-pages/man3/warn.3.html) outputs the program name, and
+ * [vwarnx(3)](https://man7.org/linux/man-pages/man3/vwarnx.3.html) outputs the program name, and
  * the vprintf()-like formatted message.
  *
  * New code should consider error() in `<error.h>`.
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 1a30eb7..56892aa 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -70,12 +70,12 @@
 __BEGIN_DECLS
 
 /**
- * [getopt_long(3)](https://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
+ * [getopt_long(3)](https://man7.org/linux/man-pages/man3/getopt_long.3.html) parses command-line options.
  */
 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)](https://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
+ * [getopt_long_only(3)](https://man7.org/linux/man-pages/man3/getopt_long_only.3.html) parses command-line options.
  */
 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);
 
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index ac27467..ba68401 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -77,8 +77,8 @@
 __nodiscard void* _Nullable realloc(void* _Nullable __ptr, size_t __byte_count) __BIONIC_ALLOC_SIZE(2);
 
 /**
- * [reallocarray(3)](https://man7.org/linux/man-pages/man3/realloc.3.html) resizes
- * allocated memory on the heap.
+ * [reallocarray(3)](https://man7.org/linux/man-pages/man3/reallocarray.3.html)
+ * resizes allocated memory on the heap.
  *
  * Equivalent to `realloc(__ptr, __item_count * __item_size)` but fails if the
  * multiplication overflows.
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 7a2dcad..58dd9a6 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -236,12 +236,12 @@
 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
+ * [CPU_ZERO](https://man7.org/linux/man-pages/man3/CPU_ZERO.3.html) clears all
  * bits in a static CPU set.
  */
 #define CPU_ZERO(set)          CPU_ZERO_S(sizeof(cpu_set_t), set)
 /**
- * [CPU_ZERO_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
+ * [CPU_ZERO_S](https://man7.org/linux/man-pages/man3/CPU_ZERO_S.3.html) clears all
  * bits in a dynamic CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_ZERO_S(setsize, set)  __builtin_memset(set, 0, setsize)
@@ -252,7 +252,7 @@
  */
 #define CPU_SET(cpu, set)      CPU_SET_S(cpu, sizeof(cpu_set_t), set)
 /**
- * [CPU_SET_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) sets one
+ * [CPU_SET_S](https://man7.org/linux/man-pages/man3/CPU_SET_S.3.html) sets one
  * bit in a dynamic CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_SET_S(cpu, setsize, set) \
@@ -263,12 +263,12 @@
   } while (0)
 
 /**
- * [CPU_CLR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears one
+ * [CPU_CLR](https://man7.org/linux/man-pages/man3/CPU_CLR.3.html) clears one
  * bit in a static CPU set.
  */
 #define CPU_CLR(cpu, set)      CPU_CLR_S(cpu, sizeof(cpu_set_t), set)
 /**
- * [CPU_CLR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears one
+ * [CPU_CLR_S](https://man7.org/linux/man-pages/man3/CPU_CLR_S.3.html) clears one
  * bit in a dynamic CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_CLR_S(cpu, setsize, set) \
@@ -279,12 +279,12 @@
   } while (0)
 
 /**
- * [CPU_ISSET](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_ISSET](https://man7.org/linux/man-pages/man3/CPU_ISSET.3.html) tests
  * whether the given bit is set in a static CPU set.
  */
 #define CPU_ISSET(cpu, set)    CPU_ISSET_S(cpu, sizeof(cpu_set_t), set)
 /**
- * [CPU_ISSET_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_ISSET_S](https://man7.org/linux/man-pages/man3/CPU_ISSET_S.3.html) tests
  * whether the given bit is set in a dynamic CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_ISSET_S(cpu, setsize, set) \
@@ -296,58 +296,58 @@
   }))
 
 /**
- * [CPU_COUNT](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) counts
+ * [CPU_COUNT](https://man7.org/linux/man-pages/man3/CPU_COUNT.3.html) counts
  * how many bits are set in a static CPU set.
  */
 #define CPU_COUNT(set)         CPU_COUNT_S(sizeof(cpu_set_t), set)
 /**
- * [CPU_COUNT_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) counts
+ * [CPU_COUNT_S](https://man7.org/linux/man-pages/man3/CPU_COUNT_S.3.html) counts
  * 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* _Nonnull __set);
 
 /**
- * [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_EQUAL.3.html) tests
  * whether two static CPU sets have the same bits set and cleared as each other.
  */
 #define CPU_EQUAL(set1, set2)  CPU_EQUAL_S(sizeof(cpu_set_t), set1, set2)
 /**
- * [CPU_EQUAL_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * [CPU_EQUAL_S](https://man7.org/linux/man-pages/man3/CPU_EQUAL_S.3.html) tests
  * whether two dynamic CPU sets allocated by `CPU_ALLOC` have the same bits
  * set and cleared as each other.
  */
 #define CPU_EQUAL_S(setsize, set1, set2)  (__builtin_memcmp(set1, set2, setsize) == 0)
 
 /**
- * [CPU_AND](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ands two
+ * [CPU_AND](https://man7.org/linux/man-pages/man3/CPU_AND.3.html) ands two
  * static CPU sets.
  */
 #define CPU_AND(dst, set1, set2)  __CPU_OP(dst, set1, set2, &)
 /**
- * [CPU_AND_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ands two
+ * [CPU_AND_S](https://man7.org/linux/man-pages/man3/CPU_AND_S.3.html) ands two
  * dynamic CPU sets allocated by `CPU_ALLOC`.
  */
 #define CPU_AND_S(setsize, dst, set1, set2)  __CPU_OP_S(setsize, dst, set1, set2, &)
 
 /**
- * [CPU_OR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ors two
+ * [CPU_OR](https://man7.org/linux/man-pages/man3/CPU_OR.3.html) ors two
  * static CPU sets.
  */
 #define CPU_OR(dst, set1, set2)   __CPU_OP(dst, set1, set2, |)
 /**
- * [CPU_OR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ors two
+ * [CPU_OR_S](https://man7.org/linux/man-pages/man3/CPU_OR_S.3.html) ors two
  * dynamic CPU sets allocated by `CPU_ALLOC`.
  */
 #define CPU_OR_S(setsize, dst, set1, set2)   __CPU_OP_S(setsize, dst, set1, set2, |)
 
 /**
- * [CPU_XOR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_XOR](https://man7.org/linux/man-pages/man3/CPU_XOR.3.html)
  * exclusive-ors two static CPU sets.
  */
 #define CPU_XOR(dst, set1, set2)  __CPU_OP(dst, set1, set2, ^)
 /**
- * [CPU_XOR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_XOR_S](https://man7.org/linux/man-pages/man3/CPU_XOR_S.3.html)
  * exclusive-ors two dynamic CPU sets allocated by `CPU_ALLOC`.
  */
 #define CPU_XOR_S(setsize, dst, set1, set2)  __CPU_OP_S(setsize, dst, set1, set2, ^)
@@ -365,21 +365,21 @@
   } while (0)
 
 /**
- * [CPU_ALLOC_SIZE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_ALLOC_SIZE](https://man7.org/linux/man-pages/man3/CPU_ALLOC_SIZE.3.html)
  * returns the size of a CPU set large enough for CPUs in the range 0..count-1.
  */
 #define CPU_ALLOC_SIZE(count) \
   __CPU_ELT((count) + (__CPU_BITS - 1)) * sizeof(__CPU_BITTYPE)
 
 /**
- * [CPU_ALLOC](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_ALLOC](https://man7.org/linux/man-pages/man3/CPU_ALLOC.3.html)
  * allocates a CPU set large enough for CPUs in the range 0..count-1.
  */
 #define CPU_ALLOC(count)  __sched_cpualloc((count))
 cpu_set_t* _Nullable __sched_cpualloc(size_t __count);
 
 /**
- * [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_FREE.3.html)
  * deallocates a CPU set allocated by `CPU_ALLOC`.
  */
 #define CPU_FREE(set)     __sched_cpufree((set))
diff --git a/libc/include/string.h b/libc/include/string.h
index 79aac91..a0a7cc4 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -160,7 +160,7 @@
 #endif
 
 /**
- * [strerrorname_np(3)](https://man7.org/linux/man-pages/man3/strerrordesc_np.3.html)
+ * [strerrorname_np(3)](https://man7.org/linux/man-pages/man3/strerrorname_np.3.html)
  * returns the name of the errno constant corresponding to its argument.
  * `strerrorname_np(38)` would return "ENOSYS", because `ENOSYS` is errno 38. This
  * is mostly useful for error reporting in cases where a string like "ENOSYS" is
diff --git a/libc/include/sys/klog.h b/libc/include/sys/klog.h
index 237d2e2..6ee410f 100644
--- a/libc/include/sys/klog.h
+++ b/libc/include/sys/klog.h
@@ -61,7 +61,7 @@
 #define KLOG_SIZE_BUFFER 10
 
 /**
- * [klogctl(2)](https://man7.org/linux/man-pages/man2/syslog.2.html) operates on the kernel log.
+ * [klogctl(3)](https://man7.org/linux/man-pages/man2/klogctl.3.html) operates on the kernel log.
  *
  * This system call is not available to applications.
  * Use syslog() or `<android/log.h>` instead.
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 38cbf2f..3fe1f9c 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -126,7 +126,7 @@
 int mlock(const void* _Nonnull __addr, size_t __size);
 
 /**
- * [mlock2(2)](https://man7.org/linux/man-pages/man2/mlock.2.html)
+ * [mlock2(2)](https://man7.org/linux/man-pages/man2/mlock2.2.html)
  * locks pages (preventing swapping), with optional flags.
  *
  * Available since API level 30.
diff --git a/libc/include/sys/pidfd.h b/libc/include/sys/pidfd.h
index aaf49c9..bd2b01e 100644
--- a/libc/include/sys/pidfd.h
+++ b/libc/include/sys/pidfd.h
@@ -54,7 +54,7 @@
 int pidfd_open(pid_t __pid, unsigned int __flags) __INTRODUCED_IN(31);
 
 /**
- * [pidfd_getfd(2)](https://man7.org/linux/man-pages/man2/pidfd_open.2.html)
+ * [pidfd_getfd(2)](https://man7.org/linux/man-pages/man2/pidfd_getfd.2.html)
  * dups a file descriptor from another process. This file descriptor will have
  * the close-on-exec flag set by default.
  *
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index a7227b0..685e6ac 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -30,7 +30,9 @@
 
 /**
  * @file sys/select.h
- * @brief Wait for events on a set of file descriptors (but use <poll.h> instead).
+ * @brief Wait for events on a set of file descriptors.
+ * New code should prefer the different interface specified in <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
  */
 
 #include <sys/cdefs.h>
@@ -44,8 +46,10 @@
 typedef unsigned long fd_mask;
 
 /**
- * The limit on the largest fd that can be used with fd_set.
- * Use <poll.h> instead.
+ * The limit on the largest fd that can be used with type `fd_set`.
+ * You can allocate your own memory,
+ * but new code should prefer the different interface specified in <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
  */
 #define FD_SETSIZE 1024
 #define NFDBITS (8 * sizeof(fd_mask))
@@ -55,7 +59,8 @@
  * The underlying system calls do not have this limit,
  * and callers can allocate their own sets with calloc().
  *
- * Use <poll.h> instead.
+ * New code should prefer the different interface specified in <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
  */
 typedef struct {
   fd_mask fds_bits[FD_SETSIZE/NFDBITS];
@@ -69,28 +74,62 @@
 void __FD_SET_chk(int, fd_set* _Nonnull, size_t);
 int __FD_ISSET_chk(int, const fd_set* _Nonnull, size_t);
 
-/** FD_CLR() with no bounds checking for users that allocated their own set. */
+/**
+ * FD_CLR() with no bounds checking for users that allocated their own set.
+ * New code should prefer <poll.h> instead.
+ */
 #define __FD_CLR(fd, set) (__FDS_BITS(fd_set*, set)[__FDELT(fd)] &= ~__FDMASK(fd))
-/** FD_SET() with no bounds checking for users that allocated their own set. */
+
+/**
+ * FD_SET() with no bounds checking for users that allocated their own set.
+ * New code should prefer <poll.h> instead.
+ */
 #define __FD_SET(fd, set) (__FDS_BITS(fd_set*, set)[__FDELT(fd)] |= __FDMASK(fd))
-/** FD_ISSET() with no bounds checking for users that allocated their own set. */
+
+/**
+ * FD_ISSET() with no bounds checking for users that allocated their own set.
+ * New code should prefer <poll.h> instead.
+ */
 #define __FD_ISSET(fd, set) ((__FDS_BITS(const fd_set*, set)[__FDELT(fd)] & __FDMASK(fd)) != 0)
 
-/** Removes all 1024 fds from the given set. Use <poll.h> instead. */
+/**
+ * Removes all 1024 fds from the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using memset() directly.
+ */
 #define FD_ZERO(set) __builtin_memset(set, 0, sizeof(*__BIONIC_CAST(static_cast, const fd_set*, set)))
 
-/** Removes `fd` from the given set. Limited to fds under 1024. Use <poll.h> instead. */
+/**
+ * Removes `fd` from the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using __FD_CLR().
+ */
 #define FD_CLR(fd, set) __FD_CLR_chk(fd, set, __bos(set))
-/** Adds `fd` to the given set. Limited to fds under 1024. Use <poll.h> instead. */
+
+/**
+ * Adds `fd` to the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using __FD_SET().
+ */
 #define FD_SET(fd, set) __FD_SET_chk(fd, set, __bos(set))
-/** Tests whether `fd` is in the given set. Limited to fds under 1024. Use <poll.h> instead. */
+
+/**
+ * Tests whether `fd` is in the given set.
+ * Limited to fds under 1024.
+ * New code should prefer <poll.h> instead for this reason,
+ * rather than using __FD_ISSET().
+ */
 #define FD_ISSET(fd, set) __FD_ISSET_chk(fd, set, __bos(set))
 
 /**
  * [select(2)](https://man7.org/linux/man-pages/man2/select.2.html) waits on a
  * set of file descriptors.
  *
- * Use poll() instead.
+ * New code should prefer poll() from <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
  *
  * Returns the number of ready file descriptors on success, 0 for timeout,
  * and returns -1 and sets `errno` on failure.
@@ -98,10 +137,11 @@
 int select(int __max_fd_plus_one, fd_set* _Nullable __read_fds, fd_set* _Nullable __write_fds, fd_set* _Nullable __exception_fds, struct timeval* _Nullable __timeout);
 
 /**
- * [pselect(2)](https://man7.org/linux/man-pages/man2/select.2.html) waits on a
+ * [pselect(2)](https://man7.org/linux/man-pages/man2/pselect.2.html) waits on a
  * set of file descriptors.
  *
- * Use ppoll() instead.
+ * New code should prefer ppoll() from <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
  *
  * Returns the number of ready file descriptors on success, 0 for timeout,
  * and returns -1 and sets `errno` on failure.
@@ -112,17 +152,16 @@
  * [pselect64(2)](https://man7.org/linux/man-pages/man2/select.2.html) waits on a
  * set of file descriptors.
  *
- * Use ppoll64() instead.
+ * New code should prefer ppoll64() from <poll.h> instead,
+ * because it scales better and easily avoids the limits on `fd_set` size.
  *
  * Returns the number of ready file descriptors on success, 0 for timeout,
  * and returns -1 and sets `errno` on failure.
  *
  * Available since API level 28.
  */
-
 #if __BIONIC_AVAILABILITY_GUARD(28)
 int pselect64(int __max_fd_plus_one, fd_set* _Nullable __read_fds, fd_set* _Nullable __write_fds, fd_set* _Nullable __exception_fds, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
 #endif /* __BIONIC_AVAILABILITY_GUARD(28) */
 
-
 __END_DECLS
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 0b4b248..12bfedc 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -216,10 +216,10 @@
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
  */
-int fstatat(int __dir_fd, const char* _Nonnull __path, struct stat* _Nonnull __buf, int __flags);
+int fstatat(int __dir_fd, const char* _Nullable __path, struct stat* _Nonnull __buf, int __flags);
 
 /** An alias for fstatat(). */
-int fstatat64(int __dir_fd, const char* _Nonnull __path, struct stat64* _Nonnull __buf, int __flags);
+int fstatat64(int __dir_fd, const char* _Nullable __path, struct stat64* _Nonnull __buf, int __flags);
 
 /**
  * [lstat(2)](https://man7.org/linux/man-pages/man2/lstat.2.html)
@@ -320,7 +320,7 @@
 int utimensat(int __dir_fd, const char* __BIONIC_COMPLICATED_NULLNESS __path, const struct timespec __times[_Nullable 2], int __flags);
 
 /**
- * [futimens(2)](https://man7.org/linux/man-pages/man2/utimensat.2.html) sets
+ * [futimens(3)](https://man7.org/linux/man-pages/man3/futimens.3.html) sets
  * the given file descriptor's timestamp.
  *
  * `__times[0]` is the access time (atime), and `__times[1]` the last modification time (mtime).
diff --git a/libc/include/time.h b/libc/include/time.h
index 6c9b761..777e648 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -281,7 +281,7 @@
 char* _Nullable ctime(const time_t* _Nonnull __t);
 
 /**
- * [ctime_r(3)](https://man7.org/linux/man-pages/man3/ctime.3p.html) formats
+ * [ctime_r(3)](https://man7.org/linux/man-pages/man3/ctime_r.3p.html) formats
  * the time `tm` as a string in the given buffer `buf`.
  *
  * Returns a pointer to a string on success, and returns NULL on failure.
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index e623339..808568a 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -283,7 +283,7 @@
 int chdir(const char* _Nonnull __path);
 
 /**
- * [fchdir(2)](https://man7.org/linux/man-pages/man2/chdir.2.html) changes
+ * [fchdir(2)](https://man7.org/linux/man-pages/man2/fchdir.2.html) changes
  * the current working directory to the given fd.
  *
  * This function affects all threads in the process, so is generally a bad idea
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index f5c720a..45cc945 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -101,4 +101,5 @@
 #define HWCAP2_SME_SF8FMA (1UL << 60)
 #define HWCAP2_SME_SF8DP4 (1UL << 61)
 #define HWCAP2_SME_SF8DP2 (1UL << 62)
+#define HWCAP2_POE (1UL << 63)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/mman.h b/libc/kernel/uapi/asm-arm64/asm/mman.h
index 1561053..cc92abe 100644
--- a/libc/kernel/uapi/asm-arm64/asm/mman.h
+++ b/libc/kernel/uapi/asm-arm64/asm/mman.h
@@ -9,4 +9,8 @@
 #include <asm-generic/mman.h>
 #define PROT_BTI 0x10
 #define PROT_MTE 0x20
+#define PKEY_DISABLE_EXECUTE 0x4
+#define PKEY_DISABLE_READ 0x8
+#undef PKEY_ACCESS_MASK
+#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE | PKEY_DISABLE_READ | PKEY_DISABLE_EXECUTE)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 8e48d55..a845a03 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -32,6 +32,11 @@
   struct _aarch64_ctx head;
   __u64 esr;
 };
+#define POE_MAGIC 0x504f4530
+struct poe_context {
+  struct _aarch64_ctx head;
+  __u64 por_el0;
+};
 #define EXTRA_MAGIC 0x45585401
 struct extra_context {
   struct _aarch64_ctx head;
@@ -95,12 +100,12 @@
 #define SVE_SIG_REGS_SIZE(vq) (__SVE_FFR_OFFSET(vq) + __SVE_FFR_SIZE(vq))
 #define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
 #define ZA_SIG_REGS_OFFSET ((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1)) / __SVE_VQ_BYTES * __SVE_VQ_BYTES)
-#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
-#define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * n))
+#define ZA_SIG_REGS_SIZE(vq) (((vq) * __SVE_VQ_BYTES) * ((vq) * __SVE_VQ_BYTES))
+#define ZA_SIG_ZAV_OFFSET(vq,n) (ZA_SIG_REGS_OFFSET + (SVE_SIG_ZREG_SIZE(vq) * (n)))
 #define ZA_SIG_CONTEXT_SIZE(vq) (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
 #define ZT_SIG_REG_SIZE 512
 #define ZT_SIG_REG_BYTES (ZT_SIG_REG_SIZE / 8)
 #define ZT_SIG_REGS_OFFSET sizeof(struct zt_context)
-#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n)
+#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * (n))
 #define ZT_SIG_CONTEXT_SIZE(n) (sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n))
 #endif
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 2d90586..a580c4c 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -92,6 +92,11 @@
 #define SO_RCVMARK 75
 #define SO_PASSPIDFD 76
 #define SO_PEERPIDFD 77
+#define SO_DEVMEM_LINEAR 78
+#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
+#define SO_DEVMEM_DMABUF 79
+#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
+#define SO_DEVMEM_DONTNEED 80
 #if __BITS_PER_LONG == 64 || defined(__x86_64__) && defined(__ILP32__)
 #define SO_TIMESTAMP SO_TIMESTAMP_OLD
 #define SO_TIMESTAMPNS SO_TIMESTAMPNS_OLD
diff --git a/libc/kernel/uapi/asm-x86/asm/elf.h b/libc/kernel/uapi/asm-x86/asm/elf.h
new file mode 100644
index 0000000..b66a229
--- /dev/null
+++ b/libc/kernel/uapi/asm-x86/asm/elf.h
@@ -0,0 +1,16 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_X86_ELF_H
+#define _UAPI_ASM_X86_ELF_H
+#include <linux/types.h>
+struct x86_xfeat_component {
+  __u32 type;
+  __u32 size;
+  __u32 offset;
+  __u32 flags;
+} __attribute__((__packed__));
+#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index cd647b6..0a35412 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -342,6 +342,7 @@
 #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4)
 #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5)
 #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6)
+#define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7)
 #define KVM_STATE_NESTED_FORMAT_VMX 0
 #define KVM_STATE_NESTED_FORMAT_SVM 1
 #define KVM_STATE_NESTED_GUEST_MODE 0x00000001
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 4902d6c..c0f5ff1 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -172,6 +172,8 @@
 #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS fourcc_mod_code(INTEL, 13)
 #define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS fourcc_mod_code(INTEL, 14)
 #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15)
+#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16)
+#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17)
 #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
 #define DRM_FORMAT_MOD_SAMSUNG_16_16_TILE fourcc_mod_code(SAMSUNG, 2)
 #define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 7ec5ed2..582da62 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -38,6 +38,8 @@
 #define MSM_PARAM_VA_SIZE 0x0f
 #define MSM_PARAM_HIGHEST_BANK_BIT 0x10
 #define MSM_PARAM_RAYTRACING 0x11
+#define MSM_PARAM_UBWC_SWIZZLE 0x12
+#define MSM_PARAM_MACROTILE_MODE 0x13
 #define MSM_PARAM_NR_RINGS MSM_PARAM_PRIORITIES
 struct drm_msm_param {
   __u32 pipe;
diff --git a/libc/kernel/uapi/drm/xe_drm.h b/libc/kernel/uapi/drm/xe_drm.h
index a034b29..16bc3b3 100644
--- a/libc/kernel/uapi/drm/xe_drm.h
+++ b/libc/kernel/uapi/drm/xe_drm.h
@@ -124,6 +124,7 @@
 #define DRM_XE_TOPO_DSS_COMPUTE 2
 #define DRM_XE_TOPO_L3_BANK 3
 #define DRM_XE_TOPO_EU_PER_DSS 4
+#define DRM_XE_TOPO_SIMD16_EU_PER_DSS 5
   __u16 type;
   __u32 num_bytes;
   __u8 mask[];
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 6e64ebc..273ee59 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -115,6 +115,11 @@
   __u32 sync_recv;
   __u32 async_recv;
 };
+struct binder_frozen_state_info {
+  binder_uintptr_t cookie;
+  __u32 is_frozen;
+  __u32 reserved;
+};
 struct binder_extended_error {
   __u32 id;
   __u32 command;
@@ -212,6 +217,8 @@
   BR_FROZEN_REPLY = _IO('r', 18),
   BR_ONEWAY_SPAM_SUSPECT = _IO('r', 19),
   BR_TRANSACTION_PENDING_FROZEN = _IO('r', 20),
+  BR_FROZEN_BINDER = _IOR('r', 21, struct binder_frozen_state_info),
+  BR_CLEAR_FREEZE_NOTIFICATION_DONE = _IOR('r', 22, binder_uintptr_t),
 };
 enum binder_driver_command_protocol {
   BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
@@ -233,5 +240,8 @@
   BC_DEAD_BINDER_DONE = _IOW('c', 16, binder_uintptr_t),
   BC_TRANSACTION_SG = _IOW('c', 17, struct binder_transaction_data_sg),
   BC_REPLY_SG = _IOW('c', 18, struct binder_transaction_data_sg),
+  BC_REQUEST_FREEZE_NOTIFICATION = _IOW('c', 19, struct binder_handle_cookie),
+  BC_CLEAR_FREEZE_NOTIFICATION = _IOW('c', 20, struct binder_handle_cookie),
+  BC_FREEZE_NOTIFICATION_DONE = _IOW('c', 21, binder_uintptr_t),
 };
 #endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 98849f1..ae50fcc 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -95,6 +95,9 @@
 #define AUDIT_MAC_UNLBL_STCDEL 1417
 #define AUDIT_MAC_CALIPSO_ADD 1418
 #define AUDIT_MAC_CALIPSO_DEL 1419
+#define AUDIT_IPE_ACCESS 1420
+#define AUDIT_IPE_CONFIG_CHANGE 1421
+#define AUDIT_IPE_POLICY_LOAD 1422
 #define AUDIT_FIRST_KERN_ANOM_MSG 1700
 #define AUDIT_LAST_KERN_ANOM_MSG 1799
 #define AUDIT_ANOM_PROMISCUOUS 1700
diff --git a/libc/kernel/uapi/linux/auto_fs.h b/libc/kernel/uapi/linux/auto_fs.h
index dd11a93..a48a887 100644
--- a/libc/kernel/uapi/linux/auto_fs.h
+++ b/libc/kernel/uapi/linux/auto_fs.h
@@ -12,7 +12,7 @@
 #define AUTOFS_PROTO_VERSION 5
 #define AUTOFS_MIN_PROTO_VERSION 3
 #define AUTOFS_MAX_PROTO_VERSION 5
-#define AUTOFS_PROTO_SUBVERSION 5
+#define AUTOFS_PROTO_SUBVERSION 6
 #if defined(__ia64__) || defined(__alpha__)
 typedef unsigned long autofs_wqt_t;
 #else
diff --git a/libc/kernel/uapi/linux/bits.h b/libc/kernel/uapi/linux/bits.h
index d747e24..2b8dbe2 100644
--- a/libc/kernel/uapi/linux/bits.h
+++ b/libc/kernel/uapi/linux/bits.h
@@ -8,4 +8,5 @@
 #define _UAPI_LINUX_BITS_H
 #define __GENMASK(h,l) (((~_UL(0)) - (_UL(1) << (l)) + 1) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
 #define __GENMASK_ULL(h,l) (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
+#define __GENMASK_U128(h,l) ((_BIT128((h)) << 1) - (_BIT128(l)))
 #endif
diff --git a/libc/kernel/uapi/linux/blkdev.h b/libc/kernel/uapi/linux/blkdev.h
new file mode 100644
index 0000000..103fa0f
--- /dev/null
+++ b/libc/kernel/uapi/linux/blkdev.h
@@ -0,0 +1,12 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_BLKDEV_H
+#define _UAPI_LINUX_BLKDEV_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define BLOCK_URING_CMD_DISCARD _IO(0x12, 0)
+#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 8d64816..c0d862d 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -671,9 +671,6 @@
   BPF_F_MARK_ENFORCE = (1ULL << 6),
 };
 enum {
-  BPF_F_INGRESS = (1ULL << 0),
-};
-enum {
   BPF_F_TUNINFO_IPV6 = (1ULL << 0),
 };
 enum {
@@ -768,8 +765,10 @@
   BPF_F_BPRM_SECUREEXEC = (1ULL << 0),
 };
 enum {
+  BPF_F_INGRESS = (1ULL << 0),
   BPF_F_BROADCAST = (1ULL << 3),
   BPF_F_EXCLUDE_INGRESS = (1ULL << 4),
+#define BPF_F_REDIRECT_FLAGS (BPF_F_INGRESS | BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS)
 };
 #define __bpf_md_ptr(type,name) union { type name; __u64 : 64; \
 } __attribute__((aligned(8)))
@@ -1275,6 +1274,7 @@
   TCP_BPF_SYN = 1005,
   TCP_BPF_SYN_IP = 1006,
   TCP_BPF_SYN_MAC = 1007,
+  TCP_BPF_SOCK_OPS_CB_FLAGS = 1008,
 };
 enum {
   BPF_LOAD_HDR_OPT_TCP_SYN = (1ULL << 0),
@@ -1528,4 +1528,7 @@
 struct bpf_iter_num {
   __u64 __opaque[1];
 } __attribute__((aligned(8)));
+enum bpf_kfunc_flags {
+  BPF_F_PAD_ZEROS = (1ULL << 0),
+};
 #endif
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 43e8456..91f4d67 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -27,6 +27,7 @@
 };
 #define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0)
 #define CEC_MSG_FL_RAW (1 << 1)
+#define CEC_MSG_FL_REPLY_VENDOR_ID (1 << 2)
 #define CEC_TX_STATUS_OK (1 << 0)
 #define CEC_TX_STATUS_ARB_LOST (1 << 1)
 #define CEC_TX_STATUS_NACK (1 << 2)
@@ -96,6 +97,7 @@
 #define CEC_CAP_NEEDS_HPD (1 << 6)
 #define CEC_CAP_MONITOR_PIN (1 << 7)
 #define CEC_CAP_CONNECTOR_INFO (1 << 8)
+#define CEC_CAP_REPLY_VENDOR_ID (1 << 9)
 struct cec_caps {
   char driver[32];
   char name[32];
diff --git a/libc/kernel/uapi/linux/const.h b/libc/kernel/uapi/linux/const.h
index c091f8d..b45b722 100644
--- a/libc/kernel/uapi/linux/const.h
+++ b/libc/kernel/uapi/linux/const.h
@@ -18,6 +18,9 @@
 #define _ULL(x) (_AC(x, ULL))
 #define _BITUL(x) (_UL(1) << (x))
 #define _BITULL(x) (_ULL(1) << (x))
+#ifndef __ASSEMBLY__
+#define _BIT128(x) ((unsigned __int128) (1) << (x))
+#endif
 #define __ALIGN_KERNEL(x,a) __ALIGN_KERNEL_MASK(x, (__typeof__(x)) (a) - 1)
 #define __ALIGN_KERNEL_MASK(x,mask) (((x) + (mask)) & ~(mask))
 #define __KERNEL_DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
diff --git a/libc/kernel/uapi/linux/dpll.h b/libc/kernel/uapi/linux/dpll.h
index dd692f6..7d6182b 100644
--- a/libc/kernel/uapi/linux/dpll.h
+++ b/libc/kernel/uapi/linux/dpll.h
@@ -108,6 +108,9 @@
   DPLL_A_PIN_PHASE_ADJUST,
   DPLL_A_PIN_PHASE_OFFSET,
   DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
+  DPLL_A_PIN_ESYNC_FREQUENCY,
+  DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED,
+  DPLL_A_PIN_ESYNC_PULSE,
   __DPLL_A_PIN_MAX,
   DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
 };
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index f1cf522..ea40103 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -329,6 +329,7 @@
 #define NT_386_IOPERM 0x201
 #define NT_X86_XSTATE 0x202
 #define NT_X86_SHSTK 0x204
+#define NT_X86_XSAVE_LAYOUT 0x205
 #define NT_S390_HIGH_GPRS 0x300
 #define NT_S390_TIMER 0x301
 #define NT_S390_TODCMP 0x302
@@ -359,6 +360,7 @@
 #define NT_ARM_ZA 0x40c
 #define NT_ARM_ZT 0x40d
 #define NT_ARM_FPMR 0x40e
+#define NT_ARM_POE 0x40f
 #define NT_ARC_V2 0x600
 #define NT_VMCOREDD 0x700
 #define NT_MIPS_DSP 0x800
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index e213ba1..323c4fc 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -1026,4 +1026,8 @@
   __u32 reserved[7];
   __u32 link_mode_masks[];
 };
+enum phy_upstream {
+  PHY_UPSTREAM_MAC,
+  PHY_UPSTREAM_PHY,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index ac6391a..7120c03 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -53,6 +53,7 @@
   ETHTOOL_MSG_MM_GET,
   ETHTOOL_MSG_MM_SET,
   ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
+  ETHTOOL_MSG_PHY_GET,
   __ETHTOOL_MSG_USER_CNT,
   ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
 };
@@ -102,6 +103,8 @@
   ETHTOOL_MSG_MM_GET_REPLY,
   ETHTOOL_MSG_MM_NTF,
   ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
+  ETHTOOL_MSG_PHY_GET_REPLY,
+  ETHTOOL_MSG_PHY_NTF,
   __ETHTOOL_MSG_KERNEL_CNT,
   ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
 };
@@ -116,6 +119,7 @@
   ETHTOOL_A_HEADER_DEV_INDEX,
   ETHTOOL_A_HEADER_DEV_NAME,
   ETHTOOL_A_HEADER_FLAGS,
+  ETHTOOL_A_HEADER_PHY_INDEX,
   __ETHTOOL_A_HEADER_CNT,
   ETHTOOL_A_HEADER_MAX = __ETHTOOL_A_HEADER_CNT - 1
 };
@@ -408,6 +412,8 @@
   ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT,
   ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT,
   ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH,
+  ETHTOOL_A_CABLE_RESULT_CODE_NOISE,
+  ETHTOOL_A_CABLE_RESULT_CODE_RESOLUTION_NOT_POSSIBLE,
 };
 enum {
   ETHTOOL_A_CABLE_PAIR_A,
@@ -416,9 +422,15 @@
   ETHTOOL_A_CABLE_PAIR_D,
 };
 enum {
+  ETHTOOL_A_CABLE_INF_SRC_UNSPEC,
+  ETHTOOL_A_CABLE_INF_SRC_TDR,
+  ETHTOOL_A_CABLE_INF_SRC_ALCD,
+};
+enum {
   ETHTOOL_A_CABLE_RESULT_UNSPEC,
   ETHTOOL_A_CABLE_RESULT_PAIR,
   ETHTOOL_A_CABLE_RESULT_CODE,
+  ETHTOOL_A_CABLE_RESULT_SRC,
   __ETHTOOL_A_CABLE_RESULT_CNT,
   ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1)
 };
@@ -426,6 +438,7 @@
   ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC,
   ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR,
   ETHTOOL_A_CABLE_FAULT_LENGTH_CM,
+  ETHTOOL_A_CABLE_FAULT_LENGTH_SRC,
   __ETHTOOL_A_CABLE_FAULT_LENGTH_CNT,
   ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1)
 };
@@ -683,6 +696,7 @@
   ETHTOOL_A_RSS_INDIR,
   ETHTOOL_A_RSS_HKEY,
   ETHTOOL_A_RSS_INPUT_XFRM,
+  ETHTOOL_A_RSS_START_CONTEXT,
   __ETHTOOL_A_RSS_CNT,
   ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1),
 };
@@ -740,6 +754,19 @@
   __ETHTOOL_A_MODULE_FW_FLASH_CNT,
   ETHTOOL_A_MODULE_FW_FLASH_MAX = (__ETHTOOL_A_MODULE_FW_FLASH_CNT - 1)
 };
+enum {
+  ETHTOOL_A_PHY_UNSPEC,
+  ETHTOOL_A_PHY_HEADER,
+  ETHTOOL_A_PHY_INDEX,
+  ETHTOOL_A_PHY_DRVNAME,
+  ETHTOOL_A_PHY_NAME,
+  ETHTOOL_A_PHY_UPSTREAM_TYPE,
+  ETHTOOL_A_PHY_UPSTREAM_INDEX,
+  ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,
+  ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,
+  __ETHTOOL_A_PHY_CNT,
+  ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
+};
 #define ETHTOOL_GENL_NAME "ethtool"
 #define ETHTOOL_GENL_VERSION 1
 #define ETHTOOL_MCGRP_MONITOR_NAME "monitor"
diff --git a/libc/kernel/uapi/linux/exfat.h b/libc/kernel/uapi/linux/exfat.h
new file mode 100644
index 0000000..b813581
--- /dev/null
+++ b/libc/kernel/uapi/linux/exfat.h
@@ -0,0 +1,15 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_EXFAT_H
+#define _UAPI_LINUX_EXFAT_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define EXFAT_IOC_SHUTDOWN _IOR('X', 125, __u32)
+#define EXFAT_GOING_DOWN_DEFAULT 0x0
+#define EXFAT_GOING_DOWN_FULLSYNC 0x1
+#define EXFAT_GOING_DOWN_NOSYNC 0x2
+#endif
diff --git a/libc/kernel/uapi/linux/falloc.h b/libc/kernel/uapi/linux/falloc.h
index cca488e..cd7017e 100644
--- a/libc/kernel/uapi/linux/falloc.h
+++ b/libc/kernel/uapi/linux/falloc.h
@@ -6,6 +6,7 @@
  */
 #ifndef _UAPI_FALLOC_H_
 #define _UAPI_FALLOC_H_
+#define FALLOC_FL_ALLOCATE_RANGE 0x00
 #define FALLOC_FL_KEEP_SIZE 0x01
 #define FALLOC_FL_PUNCH_HOLE 0x02
 #define FALLOC_FL_NO_HIDE_STALE 0x04
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index 9f32f9f..22ca65d 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -12,6 +12,7 @@
 #define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
 #define F_NOTIFY (F_LINUX_SPECIFIC_BASE + 2)
 #define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3)
+#define F_CREATED_QUERY (F_LINUX_SPECIFIC_BASE + 4)
 #define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
 #define F_DUPFD_CLOEXEC (F_LINUX_SPECIFIC_BASE + 6)
 #define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7)
@@ -44,8 +45,6 @@
 #define DN_MULTISHOT 0x80000000
 #define AT_FDCWD - 100
 #define AT_SYMLINK_NOFOLLOW 0x100
-#define AT_EACCESS 0x200
-#define AT_REMOVEDIR 0x200
 #define AT_SYMLINK_FOLLOW 0x400
 #define AT_NO_AUTOMOUNT 0x800
 #define AT_EMPTY_PATH 0x1000
@@ -54,5 +53,11 @@
 #define AT_STATX_FORCE_SYNC 0x2000
 #define AT_STATX_DONT_SYNC 0x4000
 #define AT_RECURSIVE 0x8000
-#define AT_HANDLE_FID AT_REMOVEDIR
+#define AT_RENAME_NOREPLACE 0x0001
+#define AT_RENAME_EXCHANGE 0x0002
+#define AT_RENAME_WHITEOUT 0x0004
+#define AT_EACCESS 0x200
+#define AT_REMOVEDIR 0x200
+#define AT_HANDLE_FID 0x200
+#define AT_HANDLE_MNT_ID_UNIQUE 0x001
 #endif
diff --git a/libc/kernel/uapi/linux/fib_rules.h b/libc/kernel/uapi/linux/fib_rules.h
index ee9cabc..339ccce 100644
--- a/libc/kernel/uapi/linux/fib_rules.h
+++ b/libc/kernel/uapi/linux/fib_rules.h
@@ -61,6 +61,7 @@
   FRA_IP_PROTO,
   FRA_SPORT_RANGE,
   FRA_DPORT_RANGE,
+  FRA_DSCP,
   __FRA_MAX
 };
 #define FRA_MAX (__FRA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index 4ac2d2c..c1d64ce 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -8,7 +8,7 @@
 #define _LINUX_FUSE_H
 #include <stdint.h>
 #define FUSE_KERNEL_VERSION 7
-#define FUSE_KERNEL_MINOR_VERSION 40
+#define FUSE_KERNEL_MINOR_VERSION 41
 #define FUSE_ROOT_ID 1
 struct fuse_attr {
   uint64_t ino;
@@ -135,6 +135,7 @@
 #define FUSE_NO_EXPORT_SUPPORT (1ULL << 38)
 #define FUSE_HAS_RESEND (1ULL << 39)
 #define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP
+#define FUSE_ALLOW_IDMAP (1ULL << 40)
 #define CUSE_UNRESTRICTED_IOCTL (1 << 0)
 #define FUSE_RELEASE_FLUSH (1 << 0)
 #define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
@@ -214,6 +215,7 @@
   FUSE_SYNCFS = 50,
   FUSE_TMPFILE = 51,
   FUSE_STATX = 52,
+  FUSE_CANONICAL_PATH = 2016,
   CUSE_INIT = 4096,
   CUSE_INIT_BSWAP_RESERVED = 1048576,
   FUSE_INIT_BSWAP_RESERVED = 436207616,
@@ -497,6 +499,7 @@
   uint32_t padding;
 };
 #define FUSE_UNIQUE_RESEND (1ULL << 63)
+#define FUSE_INVALID_UIDGID ((uint32_t) (- 1))
 struct fuse_in_header {
   uint32_t len;
   uint32_t opcode;
diff --git a/libc/kernel/uapi/linux/hidraw.h b/libc/kernel/uapi/linux/hidraw.h
index 25a9a17..1eb024c 100644
--- a/libc/kernel/uapi/linux/hidraw.h
+++ b/libc/kernel/uapi/linux/hidraw.h
@@ -29,6 +29,7 @@
 #define HIDIOCGINPUT(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x0A, len)
 #define HIDIOCSOUTPUT(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x0B, len)
 #define HIDIOCGOUTPUT(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x0C, len)
+#define HIDIOCREVOKE _IOW('H', 0x0D, int)
 #define HIDRAW_FIRST_MINOR 0
 #define HIDRAW_MAX_DEVICES 64
 #define HIDRAW_BUFFER_SIZE 64
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 6b4f2ea..5564bff 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -230,6 +230,7 @@
 #define IORING_CQE_F_MORE (1U << 1)
 #define IORING_CQE_F_SOCK_NONEMPTY (1U << 2)
 #define IORING_CQE_F_NOTIF (1U << 3)
+#define IORING_CQE_F_BUF_MORE (1U << 4)
 #define IORING_CQE_BUFFER_SHIFT 16
 #define IORING_OFF_SQ_RING 0ULL
 #define IORING_OFF_CQ_RING 0x8000000ULL
@@ -268,6 +269,7 @@
 #define IORING_ENTER_SQ_WAIT (1U << 2)
 #define IORING_ENTER_EXT_ARG (1U << 3)
 #define IORING_ENTER_REGISTERED_RING (1U << 4)
+#define IORING_ENTER_ABS_TIMER (1U << 5)
 struct io_uring_params {
   __u32 sq_entries;
   __u32 cq_entries;
@@ -295,6 +297,7 @@
 #define IORING_FEAT_LINKED_FILE (1U << 12)
 #define IORING_FEAT_REG_REG_RING (1U << 13)
 #define IORING_FEAT_RECVSEND_BUNDLE (1U << 14)
+#define IORING_FEAT_MIN_TIMEOUT (1U << 15)
 enum io_uring_register_op {
   IORING_REGISTER_BUFFERS = 0,
   IORING_UNREGISTER_BUFFERS = 1,
@@ -325,6 +328,8 @@
   IORING_REGISTER_PBUF_STATUS = 26,
   IORING_REGISTER_NAPI = 27,
   IORING_UNREGISTER_NAPI = 28,
+  IORING_REGISTER_CLOCK = 29,
+  IORING_REGISTER_CLONE_BUFFERS = 30,
   IORING_REGISTER_LAST,
   IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
 };
@@ -383,6 +388,18 @@
   __u8 resv;
   __u32 resv2[3];
 };
+struct io_uring_clock_register {
+  __u32 clockid;
+  __u32 __resv[3];
+};
+enum {
+  IORING_REGISTER_SRC_REGISTERED = 1,
+};
+struct io_uring_clone_buffers {
+  __u32 src_fd;
+  __u32 flags;
+  __u32 pad[6];
+};
 struct io_uring_buf {
   __u64 addr;
   __u32 len;
@@ -402,6 +419,7 @@
 };
 enum io_uring_register_pbuf_ring_flags {
   IOU_PBUF_RING_MMAP = 1,
+  IOU_PBUF_RING_INC = 2,
 };
 struct io_uring_buf_reg {
   __u64 ring_addr;
@@ -431,7 +449,7 @@
 struct io_uring_getevents_arg {
   __u64 sigmask;
   __u32 sigmask_sz;
-  __u32 pad;
+  __u32 min_wait_usec;
   __u64 ts;
 };
 struct io_uring_sync_cancel_reg {
diff --git a/libc/kernel/uapi/linux/ioam6_iptunnel.h b/libc/kernel/uapi/linux/ioam6_iptunnel.h
index 34317fc..e1a0223 100644
--- a/libc/kernel/uapi/linux/ioam6_iptunnel.h
+++ b/libc/kernel/uapi/linux/ioam6_iptunnel.h
@@ -24,6 +24,7 @@
 #define IOAM6_IPTUNNEL_FREQ_MAX 1000000
   IOAM6_IPTUNNEL_FREQ_K,
   IOAM6_IPTUNNEL_FREQ_N,
+  IOAM6_IPTUNNEL_SRC,
   __IOAM6_IPTUNNEL_MAX,
 };
 #define IOAM6_IPTUNNEL_MAX (__IOAM6_IPTUNNEL_MAX - 1)
diff --git a/libc/kernel/uapi/linux/iommufd.h b/libc/kernel/uapi/linux/iommufd.h
index 6f663b4..3bbcd40c6 100644
--- a/libc/kernel/uapi/linux/iommufd.h
+++ b/libc/kernel/uapi/linux/iommufd.h
@@ -6,8 +6,8 @@
  */
 #ifndef _UAPI_IOMMUFD_H
 #define _UAPI_IOMMUFD_H
-#include <linux/types.h>
 #include <linux/ioctl.h>
+#include <linux/types.h>
 #define IOMMUFD_TYPE (';')
 enum {
   IOMMUFD_CMD_BASE = 0x80,
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 193dd8e..8948a13 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -9,7 +9,7 @@
 #include <drm/drm.h>
 #include <linux/ioctl.h>
 #define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 16
+#define KFD_IOCTL_MINOR_VERSION 17
 struct kfd_ioctl_get_version_args {
   __u32 major_version;
   __u32 minor_version;
@@ -18,6 +18,7 @@
 #define KFD_IOC_QUEUE_TYPE_SDMA 0x1
 #define KFD_IOC_QUEUE_TYPE_COMPUTE_AQL 0x2
 #define KFD_IOC_QUEUE_TYPE_SDMA_XGMI 0x3
+#define KFD_IOC_QUEUE_TYPE_SDMA_BY_ENG_ID 0x4
 #define KFD_MAX_QUEUE_PERCENTAGE 100
 #define KFD_MAX_QUEUE_PRIORITY 15
 struct kfd_ioctl_create_queue_args {
@@ -36,6 +37,8 @@
   __u64 ctx_save_restore_address;
   __u32 ctx_save_restore_size;
   __u32 ctl_stack_size;
+  __u32 sdma_engine_id;
+  __u32 pad;
 };
 struct kfd_ioctl_destroy_queue_args {
   __u32 queue_id;
@@ -358,6 +361,16 @@
   __u32 gpuid;
   __u32 anon_fd;
 };
+#define KFD_EVENT_FMT_UPDATE_GPU_RESET(reset_seq_num,reset_cause) "%x %s\n", (reset_seq_num), (reset_cause)
+#define KFD_EVENT_FMT_THERMAL_THROTTLING(bitmask,counter) "%llx:%llx\n", (bitmask), (counter)
+#define KFD_EVENT_FMT_VMFAULT(pid,task_name) "%x:%s\n", (pid), (task_name)
+#define KFD_EVENT_FMT_PAGEFAULT_START(ns,pid,addr,node,rw) "%lld -%d @%lx(%x) %c\n", (ns), (pid), (addr), (node), (rw)
+#define KFD_EVENT_FMT_PAGEFAULT_END(ns,pid,addr,node,migrate_update) "%lld -%d @%lx(%x) %c\n", (ns), (pid), (addr), (node), (migrate_update)
+#define KFD_EVENT_FMT_MIGRATE_START(ns,pid,start,size,from,to,prefetch_loc,preferred_loc,migrate_trigger) "%lld -%d @%lx(%lx) %x->%x %x:%x %d\n", (ns), (pid), (start), (size), (from), (to), (prefetch_loc), (preferred_loc), (migrate_trigger)
+#define KFD_EVENT_FMT_MIGRATE_END(ns,pid,start,size,from,to,migrate_trigger) "%lld -%d @%lx(%lx) %x->%x %d\n", (ns), (pid), (start), (size), (from), (to), (migrate_trigger)
+#define KFD_EVENT_FMT_QUEUE_EVICTION(ns,pid,node,evict_trigger) "%lld -%d %x %d\n", (ns), (pid), (node), (evict_trigger)
+#define KFD_EVENT_FMT_QUEUE_RESTORE(ns,pid,node,rescheduled) "%lld -%d %x %c\n", (ns), (pid), (node), (rescheduled)
+#define KFD_EVENT_FMT_UNMAP_FROM_GPU(ns,pid,addr,size,node,unmap_trigger) "%lld -%d @%lx(%lx) %x %d\n", (ns), (pid), (addr), (size), (node), (unmap_trigger)
 enum kfd_criu_op {
   KFD_CRIU_OP_PROCESS_INFO,
   KFD_CRIU_OP_CHECKPOINT,
diff --git a/libc/kernel/uapi/linux/landlock.h b/libc/kernel/uapi/linux/landlock.h
index f903ae6..8f83780 100644
--- a/libc/kernel/uapi/linux/landlock.h
+++ b/libc/kernel/uapi/linux/landlock.h
@@ -10,6 +10,7 @@
 struct landlock_ruleset_attr {
   __u64 handled_access_fs;
   __u64 handled_access_net;
+  __u64 scoped;
 };
 #define LANDLOCK_CREATE_RULESET_VERSION (1U << 0)
 enum landlock_rule_type {
@@ -42,4 +43,6 @@
 #define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15)
 #define LANDLOCK_ACCESS_NET_BIND_TCP (1ULL << 0)
 #define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1)
+#define LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET (1ULL << 0)
+#define LANDLOCK_SCOPE_SIGNAL (1ULL << 1)
 #endif
diff --git a/libc/kernel/uapi/linux/libc-compat.h b/libc/kernel/uapi/linux/libc-compat.h
index 289b7c5..0b5ba60 100644
--- a/libc/kernel/uapi/linux/libc-compat.h
+++ b/libc/kernel/uapi/linux/libc-compat.h
@@ -59,19 +59,6 @@
 #define __UAPI_DEF_IN6_PKTINFO 1
 #define __UAPI_DEF_IP6_MTUINFO 1
 #endif
-#ifdef __NETIPX_IPX_H
-#define __UAPI_DEF_SOCKADDR_IPX 0
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION 0
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0
-#define __UAPI_DEF_IPX_CONFIG_DATA 0
-#define __UAPI_DEF_IPX_ROUTE_DEF 0
-#else
-#define __UAPI_DEF_SOCKADDR_IPX 1
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
-#define __UAPI_DEF_IPX_CONFIG_DATA 1
-#define __UAPI_DEF_IPX_ROUTE_DEF 1
-#endif
 #ifdef _SYS_XATTR_H
 #define __UAPI_DEF_XATTR 0
 #else
@@ -138,21 +125,6 @@
 #ifndef __UAPI_DEF_IP6_MTUINFO
 #define __UAPI_DEF_IP6_MTUINFO 1
 #endif
-#ifndef __UAPI_DEF_SOCKADDR_IPX
-#define __UAPI_DEF_SOCKADDR_IPX 1
-#endif
-#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION
-#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
-#endif
-#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION
-#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
-#endif
-#ifndef __UAPI_DEF_IPX_CONFIG_DATA
-#define __UAPI_DEF_IPX_CONFIG_DATA 1
-#endif
-#ifndef __UAPI_DEF_IPX_ROUTE_DEF
-#define __UAPI_DEF_IPX_ROUTE_DEF 1
-#endif
 #ifndef __UAPI_DEF_XATTR
 #define __UAPI_DEF_XATTR 1
 #endif
diff --git a/libc/kernel/uapi/linux/lsm.h b/libc/kernel/uapi/linux/lsm.h
index 3a3f152..b12ca64 100644
--- a/libc/kernel/uapi/linux/lsm.h
+++ b/libc/kernel/uapi/linux/lsm.h
@@ -30,6 +30,7 @@
 #define LSM_ID_LANDLOCK 110
 #define LSM_ID_IMA 111
 #define LSM_ID_EVM 112
+#define LSM_ID_IPE 113
 #define LSM_ATTR_UNDEF 0
 #define LSM_ATTR_CURRENT 100
 #define LSM_ATTR_EXEC 101
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index 7b51b73..7a4d4db 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -15,6 +15,7 @@
 #define MDIO_MMD_DTEXS 5
 #define MDIO_MMD_TC 6
 #define MDIO_MMD_AN 7
+#define MDIO_MMD_POWER_UNIT 13
 #define MDIO_MMD_C22EXT 29
 #define MDIO_MMD_VEND1 30
 #define MDIO_MMD_VEND2 31
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index d47c28f..110220f 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -23,15 +23,19 @@
   NBD_CMD_WRITE = 1,
   NBD_CMD_DISC = 2,
   NBD_CMD_FLUSH = 3,
-  NBD_CMD_TRIM = 4
+  NBD_CMD_TRIM = 4,
+  NBD_CMD_WRITE_ZEROES = 6,
 };
 #define NBD_FLAG_HAS_FLAGS (1 << 0)
 #define NBD_FLAG_READ_ONLY (1 << 1)
 #define NBD_FLAG_SEND_FLUSH (1 << 2)
 #define NBD_FLAG_SEND_FUA (1 << 3)
+#define NBD_FLAG_ROTATIONAL (1 << 4)
 #define NBD_FLAG_SEND_TRIM (1 << 5)
+#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6)
 #define NBD_FLAG_CAN_MULTI_CONN (1 << 8)
 #define NBD_CMD_FLAG_FUA (1 << 16)
+#define NBD_CMD_FLAG_NO_HOLE (1 << 17)
 #define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0)
 #define NBD_CFLAG_DISCONNECT_ON_CLOSE (1 << 1)
 #define NBD_REQUEST_MAGIC 0x25609513
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 9bbd309..b0df344 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -26,7 +26,8 @@
   SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
   SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
   SOF_TIMESTAMPING_OPT_ID_TCP = (1 << 16),
-  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_ID_TCP,
+  SOF_TIMESTAMPING_OPT_RX_FILTER = (1 << 17),
+  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_RX_FILTER,
   SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
 };
 #define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_ACK)
diff --git a/libc/kernel/uapi/linux/netdev.h b/libc/kernel/uapi/linux/netdev.h
index b084297..a7c5706 100644
--- a/libc/kernel/uapi/linux/netdev.h
+++ b/libc/kernel/uapi/linux/netdev.h
@@ -51,6 +51,7 @@
   NETDEV_A_PAGE_POOL_INFLIGHT,
   NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
   NETDEV_A_PAGE_POOL_DETACH_TIME,
+  NETDEV_A_PAGE_POOL_DMABUF,
   __NETDEV_A_PAGE_POOL_MAX,
   NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1)
 };
@@ -83,6 +84,7 @@
   NETDEV_A_QUEUE_IFINDEX,
   NETDEV_A_QUEUE_TYPE,
   NETDEV_A_QUEUE_NAPI_ID,
+  NETDEV_A_QUEUE_DMABUF,
   __NETDEV_A_QUEUE_MAX,
   NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
 };
@@ -122,6 +124,14 @@
   NETDEV_A_QSTATS_MAX = (__NETDEV_A_QSTATS_MAX - 1)
 };
 enum {
+  NETDEV_A_DMABUF_IFINDEX = 1,
+  NETDEV_A_DMABUF_QUEUES,
+  NETDEV_A_DMABUF_FD,
+  NETDEV_A_DMABUF_ID,
+  __NETDEV_A_DMABUF_MAX,
+  NETDEV_A_DMABUF_MAX = (__NETDEV_A_DMABUF_MAX - 1)
+};
+enum {
   NETDEV_CMD_DEV_GET = 1,
   NETDEV_CMD_DEV_ADD_NTF,
   NETDEV_CMD_DEV_DEL_NTF,
@@ -134,6 +144,7 @@
   NETDEV_CMD_QUEUE_GET,
   NETDEV_CMD_NAPI_GET,
   NETDEV_CMD_QSTATS_GET,
+  NETDEV_CMD_BIND_RX,
   __NETDEV_CMD_MAX,
   NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
 };
diff --git a/libc/kernel/uapi/linux/nexthop.h b/libc/kernel/uapi/linux/nexthop.h
index 5726a66..2443c18 100644
--- a/libc/kernel/uapi/linux/nexthop.h
+++ b/libc/kernel/uapi/linux/nexthop.h
@@ -17,7 +17,7 @@
 struct nexthop_grp {
   __u32 id;
   __u8 weight;
-  __u8 resvd1;
+  __u8 weight_high;
   __u16 resvd2;
 };
 enum {
@@ -28,6 +28,7 @@
 #define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
 #define NHA_OP_FLAG_DUMP_STATS BIT(0)
 #define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)
+#define NHA_OP_FLAG_RESP_GRP_RESVD_0 BIT(31)
 enum {
   NHA_UNSPEC,
   NHA_ID,
diff --git a/libc/kernel/uapi/linux/nsfs.h b/libc/kernel/uapi/linux/nsfs.h
index c8f2208..870afe7 100644
--- a/libc/kernel/uapi/linux/nsfs.h
+++ b/libc/kernel/uapi/linux/nsfs.h
@@ -18,4 +18,13 @@
 #define NS_GET_TGID_FROM_PIDNS _IOR(NSIO, 0x7, int)
 #define NS_GET_PID_IN_PIDNS _IOR(NSIO, 0x8, int)
 #define NS_GET_TGID_IN_PIDNS _IOR(NSIO, 0x9, int)
+struct mnt_ns_info {
+  __u32 size;
+  __u32 nr_mounts;
+  __u64 mnt_ns_id;
+};
+#define MNT_NS_INFO_SIZE_VER0 16
+#define NS_MNT_GET_INFO _IOR(NSIO, 10, struct mnt_ns_info)
+#define NS_MNT_GET_NEXT _IOR(NSIO, 11, struct mnt_ns_info)
+#define NS_MNT_GET_PREV _IOR(NSIO, 12, struct mnt_ns_info)
 #endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index 703d398..7083391 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -531,9 +531,11 @@
 #define PCI_EXP_RTCTL_SENFEE 0x0002
 #define PCI_EXP_RTCTL_SEFEE 0x0004
 #define PCI_EXP_RTCTL_PMEIE 0x0008
-#define PCI_EXP_RTCTL_CRSSVE 0x0010
+#define PCI_EXP_RTCTL_RRS_SVE 0x0010
+#define PCI_EXP_RTCTL_CRSSVE PCI_EXP_RTCTL_RRS_SVE
 #define PCI_EXP_RTCAP 0x1e
-#define PCI_EXP_RTCAP_CRSVIS 0x0001
+#define PCI_EXP_RTCAP_RRS_SV 0x0001
+#define PCI_EXP_RTCAP_CRSVIS PCI_EXP_RTCAP_RRS_SV
 #define PCI_EXP_RTSTA 0x20
 #define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff
 #define PCI_EXP_RTSTA_PME 0x00010000
@@ -626,6 +628,7 @@
 #define PCI_EXT_CAP_ID_DVSEC 0x23
 #define PCI_EXT_CAP_ID_DLF 0x25
 #define PCI_EXT_CAP_ID_PL_16GT 0x26
+#define PCI_EXT_CAP_ID_NPEM 0x29
 #define PCI_EXT_CAP_ID_PL_32GT 0x2A
 #define PCI_EXT_CAP_ID_DOE 0x2E
 #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE
@@ -944,6 +947,31 @@
 #define PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK 0x0000000F
 #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0
 #define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4
+#define PCI_NPEM_CAP 0x04
+#define PCI_NPEM_CAP_CAPABLE 0x00000001
+#define PCI_NPEM_CTRL 0x08
+#define PCI_NPEM_CTRL_ENABLE 0x00000001
+#define PCI_NPEM_CMD_RESET 0x00000002
+#define PCI_NPEM_IND_OK 0x00000004
+#define PCI_NPEM_IND_LOCATE 0x00000008
+#define PCI_NPEM_IND_FAIL 0x00000010
+#define PCI_NPEM_IND_REBUILD 0x00000020
+#define PCI_NPEM_IND_PFA 0x00000040
+#define PCI_NPEM_IND_HOTSPARE 0x00000080
+#define PCI_NPEM_IND_ICA 0x00000100
+#define PCI_NPEM_IND_IFA 0x00000200
+#define PCI_NPEM_IND_IDT 0x00000400
+#define PCI_NPEM_IND_DISABLED 0x00000800
+#define PCI_NPEM_IND_SPEC_0 0x01000000
+#define PCI_NPEM_IND_SPEC_1 0x02000000
+#define PCI_NPEM_IND_SPEC_2 0x04000000
+#define PCI_NPEM_IND_SPEC_3 0x08000000
+#define PCI_NPEM_IND_SPEC_4 0x10000000
+#define PCI_NPEM_IND_SPEC_5 0x20000000
+#define PCI_NPEM_IND_SPEC_6 0x40000000
+#define PCI_NPEM_IND_SPEC_7 0x80000000
+#define PCI_NPEM_STATUS 0x0c
+#define PCI_NPEM_STATUS_CC 0x00000001
 #define PCI_DOE_CAP 0x04
 #define PCI_DOE_CAP_INT_SUP 0x00000001
 #define PCI_DOE_CAP_INT_MSG_NUM 0x00000ffe
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index bdca553..c5d8d79 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -179,7 +179,12 @@
   int offmask;
 };
 struct tc_u32_sel {
-  unsigned char flags;
+  /**
+   ** ANDROID FIX: Comment out TAG value to avoid C++ error about using
+   ** a type declared in an anonymous union. This is being fixed upstream
+   ** and should be corrected by the next kernel import.
+   */
+  __struct_group(/*tc_u32_sel_hdr*/, hdr,, unsigned char flags;
   unsigned char offshift;
   unsigned char nkeys;
   __be16 offmask;
@@ -187,6 +192,7 @@
   short offoff;
   short hoff;
   __be32 hmask;
+ );
   struct tc_u32_key keys[];
 };
 struct tc_u32_mark {
diff --git a/libc/kernel/uapi/linux/ptp_clock.h b/libc/kernel/uapi/linux/ptp_clock.h
index 5014936..88c6786 100644
--- a/libc/kernel/uapi/linux/ptp_clock.h
+++ b/libc/kernel/uapi/linux/ptp_clock.h
@@ -65,7 +65,8 @@
 };
 struct ptp_sys_offset_extended {
   unsigned int n_samples;
-  unsigned int rsv[3];
+  __kernel_clockid_t clockid;
+  unsigned int rsv[2];
   struct ptp_clock_time ts[PTP_MAX_SAMPLES][3];
 };
 struct ptp_sys_offset_precise {
diff --git a/libc/kernel/uapi/linux/rkisp1-config.h b/libc/kernel/uapi/linux/rkisp1-config.h
index d4206a0..d5cf92a 100644
--- a/libc/kernel/uapi/linux/rkisp1-config.h
+++ b/libc/kernel/uapi/linux/rkisp1-config.h
@@ -88,6 +88,7 @@
 #define RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(n,v) ((v) << ((n) * 4 + 2))
 #define RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS 17
 #define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS 6
+#define RKISP1_CIF_ISP_COMPAND_NUM_POINTS 64
 #define RKISP1_CIF_ISP_STAT_AWB (1U << 0)
 #define RKISP1_CIF_ISP_STAT_AUTOEXP (1U << 1)
 #define RKISP1_CIF_ISP_STAT_AFM (1U << 2)
@@ -348,6 +349,17 @@
   struct rkisp1_cif_isp_isp_meas_cfg meas;
   struct rkisp1_cif_isp_isp_other_cfg others;
 };
+struct rkisp1_cif_isp_compand_bls_config {
+  __u32 r;
+  __u32 gr;
+  __u32 gb;
+  __u32 b;
+};
+struct rkisp1_cif_isp_compand_curve_config {
+  __u8 px[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
+  __u32 x[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
+  __u32 y[RKISP1_CIF_ISP_COMPAND_NUM_POINTS];
+};
 struct rkisp1_cif_isp_awb_meas {
   __u32 cnt;
   __u8 mean_y_or_g;
@@ -388,4 +400,118 @@
   __u32 frame_id;
   struct rkisp1_cif_isp_stat params;
 };
+enum rkisp1_ext_params_block_type {
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_IE,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND,
+  RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS,
+};
+#define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE (1U << 0)
+#define RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE (1U << 1)
+struct rkisp1_ext_params_block_header {
+  __u16 type;
+  __u16 flags;
+  __u32 size;
+};
+struct rkisp1_ext_params_bls_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_bls_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_dpcc_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_dpcc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_sdg_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_sdg_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_lsc_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_lsc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_awb_gain_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_awb_gain_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_flt_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_flt_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_bdm_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_bdm_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_ctk_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_ctk_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_goc_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_goc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_dpf_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_dpf_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_dpf_strength_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_dpf_strength_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_cproc_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_cproc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_ie_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_ie_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_awb_meas_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_awb_meas_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_hst_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_hst_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_aec_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_aec_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_afc_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_afc_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_compand_bls_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_compand_bls_config config;
+} __attribute__((aligned(8)));
+struct rkisp1_ext_params_compand_curve_config {
+  struct rkisp1_ext_params_block_header header;
+  struct rkisp1_cif_isp_compand_curve_config config;
+} __attribute__((aligned(8)));
+#define RKISP1_EXT_PARAMS_MAX_SIZE (sizeof(struct rkisp1_ext_params_bls_config) + sizeof(struct rkisp1_ext_params_dpcc_config) + sizeof(struct rkisp1_ext_params_sdg_config) + sizeof(struct rkisp1_ext_params_lsc_config) + sizeof(struct rkisp1_ext_params_awb_gain_config) + sizeof(struct rkisp1_ext_params_flt_config) + sizeof(struct rkisp1_ext_params_bdm_config) + sizeof(struct rkisp1_ext_params_ctk_config) + sizeof(struct rkisp1_ext_params_goc_config) + sizeof(struct rkisp1_ext_params_dpf_config) + sizeof(struct rkisp1_ext_params_dpf_strength_config) + sizeof(struct rkisp1_ext_params_cproc_config) + sizeof(struct rkisp1_ext_params_ie_config) + sizeof(struct rkisp1_ext_params_awb_meas_config) + sizeof(struct rkisp1_ext_params_hst_config) + sizeof(struct rkisp1_ext_params_aec_config) + sizeof(struct rkisp1_ext_params_afc_config) + sizeof(struct rkisp1_ext_params_compand_bls_config) + sizeof(struct rkisp1_ext_params_compand_curve_config) + sizeof(struct rkisp1_ext_params_compand_curve_config))
+enum rksip1_ext_param_buffer_version {
+  RKISP1_EXT_PARAM_BUFFER_V1 = 1,
+};
+struct rkisp1_ext_params_cfg {
+  __u32 version;
+  __u32 data_size;
+  __u8 data[RKISP1_EXT_PARAMS_MAX_SIZE];
+};
 #endif
diff --git a/libc/kernel/uapi/linux/sched.h b/libc/kernel/uapi/linux/sched.h
index ae914f7..eaeeee3 100644
--- a/libc/kernel/uapi/linux/sched.h
+++ b/libc/kernel/uapi/linux/sched.h
@@ -59,6 +59,7 @@
 #define SCHED_BATCH 3
 #define SCHED_IDLE 5
 #define SCHED_DEADLINE 6
+#define SCHED_EXT 7
 #define SCHED_RESET_ON_FORK 0x40000000
 #define SCHED_FLAG_RESET_ON_FORK 0x01
 #define SCHED_FLAG_RECLAIM 0x02
diff --git a/libc/kernel/uapi/linux/serio.h b/libc/kernel/uapi/linux/serio.h
index 424144e..0f0668f 100644
--- a/libc/kernel/uapi/linux/serio.h
+++ b/libc/kernel/uapi/linux/serio.h
@@ -66,4 +66,5 @@
 #define SERIO_PULSE8_CEC 0x40
 #define SERIO_RAINSHADOW_CEC 0x41
 #define SERIO_FSIA6B 0x42
+#define SERIO_EXTRON_DA_HD_4K_PLUS 0x43
 #endif
diff --git a/libc/kernel/uapi/linux/smc.h b/libc/kernel/uapi/linux/smc.h
index 5e75fac..52a0da1 100644
--- a/libc/kernel/uapi/linux/smc.h
+++ b/libc/kernel/uapi/linux/smc.h
@@ -103,6 +103,8 @@
   SMC_NLA_LGR_R_NET_COOKIE,
   SMC_NLA_LGR_R_PAD,
   SMC_NLA_LGR_R_BUF_TYPE,
+  SMC_NLA_LGR_R_SNDBUF_ALLOC,
+  SMC_NLA_LGR_R_RMB_ALLOC,
   __SMC_NLA_LGR_R_MAX,
   SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
 };
@@ -134,6 +136,8 @@
   SMC_NLA_LGR_D_V2_COMMON,
   SMC_NLA_LGR_D_EXT_GID,
   SMC_NLA_LGR_D_PEER_EXT_GID,
+  SMC_NLA_LGR_D_SNDBUF_ALLOC,
+  SMC_NLA_LGR_D_DMB_ALLOC,
   __SMC_NLA_LGR_D_MAX,
   SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
 };
@@ -210,6 +214,8 @@
   SMC_NLA_STATS_T_TX_BYTES,
   SMC_NLA_STATS_T_RX_CNT,
   SMC_NLA_STATS_T_TX_CNT,
+  SMC_NLA_STATS_T_RX_RMB_USAGE,
+  SMC_NLA_STATS_T_TX_RMB_USAGE,
   __SMC_NLA_STATS_T_MAX,
   SMC_NLA_STATS_T_MAX = __SMC_NLA_STATS_T_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/spi/spi.h b/libc/kernel/uapi/linux/spi/spi.h
index 45c45cd..d0ead4b 100644
--- a/libc/kernel/uapi/linux/spi/spi.h
+++ b/libc/kernel/uapi/linux/spi/spi.h
@@ -30,5 +30,6 @@
 #define SPI_3WIRE_HIZ _BITUL(15)
 #define SPI_RX_CPHA_FLIP _BITUL(16)
 #define SPI_MOSI_IDLE_LOW _BITUL(17)
-#define SPI_MODE_USER_MASK (_BITUL(18) - 1)
+#define SPI_MOSI_IDLE_HIGH _BITUL(18)
+#define SPI_MODE_USER_MASK (_BITUL(19) - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/uio.h b/libc/kernel/uapi/linux/uio.h
index 70d6962..3384309 100644
--- a/libc/kernel/uapi/linux/uio.h
+++ b/libc/kernel/uapi/linux/uio.h
@@ -12,6 +12,17 @@
   void  * iov_base;
   __kernel_size_t iov_len;
 };
+struct dmabuf_cmsg {
+  __u64 frag_offset;
+  __u32 frag_size;
+  __u32 frag_token;
+  __u32 dmabuf_id;
+  __u32 flags;
+};
+struct dmabuf_token {
+  __u32 token_start;
+  __u32 token_count;
+};
 #define UIO_FASTIOV 8
 #define UIO_MAXIOV 1024
 #endif
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 6762773..c1121fb 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -119,6 +119,7 @@
 #define USB_DT_DEVICE_CAPABILITY 0x10
 #define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
 #define USB_DT_WIRE_ADAPTER 0x21
+#define USB_DT_DFU_FUNCTIONAL 0x21
 #define USB_DT_RPIPE 0x22
 #define USB_DT_CS_RADIO_CONTROL 0x23
 #define USB_DT_PIPE_USAGE 0x24
@@ -170,6 +171,7 @@
 #define USB_CLASS_USB_TYPE_C_BRIDGE 0x12
 #define USB_CLASS_MISC 0xef
 #define USB_CLASS_APP_SPEC 0xfe
+#define USB_SUBCLASS_DFU 0x01
 #define USB_CLASS_VENDOR_SPEC 0xff
 #define USB_SUBCLASS_VENDOR_SPEC 0xff
 struct usb_config_descriptor {
diff --git a/libc/kernel/uapi/linux/usb/functionfs.h b/libc/kernel/uapi/linux/usb/functionfs.h
index 095e937..e838363 100644
--- a/libc/kernel/uapi/linux/usb/functionfs.h
+++ b/libc/kernel/uapi/linux/usb/functionfs.h
@@ -6,6 +6,7 @@
  */
 #ifndef _UAPI__LINUX_FUNCTIONFS_H__
 #define _UAPI__LINUX_FUNCTIONFS_H__
+#include <linux/const.h>
 #include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/usb/ch9.h>
@@ -32,6 +33,18 @@
   __le16 wMaxPacketSize;
   __u8 bInterval;
 } __attribute__((packed));
+struct usb_dfu_functional_descriptor {
+  __u8 bLength;
+  __u8 bDescriptorType;
+  __u8 bmAttributes;
+  __le16 wDetachTimeOut;
+  __le16 wTransferSize;
+  __le16 bcdDFUVersion;
+} __attribute__((packed));
+#define DFU_FUNC_ATT_CAN_DOWNLOAD _BITUL(0)
+#define DFU_FUNC_ATT_CAN_UPLOAD _BITUL(1)
+#define DFU_FUNC_ATT_MANIFEST_TOLERANT _BITUL(2)
+#define DFU_FUNC_ATT_WILL_DETACH _BITUL(3)
 struct usb_functionfs_descs_head_v2 {
   __le32 magic;
   __le32 length;
diff --git a/libc/kernel/uapi/linux/usb/g_hid.h b/libc/kernel/uapi/linux/usb/g_hid.h
new file mode 100644
index 0000000..db50738
--- /dev/null
+++ b/libc/kernel/uapi/linux/usb/g_hid.h
@@ -0,0 +1,20 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __UAPI_LINUX_USB_G_HID_H
+#define __UAPI_LINUX_USB_G_HID_H
+#include <linux/types.h>
+#define MAX_REPORT_LENGTH 64
+struct usb_hidg_report {
+  __u8 report_id;
+  __u8 userspace_req;
+  __u16 length;
+  __u8 data[MAX_REPORT_LENGTH];
+  __u8 padding[4];
+};
+#define GADGET_HID_READ_GET_REPORT_ID _IOR('g', 0x41, __u8)
+#define GADGET_HID_WRITE_GET_REPORT _IOW('g', 0x42, struct usb_hidg_report)
+#endif
diff --git a/libc/kernel/uapi/linux/vbox_vmmdev_types.h b/libc/kernel/uapi/linux/vbox_vmmdev_types.h
index 7123c02..cd0dcd9 100644
--- a/libc/kernel/uapi/linux/vbox_vmmdev_types.h
+++ b/libc/kernel/uapi/linux/vbox_vmmdev_types.h
@@ -177,6 +177,9 @@
   __u32 flags;
   __u16 offset_first_page;
   __u16 page_count;
-  __u64 pages[1];
+  union {
+    __u64 unused;
+    __DECLARE_FLEX_ARRAY(__u64, pages);
+  };
 };
 #endif
diff --git a/libc/kernel/uapi/linux/vdpa.h b/libc/kernel/uapi/linux/vdpa.h
index 462d579..a689f0d 100644
--- a/libc/kernel/uapi/linux/vdpa.h
+++ b/libc/kernel/uapi/linux/vdpa.h
@@ -17,6 +17,7 @@
   VDPA_CMD_DEV_GET,
   VDPA_CMD_DEV_CONFIG_GET,
   VDPA_CMD_DEV_VSTATS_GET,
+  VDPA_CMD_DEV_ATTR_SET,
 };
 enum vdpa_attr {
   VDPA_ATTR_UNSPEC,
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 0cc45cf..728b80a 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -4,8 +4,8 @@
  * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
  * for more information.
  */
-#define LINUX_VERSION_CODE 396032
+#define LINUX_VERSION_CODE 396288
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
 #define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 11
+#define LINUX_VERSION_PATCHLEVEL 12
 #define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index fb69a8a..e49f5ea 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -173,6 +173,7 @@
 #define V4L2_CAP_SDR_OUTPUT 0x00400000
 #define V4L2_CAP_META_CAPTURE 0x00800000
 #define V4L2_CAP_READWRITE 0x01000000
+#define V4L2_CAP_EDID 0x02000000
 #define V4L2_CAP_STREAMING 0x04000000
 #define V4L2_CAP_META_OUTPUT 0x08000000
 #define V4L2_CAP_TOUCH 0x10000000
@@ -456,6 +457,7 @@
 #define V4L2_META_FMT_VIVID v4l2_fourcc('V', 'I', 'V', 'D')
 #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P')
 #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S')
+#define V4L2_META_FMT_RK_ISP1_EXT_PARAMS v4l2_fourcc('R', 'K', '1', 'E')
 #define V4L2_META_FMT_RPI_BE_CFG v4l2_fourcc('R', 'P', 'B', 'C')
 #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
 #define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001
diff --git a/libc/kernel/uapi/linux/virtio_balloon.h b/libc/kernel/uapi/linux/virtio_balloon.h
index f37c148..3cf8807 100644
--- a/libc/kernel/uapi/linux/virtio_balloon.h
+++ b/libc/kernel/uapi/linux/virtio_balloon.h
@@ -38,8 +38,14 @@
 #define VIRTIO_BALLOON_S_CACHES 7
 #define VIRTIO_BALLOON_S_HTLB_PGALLOC 8
 #define VIRTIO_BALLOON_S_HTLB_PGFAIL 9
-#define VIRTIO_BALLOON_S_NR 10
-#define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { VIRTIO_BALLOON_S_NAMES_prefix "swap-in", VIRTIO_BALLOON_S_NAMES_prefix "swap-out", VIRTIO_BALLOON_S_NAMES_prefix "major-faults", VIRTIO_BALLOON_S_NAMES_prefix "minor-faults", VIRTIO_BALLOON_S_NAMES_prefix "free-memory", VIRTIO_BALLOON_S_NAMES_prefix "total-memory", VIRTIO_BALLOON_S_NAMES_prefix "available-memory", VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures" \
+#define VIRTIO_BALLOON_S_OOM_KILL 10
+#define VIRTIO_BALLOON_S_ALLOC_STALL 11
+#define VIRTIO_BALLOON_S_ASYNC_SCAN 12
+#define VIRTIO_BALLOON_S_DIRECT_SCAN 13
+#define VIRTIO_BALLOON_S_ASYNC_RECLAIM 14
+#define VIRTIO_BALLOON_S_DIRECT_RECLAIM 15
+#define VIRTIO_BALLOON_S_NR 16
+#define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { VIRTIO_BALLOON_S_NAMES_prefix "swap-in", VIRTIO_BALLOON_S_NAMES_prefix "swap-out", VIRTIO_BALLOON_S_NAMES_prefix "major-faults", VIRTIO_BALLOON_S_NAMES_prefix "minor-faults", VIRTIO_BALLOON_S_NAMES_prefix "free-memory", VIRTIO_BALLOON_S_NAMES_prefix "total-memory", VIRTIO_BALLOON_S_NAMES_prefix "available-memory", VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures", VIRTIO_BALLOON_S_NAMES_prefix "oom-kills", VIRTIO_BALLOON_S_NAMES_prefix "alloc-stalls", VIRTIO_BALLOON_S_NAMES_prefix "async-scans", VIRTIO_BALLOON_S_NAMES_prefix "direct-scans", VIRTIO_BALLOON_S_NAMES_prefix "async-reclaims", VIRTIO_BALLOON_S_NAMES_prefix "direct-reclaims" \
 }
 #define VIRTIO_BALLOON_S_NAMES VIRTIO_BALLOON_S_NAMES_WITH_PREFIX("")
 struct virtio_balloon_stat {
diff --git a/libc/kernel/uapi/linux/virtio_gpu.h b/libc/kernel/uapi/linux/virtio_gpu.h
index c3f0fcc..bf35cf7 100644
--- a/libc/kernel/uapi/linux/virtio_gpu.h
+++ b/libc/kernel/uapi/linux/virtio_gpu.h
@@ -195,6 +195,7 @@
 #define VIRTIO_GPU_CAPSET_VIRGL 1
 #define VIRTIO_GPU_CAPSET_VIRGL2 2
 #define VIRTIO_GPU_CAPSET_VENUS 4
+#define VIRTIO_GPU_CAPSET_DRM 6
 struct virtio_gpu_get_capset_info {
   struct virtio_gpu_ctrl_hdr hdr;
   __le32 capset_index;
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 50f8b8a..38bfb1b 100644
--- a/libc/kernel/uapi/rdma/bnxt_re-abi.h
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -27,6 +27,7 @@
 };
 enum {
   BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT = 0x01,
+  BNXT_RE_COMP_MASK_REQ_UCNTX_VAR_WQE_SUPPORT = 0x02,
 };
 struct bnxt_re_uctx_req {
   __aligned_u64 comp_mask;
@@ -66,10 +67,15 @@
 struct bnxt_re_resize_cq_req {
   __aligned_u64 cq_va;
 };
+enum bnxt_re_qp_mask {
+  BNXT_RE_QP_REQ_MASK_VAR_WQE_SQ_SLOTS = 0x1,
+};
 struct bnxt_re_qp_req {
   __aligned_u64 qpsva;
   __aligned_u64 qprva;
   __aligned_u64 qp_handle;
+  __aligned_u64 comp_mask;
+  __u32 sq_slots;
 };
 struct bnxt_re_qp_resp {
   __u32 qpid;
@@ -79,8 +85,13 @@
   __aligned_u64 srqva;
   __aligned_u64 srq_handle;
 };
+enum bnxt_re_srq_mask {
+  BNXT_RE_SRQ_TOGGLE_PAGE_SUPPORT = 0x1,
+};
 struct bnxt_re_srq_resp {
   __u32 srqid;
+  __u32 rsvd;
+  __aligned_u64 comp_mask;
 };
 enum bnxt_re_shpg_offt {
   BNXT_RE_BEG_RESV_OFFT = 0x00,
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index ebafb00..2e61c71 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -204,6 +204,9 @@
 enum mlx5_ib_create_cq_attrs {
   MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX = UVERBS_ID_DRIVER_NS_WITH_UHW,
 };
+enum mlx5_ib_reg_dmabuf_mr_attrs {
+  MLX5_IB_ATTR_REG_DMABUF_MR_ACCESS_FLAGS = (1U << UVERBS_ID_NS_SHIFT),
+};
 #define MLX5_IB_DW_MATCH_PARAM 0xA0
 struct mlx5_ib_match_params {
   __u32 match_params[MLX5_IB_DW_MATCH_PARAM];
@@ -261,9 +264,13 @@
 };
 enum mlx5_ib_device_methods {
   MLX5_IB_METHOD_QUERY_PORT = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_METHOD_GET_DATA_DIRECT_SYSFS_PATH,
 };
 enum mlx5_ib_query_port_attrs {
   MLX5_IB_ATTR_QUERY_PORT_PORT_NUM = (1U << UVERBS_ID_NS_SHIFT),
   MLX5_IB_ATTR_QUERY_PORT,
 };
+enum mlx5_ib_get_data_direct_sysfs_path_attrs {
+  MLX5_IB_ATTR_GET_DATA_DIRECT_SYSFS_PATH = (1U << UVERBS_ID_NS_SHIFT),
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index f087ee8..3fe3c82 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -23,6 +23,9 @@
   MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2 = 0x2,
   MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL = 0x3,
 };
+enum mlx5_ib_uapi_reg_dmabuf_flags {
+  MLX5_IB_UAPI_REG_DMABUF_ACCESS_DATA_DIRECT = 1 << 0,
+};
 struct mlx5_ib_uapi_devx_async_cmd_hdr {
   __aligned_u64 wr_id;
   __u8 out_data[];
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index ac027ac..137b68f 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -17,6 +17,7 @@
 enum {
   RDMA_NL_GROUP_IWPM = 2,
   RDMA_NL_GROUP_LS,
+  RDMA_NL_GROUP_NOTIFY,
   RDMA_NL_NUM_GROUPS
 };
 #define RDMA_NL_GET_CLIENT(type) ((type & (((1 << 6) - 1) << 10)) >> 10)
@@ -201,6 +202,7 @@
   RDMA_NLDEV_CMD_RES_SRQ_GET_RAW,
   RDMA_NLDEV_CMD_NEWDEV,
   RDMA_NLDEV_CMD_DELDEV,
+  RDMA_NLDEV_CMD_MONITOR,
   RDMA_NLDEV_NUM_OPS
 };
 enum rdma_nldev_print_type {
@@ -311,6 +313,8 @@
   RDMA_NLDEV_ATTR_DEV_TYPE,
   RDMA_NLDEV_ATTR_PARENT_NAME,
   RDMA_NLDEV_ATTR_NAME_ASSIGN_TYPE,
+  RDMA_NLDEV_ATTR_EVENT_TYPE,
+  RDMA_NLDEV_SYS_ATTR_MONITOR_MODE,
   RDMA_NLDEV_ATTR_MAX
 };
 enum rdma_nl_counter_mode {
@@ -330,4 +334,10 @@
   RDMA_NAME_ASSIGN_TYPE_UNKNOWN = 0,
   RDMA_NAME_ASSIGN_TYPE_USER = 1,
 };
+enum rdma_nl_notify_event_type {
+  RDMA_REGISTER_EVENT,
+  RDMA_UNREGISTER_EVENT,
+  RDMA_NETDEV_ATTACH_EVENT,
+  RDMA_NETDEV_DETACH_EVENT,
+};
 #endif
diff --git a/libc/kernel/uapi/sound/asequencer.h b/libc/kernel/uapi/sound/asequencer.h
index a3826a5..83b38f1 100644
--- a/libc/kernel/uapi/sound/asequencer.h
+++ b/libc/kernel/uapi/sound/asequencer.h
@@ -298,6 +298,7 @@
 #define SNDRV_SEQ_PORT_FLG_GIVEN_PORT (1 << 0)
 #define SNDRV_SEQ_PORT_FLG_TIMESTAMP (1 << 1)
 #define SNDRV_SEQ_PORT_FLG_TIME_REAL (1 << 2)
+#define SNDRV_SEQ_PORT_FLG_IS_MIDI1 (1 << 3)
 #define SNDRV_SEQ_PORT_DIR_UNKNOWN 0
 #define SNDRV_SEQ_PORT_DIR_INPUT 1
 #define SNDRV_SEQ_PORT_DIR_OUTPUT 2
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index f7992cb..22e750d 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -53,7 +53,7 @@
 #define SND_SOC_TPLG_MAGIC 0x41536F43
 #define SND_SOC_TPLG_NUM_TEXTS 16
 #define SND_SOC_TPLG_ABI_VERSION 0x5
-#define SND_SOC_TPLG_ABI_VERSION_MIN 0x4
+#define SND_SOC_TPLG_ABI_VERSION_MIN 0x5
 #define SND_SOC_TPLG_TLV_SIZE 32
 #define SND_SOC_TPLG_TYPE_MIXER 1
 #define SND_SOC_TPLG_TYPE_BYTES 2
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index cfe9f66..cbebef3 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -676,7 +676,7 @@
 #define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
 #define SNDRV_UMP_IOCTL_ENDPOINT_INFO _IOR('W', 0x40, struct snd_ump_endpoint_info)
 #define SNDRV_UMP_IOCTL_BLOCK_INFO _IOR('W', 0x41, struct snd_ump_block_info)
-#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
+#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
 enum {
   SNDRV_TIMER_CLASS_NONE = - 1,
   SNDRV_TIMER_CLASS_SLAVE = 0,
@@ -696,6 +696,7 @@
 #define SNDRV_TIMER_GLOBAL_RTC 1
 #define SNDRV_TIMER_GLOBAL_HPET 2
 #define SNDRV_TIMER_GLOBAL_HRTIMER 3
+#define SNDRV_TIMER_GLOBAL_UDRIVEN 4
 #define SNDRV_TIMER_FLG_SLAVE (1 << 0)
 struct snd_timer_id {
   int dev_class;
@@ -762,6 +763,12 @@
   unsigned int queue;
   unsigned char reserved[64];
 };
+struct snd_timer_uinfo {
+  __u64 resolution;
+  int fd;
+  unsigned int id;
+  unsigned char reserved[16];
+};
 #define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
 #define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id)
 #define SNDRV_TIMER_IOCTL_TREAD_OLD _IOW('T', 0x02, int)
@@ -777,6 +784,8 @@
 #define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
 #define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
 #define SNDRV_TIMER_IOCTL_TREAD64 _IOW('T', 0xa4, int)
+#define SNDRV_TIMER_IOCTL_CREATE _IOWR('T', 0xa5, struct snd_timer_uinfo)
+#define SNDRV_TIMER_IOCTL_TRIGGER _IO('T', 0xa6)
 #if __BITS_PER_LONG == 64
 #define SNDRV_TIMER_IOCTL_TREAD SNDRV_TIMER_IOCTL_TREAD_OLD
 #else
diff --git a/libc/kernel/uapi/xen/privcmd.h b/libc/kernel/uapi/xen/privcmd.h
index 0597247..0874e4b 100644
--- a/libc/kernel/uapi/xen/privcmd.h
+++ b/libc/kernel/uapi/xen/privcmd.h
@@ -77,6 +77,10 @@
   domid_t dom;
   __u8 pad[2];
 };
+struct privcmd_pcidev_get_gsi {
+  __u32 sbdf;
+  __u32 gsi;
+};
 #define IOCTL_PRIVCMD_HYPERCALL _IOC(_IOC_NONE, 'P', 0, sizeof(struct privcmd_hypercall))
 #define IOCTL_PRIVCMD_MMAP _IOC(_IOC_NONE, 'P', 2, sizeof(struct privcmd_mmap))
 #define IOCTL_PRIVCMD_MMAPBATCH _IOC(_IOC_NONE, 'P', 3, sizeof(struct privcmd_mmapbatch))
@@ -86,4 +90,5 @@
 #define IOCTL_PRIVCMD_MMAP_RESOURCE _IOC(_IOC_NONE, 'P', 7, sizeof(struct privcmd_mmap_resource))
 #define IOCTL_PRIVCMD_IRQFD _IOW('P', 8, struct privcmd_irqfd)
 #define IOCTL_PRIVCMD_IOEVENTFD _IOW('P', 9, struct privcmd_ioeventfd)
+#define IOCTL_PRIVCMD_PCIDEV_GET_GSI _IOC(_IOC_NONE, 'P', 10, sizeof(struct privcmd_pcidev_get_gsi))
 #endif
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 5d61801..50f24f6 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -135,6 +135,7 @@
         "tests/log_fake.cpp",
         "tests/libc_fake.cpp",
         "tests/malloc_debug_config_tests.cpp",
+        "tests/malloc_debug_record_data_tests.cpp",
         "tests/malloc_debug_unit_tests.cpp",
     ],
 
@@ -182,11 +183,6 @@
         "bionic_libc_platform_headers",
     ],
 
-    // The clang-analyzer-unix.Malloc and other warnings in these
-    // unit tests are either false positive or in
-    // negative tests that can be ignored.
-    tidy: false,
-
     srcs: [
         "tests/malloc_debug_system_tests.cpp",
     ],
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 1641732..1df0b0c 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -38,7 +38,6 @@
 
 #include <mutex>
 
-#include <android-base/stringprintf.h>
 #include <memory_trace/MemoryTrace.h>
 
 #include "Config.h"
@@ -55,7 +54,7 @@
   size_t count = 0;
 };
 
-static void ThreadKeyDelete(void* data) {
+void RecordData::ThreadKeyDelete(void* data) {
   ThreadData* thread_data = reinterpret_cast<ThreadData*>(data);
 
   thread_data->count++;
@@ -64,8 +63,11 @@
   if (thread_data->count == 4) {
     ScopedDisableDebugCalls disable;
 
-    thread_data->record_data->AddEntryOnly(memory_trace::Entry{
-        .tid = gettid(), .type = memory_trace::THREAD_DONE, .end_ns = Nanotime()});
+    memory_trace::Entry* entry = thread_data->record_data->InternalReserveEntry();
+    if (entry != nullptr) {
+      *entry = memory_trace::Entry{
+          .tid = gettid(), .type = memory_trace::THREAD_DONE, .end_ns = Nanotime()};
+    }
     delete thread_data;
   } else {
     pthread_setspecific(thread_data->record_data->key(), data);
@@ -107,6 +109,11 @@
   }
 
   for (size_t i = 0; i < cur_index_; i++) {
+    if (entries_[i].type == memory_trace::UNKNOWN) {
+      // This can happen if an entry was reserved but not filled in due to some
+      // type of error during the operation.
+      continue;
+    }
     if (!memory_trace::WriteEntryToFd(dump_fd, entries_[i])) {
       error_log("Failed to write record alloc information: %s", strerror(errno));
       break;
@@ -142,32 +149,118 @@
   cur_index_ = 0U;
   file_ = config.record_allocs_file();
 
+  pagemap_fd_ = TEMP_FAILURE_RETRY(open("/proc/self/pagemap", O_RDONLY | O_CLOEXEC));
+  if (pagemap_fd_ == -1) {
+    error_log("Unable to open /proc/self/pagemap: %s", strerror(errno));
+    return false;
+  }
+
   return true;
 }
 
 RecordData::~RecordData() {
+  if (pagemap_fd_ != -1) {
+    close(pagemap_fd_);
+  }
+
   pthread_key_delete(key_);
 }
 
-void RecordData::AddEntryOnly(const memory_trace::Entry& entry) {
+memory_trace::Entry* RecordData::InternalReserveEntry() {
   std::lock_guard<std::mutex> entries_lock(entries_lock_);
   if (cur_index_ == entries_.size()) {
-    // Maxed out, throw the entry away.
-    return;
+    return nullptr;
   }
 
-  entries_[cur_index_++] = entry;
-  if (cur_index_ == entries_.size()) {
+  memory_trace::Entry* entry = &entries_[cur_index_];
+  entry->type = memory_trace::UNKNOWN;
+  if (++cur_index_ == entries_.size()) {
     info_log("Maximum number of records added, all new operations will be dropped.");
   }
+  return entry;
 }
 
-void RecordData::AddEntry(const memory_trace::Entry& entry) {
+memory_trace::Entry* RecordData::ReserveEntry() {
   void* data = pthread_getspecific(key_);
   if (data == nullptr) {
     ThreadData* thread_data = new ThreadData(this);
     pthread_setspecific(key_, thread_data);
   }
 
-  AddEntryOnly(entry);
+  return InternalReserveEntry();
+}
+
+static inline bool IsPagePresent(uint64_t page_data) {
+  // Page Present is bit 63
+  return (page_data & (1ULL << 63)) != 0;
+}
+
+int64_t RecordData::GetPresentBytes(void* ptr, size_t alloc_size) {
+  uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
+  if (addr == 0 || alloc_size == 0) {
+    return -1;
+  }
+
+  uintptr_t page_size = getpagesize();
+  uintptr_t page_size_mask = page_size - 1;
+
+  size_t start_page = (addr & ~page_size_mask) / page_size;
+  size_t last_page = ((addr + alloc_size - 1) & ~page_size_mask) / page_size;
+
+  constexpr size_t kMaxReadPages = 1024;
+  uint64_t page_data[kMaxReadPages];
+
+  int64_t present_bytes = 0;
+  size_t cur_page = start_page;
+  while (cur_page <= last_page) {
+    size_t num_pages = last_page - cur_page + 1;
+    size_t last_page_index;
+    if (num_pages > kMaxReadPages) {
+      num_pages = kMaxReadPages;
+      last_page_index = num_pages;
+    } else {
+      // Handle the last page differently, so do not handle it in the loop.
+      last_page_index = num_pages - 1;
+    }
+    ssize_t bytes_read =
+        pread64(pagemap_fd_, page_data, num_pages * sizeof(uint64_t), cur_page * sizeof(uint64_t));
+    if (bytes_read <= 0) {
+      error_log("Failed to read page data: %s", strerror(errno));
+      return -1;
+    }
+
+    size_t page_index = 0;
+    // Handling the first page is special, handle it separately.
+    if (cur_page == start_page) {
+      if (IsPagePresent(page_data[0])) {
+        present_bytes = page_size - (addr & page_size_mask);
+        if (present_bytes >= alloc_size) {
+          // The allocation fits on a single page and that page is present.
+          return alloc_size;
+        }
+      } else if (start_page == last_page) {
+        // Only one page that isn't present.
+        return 0;
+      }
+      page_index = 1;
+    }
+
+    for (; page_index < last_page_index; page_index++) {
+      if (IsPagePresent(page_data[page_index])) {
+        present_bytes += page_size;
+      }
+    }
+
+    cur_page += last_page_index;
+
+    // Check the last page in the allocation.
+    if (cur_page == last_page) {
+      if (IsPagePresent(page_data[num_pages - 1])) {
+        present_bytes += ((addr + alloc_size - 1) & page_size_mask) + 1;
+      }
+      return present_bytes;
+    }
+  }
+
+  return present_bytes;
 }
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index f4b0d82..bf5cc57 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -51,26 +51,32 @@
 
   bool Initialize(const Config& config);
 
-  void AddEntry(const memory_trace::Entry& entry);
-  void AddEntryOnly(const memory_trace::Entry& entry);
+  memory_trace::Entry* ReserveEntry();
 
   const std::string& file() { return file_; }
   pthread_key_t key() { return key_; }
 
+  int64_t GetPresentBytes(void* pointer, size_t size);
+
   static void WriteEntriesOnExit();
 
  private:
   static void WriteData(int, siginfo_t*, void*);
   static RecordData* record_obj_;
 
+  static void ThreadKeyDelete(void* data);
+
   void WriteEntries();
   void WriteEntries(const std::string& file);
 
+  memory_trace::Entry* InternalReserveEntry();
+
   std::mutex entries_lock_;
   pthread_key_t key_;
   std::vector<memory_trace::Entry> entries_;
   size_t cur_index_;
   std::string file_;
+  int pagemap_fd_ = -1;
 
   BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);
 };
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index a662529..7e96169 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -590,16 +590,22 @@
   ScopedDisableDebugCalls disable;
   ScopedBacktraceSignalBlocker blocked;
 
+  memory_trace::Entry* entry = nullptr;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // In order to preserve the order of operations, reserve the entry before
+    // performing the operation.
+    entry = g_debug->record->ReserveEntry();
+  }
+
   TimedResult result = InternalMalloc(size);
 
-  if (g_debug->config().options() & RECORD_ALLOCS) {
-    g_debug->record->AddEntry(
-        memory_trace::Entry{.tid = gettid(),
-                            .type = memory_trace::MALLOC,
-                            .ptr = reinterpret_cast<uint64_t>(result.getValue<void*>()),
-                            .size = size,
-                            .start_ns = result.GetStartTimeNS(),
-                            .end_ns = result.GetEndTimeNS()});
+  if (entry != nullptr) {
+    *entry = memory_trace::Entry{.tid = gettid(),
+                                 .type = memory_trace::MALLOC,
+                                 .ptr = reinterpret_cast<uint64_t>(result.getValue<void*>()),
+                                 .size = size,
+                                 .start_ns = result.GetStartTimeNS(),
+                                 .end_ns = result.GetEndTimeNS()};
   }
 
   return result.getValue<void*>();
@@ -676,6 +682,13 @@
   if (DebugCallsDisabled() || pointer == nullptr) {
     return g_dispatch->free(pointer);
   }
+
+  size_t size;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // Need to get the size before disabling debug calls.
+    size = debug_malloc_usable_size(pointer);
+  }
+
   ScopedConcurrentLock lock;
   ScopedDisableDebugCalls disable;
   ScopedBacktraceSignalBlocker blocked;
@@ -684,14 +697,27 @@
     return;
   }
 
+  int64_t present_bytes = -1;
+  memory_trace::Entry* entry = nullptr;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // In order to preserve the order of operations, reserve the entry before
+    // performing the operation.
+    entry = g_debug->record->ReserveEntry();
+
+    // Need to get the present bytes before the pointer is freed in case the
+    // memory is released during the free call.
+    present_bytes = g_debug->record->GetPresentBytes(pointer, size);
+  }
+
   TimedResult result = InternalFree(pointer);
 
-  if (g_debug->config().options() & RECORD_ALLOCS) {
-    g_debug->record->AddEntry(memory_trace::Entry{.tid = gettid(),
-                                                  .type = memory_trace::FREE,
-                                                  .ptr = reinterpret_cast<uint64_t>(pointer),
-                                                  .start_ns = result.GetStartTimeNS(),
-                                                  .end_ns = result.GetEndTimeNS()});
+  if (entry != nullptr) {
+    *entry = memory_trace::Entry{.tid = gettid(),
+                                 .type = memory_trace::FREE,
+                                 .ptr = reinterpret_cast<uint64_t>(pointer),
+                                 .present_bytes = present_bytes,
+                                 .start_ns = result.GetStartTimeNS(),
+                                 .end_ns = result.GetEndTimeNS()};
   }
 }
 
@@ -714,6 +740,13 @@
     return nullptr;
   }
 
+  memory_trace::Entry* entry = nullptr;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // In order to preserve the order of operations, reserve the entry before
+    // performing the operation.
+    entry = g_debug->record->ReserveEntry();
+  }
+
   TimedResult result;
   void* pointer;
   if (g_debug->HeaderEnabled()) {
@@ -761,27 +794,29 @@
     pointer = result.getValue<void*>();
   }
 
-  if (pointer != nullptr) {
-    if (g_debug->TrackPointers()) {
-      PointerData::Add(pointer, bytes);
-    }
+  if (pointer == nullptr) {
+    return nullptr;
+  }
 
-    if (g_debug->config().options() & FILL_ON_ALLOC) {
-      size_t bytes = InternalMallocUsableSize(pointer);
-      size_t fill_bytes = g_debug->config().fill_on_alloc_bytes();
-      bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
-      memset(pointer, g_debug->config().fill_alloc_value(), bytes);
-    }
+  if (g_debug->TrackPointers()) {
+    PointerData::Add(pointer, bytes);
+  }
 
-    if (g_debug->config().options() & RECORD_ALLOCS) {
-      g_debug->record->AddEntry(memory_trace::Entry{.tid = gettid(),
-                                                    .type = memory_trace::MEMALIGN,
-                                                    .ptr = reinterpret_cast<uint64_t>(pointer),
-                                                    .size = bytes,
-                                                    .u.align = alignment,
-                                                    .start_ns = result.GetStartTimeNS(),
-                                                    .end_ns = result.GetEndTimeNS()});
-    }
+  if (g_debug->config().options() & FILL_ON_ALLOC) {
+    size_t bytes = InternalMallocUsableSize(pointer);
+    size_t fill_bytes = g_debug->config().fill_on_alloc_bytes();
+    bytes = (bytes < fill_bytes) ? bytes : fill_bytes;
+    memset(pointer, g_debug->config().fill_alloc_value(), bytes);
+  }
+
+  if (entry != nullptr) {
+    *entry = memory_trace::Entry{.tid = gettid(),
+                                 .type = memory_trace::MEMALIGN,
+                                 .ptr = reinterpret_cast<uint64_t>(pointer),
+                                 .size = bytes,
+                                 .u.align = alignment,
+                                 .start_ns = result.GetStartTimeNS(),
+                                 .end_ns = result.GetEndTimeNS()};
   }
 
   return pointer;
@@ -793,21 +828,35 @@
   if (DebugCallsDisabled()) {
     return g_dispatch->realloc(pointer, bytes);
   }
+
+  size_t old_size;
+  if (pointer != nullptr && g_debug->config().options() & RECORD_ALLOCS) {
+    // Need to get the size before disabling debug calls.
+    old_size = debug_malloc_usable_size(pointer);
+  }
+
   ScopedConcurrentLock lock;
   ScopedDisableDebugCalls disable;
   ScopedBacktraceSignalBlocker blocked;
 
+  memory_trace::Entry* entry = nullptr;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // In order to preserve the order of operations, reserve the entry before
+    // performing the operation.
+    entry = g_debug->record->ReserveEntry();
+  }
+
   if (pointer == nullptr) {
     TimedResult result = InternalMalloc(bytes);
     pointer = result.getValue<void*>();
-    if (g_debug->config().options() & RECORD_ALLOCS) {
-      g_debug->record->AddEntry(memory_trace::Entry{.tid = gettid(),
-                                                    .type = memory_trace::REALLOC,
-                                                    .ptr = reinterpret_cast<uint64_t>(pointer),
-                                                    .size = bytes,
-                                                    .u.old_ptr = 0,
-                                                    .start_ns = result.GetStartTimeNS(),
-                                                    .end_ns = result.GetEndTimeNS()});
+    if (entry != nullptr) {
+      *entry = memory_trace::Entry{.tid = gettid(),
+                                   .type = memory_trace::REALLOC,
+                                   .ptr = reinterpret_cast<uint64_t>(pointer),
+                                   .size = bytes,
+                                   .u.old_ptr = 0,
+                                   .start_ns = result.GetStartTimeNS(),
+                                   .end_ns = result.GetEndTimeNS()};
     }
     return pointer;
   }
@@ -816,18 +865,25 @@
     return nullptr;
   }
 
+  int64_t present_bytes = -1;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // Need to get the present bytes before the pointer is freed in case the
+    // memory is released during the free call.
+    present_bytes = g_debug->record->GetPresentBytes(pointer, old_size);
+  }
+
   if (bytes == 0) {
     TimedResult result = InternalFree(pointer);
 
-    if (g_debug->config().options() & RECORD_ALLOCS) {
-      g_debug->record->AddEntry(
-          memory_trace::Entry{.tid = gettid(),
-                              .type = memory_trace::REALLOC,
-                              .ptr = 0,
-                              .size = 0,
-                              .u.old_ptr = reinterpret_cast<uint64_t>(pointer),
-                              .start_ns = result.GetStartTimeNS(),
-                              .end_ns = result.GetEndTimeNS()});
+    if (entry != nullptr) {
+      *entry = memory_trace::Entry{.tid = gettid(),
+                                   .type = memory_trace::REALLOC,
+                                   .ptr = 0,
+                                   .size = 0,
+                                   .u.old_ptr = reinterpret_cast<uint64_t>(pointer),
+                                   .present_bytes = present_bytes,
+                                   .start_ns = result.GetStartTimeNS(),
+                                   .end_ns = result.GetEndTimeNS()};
     }
 
     return nullptr;
@@ -923,14 +979,15 @@
     }
   }
 
-  if (g_debug->config().options() & RECORD_ALLOCS) {
-    g_debug->record->AddEntry(memory_trace::Entry{.tid = gettid(),
-                                                  .type = memory_trace::REALLOC,
-                                                  .ptr = reinterpret_cast<uint64_t>(new_pointer),
-                                                  .size = bytes,
-                                                  .u.old_ptr = reinterpret_cast<uint64_t>(pointer),
-                                                  .start_ns = result.GetStartTimeNS(),
-                                                  .end_ns = result.GetEndTimeNS()});
+  if (entry != nullptr) {
+    *entry = memory_trace::Entry{.tid = gettid(),
+                                 .type = memory_trace::REALLOC,
+                                 .ptr = reinterpret_cast<uint64_t>(new_pointer),
+                                 .size = bytes,
+                                 .u.old_ptr = reinterpret_cast<uint64_t>(pointer),
+                                 .present_bytes = present_bytes,
+                                 .start_ns = result.GetStartTimeNS(),
+                                 .end_ns = result.GetEndTimeNS()};
   }
 
   return new_pointer;
@@ -969,6 +1026,13 @@
     return nullptr;
   }
 
+  memory_trace::Entry* entry = nullptr;
+  if (g_debug->config().options() & RECORD_ALLOCS) {
+    // In order to preserve the order of operations, reserve the entry before
+    // performing the operation.
+    entry = g_debug->record->ReserveEntry();
+  }
+
   void* pointer;
   TimedResult result;
   if (g_debug->HeaderEnabled()) {
@@ -985,14 +1049,14 @@
     pointer = result.getValue<void*>();
   }
 
-  if (g_debug->config().options() & RECORD_ALLOCS) {
-    g_debug->record->AddEntry(memory_trace::Entry{.tid = gettid(),
-                                                  .type = memory_trace::CALLOC,
-                                                  .ptr = reinterpret_cast<uint64_t>(pointer),
-                                                  .size = bytes,
-                                                  .u.n_elements = nmemb,
-                                                  .start_ns = result.GetStartTimeNS(),
-                                                  .end_ns = result.GetEndTimeNS()});
+  if (entry != nullptr) {
+    *entry = memory_trace::Entry{.tid = gettid(),
+                                 .type = memory_trace::CALLOC,
+                                 .ptr = reinterpret_cast<uint64_t>(pointer),
+                                 .size = bytes,
+                                 .u.n_elements = nmemb,
+                                 .start_ns = result.GetStartTimeNS(),
+                                 .end_ns = result.GetEndTimeNS()};
   }
 
   if (pointer != nullptr && g_debug->TrackPointers()) {
diff --git a/libc/malloc_debug/tests/malloc_debug_record_data_tests.cpp b/libc/malloc_debug/tests/malloc_debug_record_data_tests.cpp
new file mode 100644
index 0000000..b94dc8f
--- /dev/null
+++ b/libc/malloc_debug/tests/malloc_debug_record_data_tests.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2024 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 <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+#include "Config.h"
+#include "RecordData.h"
+
+#include "log_fake.h"
+
+class MallocDebugRecordDataTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    page_size_ = getpagesize();
+    Config config;
+    ASSERT_TRUE(config.Init("record_allocs"));
+    ASSERT_TRUE(record_.Initialize(config));
+  }
+
+  uint8_t* AllocPageAligned(size_t alloc_pages) {
+    uint8_t* ptr = reinterpret_cast<uint8_t*>(memalign(page_size_, alloc_pages * page_size_));
+    if (ptr == nullptr) {
+      return nullptr;
+    }
+    // Release all the pages so the test can make them present.
+    EXPECT_EQ(0, madvise(ptr, page_size_ * alloc_pages, MADV_DONTNEED));
+    return ptr;
+  }
+
+  size_t page_size_;
+  RecordData record_;
+};
+
+TEST_F(MallocDebugRecordDataTest, get_present_bytes_error) {
+  EXPECT_EQ(-1, record_.GetPresentBytes(nullptr, 1000));
+  EXPECT_EQ(-1, record_.GetPresentBytes(reinterpret_cast<void*>(1000), 0));
+}
+
+TEST_F(MallocDebugRecordDataTest, get_present_bytes_edge_cases) {
+  // Need two pages to check allocations crossing over the page.
+  size_t alloc_pages = 2;
+  uint8_t* ptr = AllocPageAligned(alloc_pages);
+  ASSERT_TRUE(ptr != nullptr);
+  memset(ptr, 1, alloc_pages * page_size_);
+
+  EXPECT_EQ(20, record_.GetPresentBytes(ptr, 20));
+  EXPECT_EQ(page_size_ + 20, record_.GetPresentBytes(ptr, page_size_ + 20));
+  EXPECT_EQ(17, record_.GetPresentBytes(&ptr[page_size_ - 20], 17));
+  EXPECT_EQ(32, record_.GetPresentBytes(&ptr[page_size_ - 16], 32));
+  EXPECT_EQ(page_size_, record_.GetPresentBytes(ptr, page_size_));
+  EXPECT_EQ(page_size_ * 2, record_.GetPresentBytes(ptr, page_size_ * 2));
+}
+
+TEST_F(MallocDebugRecordDataTest, get_present_bytes_first_page_not_present) {
+  uint8_t* ptr = AllocPageAligned(2);
+  ASSERT_TRUE(ptr != nullptr);
+  ptr[page_size_] = 1;
+
+  EXPECT_EQ(0, record_.GetPresentBytes(ptr, page_size_));
+  EXPECT_EQ(3996, record_.GetPresentBytes(&ptr[100], page_size_ * 2 - 200));
+}
+
+TEST_F(MallocDebugRecordDataTest, get_present_bytes_last_page_not_present) {
+  uint8_t* ptr = AllocPageAligned(2);
+  ASSERT_TRUE(ptr != nullptr);
+  ptr[0] = 1;
+
+  EXPECT_EQ(3596, record_.GetPresentBytes(&ptr[500], page_size_ * 2 - 600));
+}
+
+TEST_F(MallocDebugRecordDataTest, get_present_bytes_large) {
+  // Needs to match the kMaxReadPages from GetPresentBytes
+  constexpr size_t kMaxReadPages = 1024;
+  // Allocate large enough that it requires at least two preads.
+  size_t alloc_pages = 2 * kMaxReadPages;
+  uint8_t* ptr = AllocPageAligned(alloc_pages);
+  ASSERT_TRUE(ptr != nullptr);
+  // Make sure that there are different number of pages present in the first
+  // read than in the second read.
+  ptr[0] = 1;
+  ptr[page_size_] = 1;
+  ptr[page_size_ * 4] = 1;
+  // Should be in the second read.
+  size_t start = kMaxReadPages * page_size_;
+  ptr[start + page_size_ * 2] = 1;
+  ptr[start + page_size_ * 4] = 1;
+  ptr[start + page_size_ * 8] = 1;
+  ptr[start + page_size_ * 9] = 1;
+
+  EXPECT_EQ(page_size_ * 7, record_.GetPresentBytes(ptr, alloc_pages * page_size_));
+
+  // Make the entire allocation resident for the next few tests.
+  for (size_t i = 0; i < alloc_pages; i++) {
+    ptr[i * page_size_] = 1;
+  }
+
+  EXPECT_EQ(page_size_ * kMaxReadPages, record_.GetPresentBytes(ptr, page_size_ * kMaxReadPages));
+  EXPECT_EQ(page_size_ * (kMaxReadPages + 1),
+            record_.GetPresentBytes(ptr, page_size_ * (kMaxReadPages + 1)));
+  EXPECT_EQ(page_size_ * kMaxReadPages - 50,
+            record_.GetPresentBytes(ptr, page_size_ * kMaxReadPages - 50));
+  EXPECT_EQ(page_size_ * (kMaxReadPages + 1) - 50,
+            record_.GetPresentBytes(ptr, page_size_ * (kMaxReadPages + 1) - 50));
+}
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index c808dc0..79f946f 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -45,6 +45,7 @@
 #include <platform/bionic/macros.h>
 #include <private/bionic_malloc_dispatch.h>
 
+#include <memory_trace/MemoryTrace.h>
 #include <unwindstack/Unwinder.h>
 
 #include "Config.h"
@@ -202,6 +203,44 @@
   }
 }
 
+static void VerifyRecordEntries(const std::vector<memory_trace::Entry>& expected,
+                                std::string& actual) {
+  ASSERT_TRUE(expected.size() != 0);
+  // Convert the text to entries.
+  std::vector<memory_trace::Entry> actual_entries;
+  for (const auto& line : android::base::Split(actual, "\n")) {
+    if (line.empty()) {
+      continue;
+    }
+    memory_trace::Entry entry;
+    std::string error;
+    ASSERT_TRUE(memory_trace::FillInEntryFromString(line, entry, error)) << error;
+    actual_entries.emplace_back(entry);
+  }
+  auto expected_iter = expected.begin();
+  for (const auto& actual_entry : actual_entries) {
+    if (actual_entry.type == memory_trace::THREAD_DONE) {
+      // Skip thread done entries.
+      continue;
+    }
+    ASSERT_NE(expected_iter, expected.end())
+        << "Found extra entry " << memory_trace::CreateStringFromEntry(*expected_iter);
+    SCOPED_TRACE(testing::Message()
+                 << "\nExpected entry:\n  " << memory_trace::CreateStringFromEntry(*expected_iter)
+                 << "\nActual entry:\n  " << memory_trace::CreateStringFromEntry(actual_entry));
+    EXPECT_EQ(actual_entry.type, expected_iter->type);
+    EXPECT_EQ(actual_entry.ptr, expected_iter->ptr);
+    EXPECT_EQ(actual_entry.size, expected_iter->size);
+    EXPECT_EQ(actual_entry.u.old_ptr, expected_iter->u.old_ptr);
+    EXPECT_EQ(actual_entry.present_bytes, expected_iter->present_bytes);
+    // Verify the timestamps are non-zero.
+    EXPECT_NE(actual_entry.start_ns, 0U);
+    EXPECT_NE(actual_entry.end_ns, 0U);
+    ++expected_iter;
+  }
+  EXPECT_TRUE(expected_iter == expected.end()) << "Not all expected entries found.";
+}
+
 void VerifyAllocCalls(bool all_options) {
   size_t alloc_size = 1024;
 
@@ -2457,6 +2496,114 @@
   ASSERT_STREQ("", getFakeLogPrint().c_str());
 }
 
+TEST_F(MallocDebugTest, record_allocs_present_bytes_check) {
+  InitRecordAllocs("record_allocs record_allocs_on_exit");
+
+  // The filename created on exit always appends the pid.
+  // Modify the variable so the file is deleted at the end of the test.
+  record_filename += '.' + std::to_string(getpid());
+
+  std::vector<memory_trace::Entry> expected;
+  void* ptr = debug_malloc(100);
+  expected.push_back(memory_trace::Entry{
+      .type = memory_trace::MALLOC, .ptr = reinterpret_cast<uint64_t>(ptr), .size = 100});
+
+  // Make the entire allocation present.
+  memset(ptr, 1, 100);
+
+  int64_t real_size = debug_malloc_usable_size(ptr);
+  debug_free(ptr);
+  expected.push_back(memory_trace::Entry{.type = memory_trace::FREE,
+                                         .ptr = reinterpret_cast<uint64_t>(ptr),
+                                         .present_bytes = real_size});
+
+  ptr = debug_malloc(4096);
+  expected.push_back(memory_trace::Entry{
+      .type = memory_trace::MALLOC, .ptr = reinterpret_cast<uint64_t>(ptr), .size = 4096});
+
+  memset(ptr, 1, 4096);
+  real_size = debug_malloc_usable_size(ptr);
+  void* new_ptr = debug_realloc(ptr, 8192);
+  expected.push_back(memory_trace::Entry{.type = memory_trace::REALLOC,
+                                         .ptr = reinterpret_cast<uint64_t>(new_ptr),
+                                         .size = 8192,
+                                         .u.old_ptr = reinterpret_cast<uint64_t>(ptr),
+                                         .present_bytes = real_size});
+
+  memset(new_ptr, 1, 8192);
+  real_size = debug_malloc_usable_size(new_ptr);
+  debug_free(new_ptr);
+  expected.push_back(memory_trace::Entry{.type = memory_trace::FREE,
+                                         .ptr = reinterpret_cast<uint64_t>(new_ptr),
+                                         .present_bytes = real_size});
+
+  ptr = debug_malloc(4096);
+  expected.push_back(memory_trace::Entry{
+      .type = memory_trace::MALLOC, .ptr = reinterpret_cast<uint64_t>(ptr), .size = 4096});
+  memset(ptr, 1, 4096);
+
+  // Verify a free realloc does update the present bytes.
+  real_size = debug_malloc_usable_size(ptr);
+  EXPECT_TRUE(debug_realloc(ptr, 0) == nullptr);
+  expected.push_back(memory_trace::Entry{.type = memory_trace::REALLOC,
+                                         .ptr = 0,
+                                         .u.old_ptr = reinterpret_cast<uint64_t>(ptr),
+                                         .present_bytes = real_size});
+
+  // Call the exit function manually.
+  debug_finalize();
+
+  // Read all of the contents.
+  std::string actual;
+  ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
+  VerifyRecordEntries(expected, actual);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(MallocDebugTest, record_allocs_not_all_bytes_present) {
+  InitRecordAllocs("record_allocs record_allocs_on_exit");
+
+  // The filename created on exit always appends the pid.
+  // Modify the variable so the file is deleted at the end of the test.
+  record_filename += '.' + std::to_string(getpid());
+
+  std::vector<memory_trace::Entry> expected;
+  size_t pagesize = getpagesize();
+  void* ptr = debug_memalign(pagesize, pagesize * 8);
+  ASSERT_TRUE(ptr != nullptr);
+  expected.push_back(memory_trace::Entry{.type = memory_trace::MEMALIGN,
+                                         .ptr = reinterpret_cast<uint64_t>(ptr),
+                                         .size = pagesize * 8,
+                                         .u.align = pagesize});
+
+  // Mark only some pages in use.
+  uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
+  // Make sure the memory is not in use.
+  ASSERT_EQ(0, madvise(ptr, pagesize * 8, MADV_DONTNEED));
+  // Dirty three non-consecutive pages.
+  data[0] = 1;
+  data[pagesize * 2] = 1;
+  data[pagesize * 4] = 1;
+
+  debug_free(ptr);
+  expected.push_back(memory_trace::Entry{.type = memory_trace::FREE,
+                                         .ptr = reinterpret_cast<uint64_t>(ptr),
+                                         .present_bytes = static_cast<int64_t>(pagesize) * 3});
+
+  // Call the exit function manually.
+  debug_finalize();
+
+  // Read all of the contents.
+  std::string actual;
+  ASSERT_TRUE(android::base::ReadFileToString(record_filename, &actual));
+  VerifyRecordEntries(expected, actual);
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
 TEST_F(MallocDebugTest, verify_pointers) {
   Init("verify_pointers");
 
diff --git a/libc/malloc_hooks/Android.bp b/libc/malloc_hooks/Android.bp
index 3f0640b..06e91c6 100644
--- a/libc/malloc_hooks/Android.bp
+++ b/libc/malloc_hooks/Android.bp
@@ -60,11 +60,6 @@
     name: "malloc_hooks_system_tests",
     isolated: true,
 
-    // The clang-analyzer-unix.Malloc and other warnings in these
-    // unit tests are either false positive or in
-    // negative tests that can be ignored.
-    tidy: false,
-
     srcs: [
         "tests/malloc_hooks_tests.cpp",
     ],
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index 1e7ca88..c4af3b9 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -32,24 +32,6 @@
     ? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
     : (1UL << (32 - __builtin_clz(static_cast<unsigned int>(value)))))
 
-static constexpr uintptr_t align_down(uintptr_t p, size_t align) {
-  return p & ~(align - 1);
-}
-
-static constexpr uintptr_t align_up(uintptr_t p, size_t align) {
-  return (p + align - 1) & ~(align - 1);
-}
-
-template <typename T>
-static inline T* _Nonnull align_down(T* _Nonnull p, size_t align) {
-  return reinterpret_cast<T*>(align_down(reinterpret_cast<uintptr_t>(p), align));
-}
-
-template <typename T>
-static inline T* _Nonnull align_up(T* _Nonnull p, size_t align) {
-  return reinterpret_cast<T*>(align_up(reinterpret_cast<uintptr_t>(p), align));
-}
-
 #if defined(__arm__)
 #define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined r14")
 #elif defined(__aarch64__)
diff --git a/libc/platform/bionic/reserved_signals.h b/libc/platform/bionic/reserved_signals.h
index eb423f6..1c7076b 100644
--- a/libc/platform/bionic/reserved_signals.h
+++ b/libc/platform/bionic/reserved_signals.h
@@ -50,6 +50,13 @@
 #define BIONIC_SIGNAL_BACKTRACE (__SIGRTMIN + 1)
 #define BIONIC_SIGNAL_DEBUGGER (__SIGRTMIN + 3)
 #define BIONIC_SIGNAL_PROFILER (__SIGRTMIN + 4)
+// When used for the dumping a heap dump, BIONIC_SIGNAL_ART_PROFILER is always handled
+// gracefully without crashing.
+// In debuggerd, we crash the process with this signal to indicate to init that
+// a process has been terminated by an MTEAERR SEGV. This works because there is
+// no other reason a process could have terminated with this signal.
+// This is to work around the limitation of that it is not possible to get the
+// si_code that terminated a process.
 #define BIONIC_SIGNAL_ART_PROFILER (__SIGRTMIN + 6)
 #define BIONIC_SIGNAL_FDTRACK (__SIGRTMIN + 7)
 #define BIONIC_SIGNAL_RUN_ON_ALL_THREADS (__SIGRTMIN + 8)
diff --git a/libc/private/CFIShadow.h b/libc/private/CFIShadow.h
index cbdf0f7..b40c063 100644
--- a/libc/private/CFIShadow.h
+++ b/libc/private/CFIShadow.h
@@ -40,7 +40,7 @@
 // below) are interpreted as follows.
 //
 // For an address P and corresponding shadow value V, the address of __cfi_check is calculated as
-//   align_up(P, 2**kShadowGranularity) - (V - 2) * (2 ** kCfiCheckGranularity)
+//   __builtin_align_up(P, 2**kShadowGranularity) - (V - 2) * (2 ** kCfiCheckGranularity)
 //
 // Special shadow values:
 //        0 = kInvalidShadow, this memory range has no valid CFI targets.
diff --git a/libc/upstream-netbsd/lib/libc/regex/regcomp.c b/libc/upstream-netbsd/lib/libc/regex/regcomp.c
index 86321c1..b0f29d6 100644
--- a/libc/upstream-netbsd/lib/libc/regex/regcomp.c
+++ b/libc/upstream-netbsd/lib/libc/regex/regcomp.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: regcomp.c,v 1.47 2022/12/21 17:44:15 wiz Exp $	*/
+/*	$NetBSD: regcomp.c,v 1.49 2025/01/01 18:19:50 christos Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
@@ -51,7 +51,7 @@
 static char sccsid[] = "@(#)regcomp.c	8.5 (Berkeley) 3/20/94";
 __FBSDID("$FreeBSD: head/lib/libc/regex/regcomp.c 368359 2020-12-05 03:18:48Z kevans $");
 #endif
-__RCSID("$NetBSD: regcomp.c,v 1.47 2022/12/21 17:44:15 wiz Exp $");
+__RCSID("$NetBSD: regcomp.c,v 1.49 2025/01/01 18:19:50 christos Exp $");
 
 #ifndef LIBHACK
 #define REGEX_GNU_EXTENSIONS
@@ -898,10 +898,10 @@
 	handled = false;
 
 	assert(MORE());		/* caller should have ensured this */
-	c = GETNEXT();
+	c = (uch)GETNEXT();
 	if (c == '\\') {
 		(void)REQUIRE(MORE(), REG_EESCAPE);
-		cc = GETNEXT();
+		cc = (uch)GETNEXT();
 		c = BACKSL | cc;
 #ifdef REGEX_GNU_EXTENSIONS
 		if (p->gnuext) {
@@ -1083,7 +1083,7 @@
 	int ndigits = 0;
 
 	while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) {
-		count = count*10 + (GETNEXT() - '0');
+		count = count*10 + ((uch)GETNEXT() - '0');
 		ndigits++;
 	}
 
@@ -1422,7 +1422,7 @@
 
 	if ((p->pflags & PFLAG_LEGACY_ESC) != 0)
 		return (true);
-	if (isalpha(ch) || ch == '\'' || ch == '`')
+	if (iswalpha(ch) || ch == '\'' || ch == '`')
 		return (false);
 	return (true);
 #ifdef NOTYET
@@ -1764,8 +1764,7 @@
 	_DIAGASSERT(p != NULL);
 	_DIAGASSERT(cs != NULL);
 
-	assert(ch >= 0);
-	if (ch < NC)
+	if ((unsigned)ch < NC)
 		cs->bmp[(unsigned)ch >> 3] |= 1 << (ch & 7);
 	else {
 		newwides = reallocarray(cs->wides, cs->nwides + 1,
@@ -1778,9 +1777,9 @@
 		cs->wides[cs->nwides++] = ch;
 	}
 	if (cs->icase) {
-		if ((nch = towlower(ch)) < NC)
+		if ((unsigned)(nch = towlower(ch)) < NC)
 			cs->bmp[(unsigned)nch >> 3] |= 1 << (nch & 7);
-		if ((nch = towupper(ch)) < NC)
+		if ((unsigned)(nch = towupper(ch)) < NC)
 			cs->bmp[(unsigned)nch >> 3] |= 1 << (nch & 7);
 	}
 }
diff --git a/libc/upstream-netbsd/lib/libc/regex/regex2.h b/libc/upstream-netbsd/lib/libc/regex/regex2.h
index fbfff0d..d44785f 100644
--- a/libc/upstream-netbsd/lib/libc/regex/regex2.h
+++ b/libc/upstream-netbsd/lib/libc/regex/regex2.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: regex2.h,v 1.15 2021/02/24 18:13:21 christos Exp $	*/
+/*	$NetBSD: regex2.h,v 1.16 2025/01/01 18:19:50 christos Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
@@ -135,8 +135,7 @@
 {
 	unsigned int i;
 
-	assert(ch >= 0);
-	if (ch < NC)
+	if ((unsigned)ch < NC)
 		return (((cs->bmp[(unsigned)ch >> 3] & (1 << (ch & 7))) != 0) ^
 		    cs->invert);
 	for (i = 0; i < cs->nwides; i++) {
@@ -160,8 +159,7 @@
 CHIN(cset *cs, wint_t ch)
 {
 
-	assert(ch >= 0);
-	if (ch < NC)
+	if ((unsigned)ch < NC)
 		return (((cs->bmp[(unsigned)ch >> 3] & (1 << (ch & 7))) != 0) ^
 		    cs->invert);
 	else if (cs->icase)
diff --git a/libc/upstream-netbsd/lib/libc/regex/utils.h b/libc/upstream-netbsd/lib/libc/regex/utils.h
index 972f555..8650dd4 100644
--- a/libc/upstream-netbsd/lib/libc/regex/utils.h
+++ b/libc/upstream-netbsd/lib/libc/regex/utils.h
@@ -63,6 +63,7 @@
 
 /* utility definitions */
 #define	DUPMAX		_POSIX2_RE_DUP_MAX	/* xxx is this right? */
+#undef INFINITY // Android-added: avoid collision with C23 <float.h> INFINITY (via <limits.h>)
 #define	INFINITY	(DUPMAX + 1)
 
 #define	NC_MAX		(CHAR_MAX - CHAR_MIN + 1)
diff --git a/libc/upstream-openbsd/lib/libc/string/memchr.c b/libc/upstream-openbsd/lib/libc/string/memchr.c
deleted file mode 100644
index a6a4bd6..0000000
--- a/libc/upstream-openbsd/lib/libc/string/memchr.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*	$OpenBSD: memchr.c,v 1.8 2015/08/31 02:53:57 guenther Exp $ */
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <string.h>
-
-void *
-memchr(const void *s, int c, size_t n)
-{
-	if (n != 0) {
-		const unsigned char *p = s;
-
-		do {
-			if (*p++ == (unsigned char)c)
-				return ((void *)(p - 1));
-		} while (--n != 0);
-	}
-	return (NULL);
-}
-DEF_STRONG(memchr);
diff --git a/libdl/NOTICE b/libdl/NOTICE
index fce0104..80038fc 100644
--- a/libdl/NOTICE
+++ b/libdl/NOTICE
@@ -30,3 +30,19 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2024 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.
+
+-------------------------------------------------------------------
+
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 8adc342..e096f9a 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -55,8 +55,8 @@
   uintptr_t addr = reinterpret_cast<uintptr_t>(Ptr);
   // The aligned range of [0, kShadowAlign) uses a single shadow element, therefore all pointers in
   // this range must get the same aligned_addr below. This matches CFIShadowWriter::Add; not the
-  // same as align_up().
-  uintptr_t aligned_addr = align_down(addr, CFIShadow::kShadowAlign) + CFIShadow::kShadowAlign;
+  // same as just __builtin_align_up().
+  uintptr_t aligned_addr = __builtin_align_down(addr, CFIShadow::kShadowAlign) + CFIShadow::kShadowAlign;
   uintptr_t p = aligned_addr - (static_cast<uintptr_t>(v - CFIShadow::kRegularShadowMin)
                                 << CFIShadow::kCfiCheckGranularity);
 #ifdef __arm__
diff --git a/libm/Android.bp b/libm/Android.bp
index ee86959..69cfb14 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -32,7 +32,6 @@
 
     whole_static_libs: ["libarm-optimized-routines-math"],
 
-    tidy_disabled_srcs: ["upstream-*/**/*.c"],
     srcs: [
         "upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c",
         "upstream-freebsd/lib/msun/src/catrig.c",
@@ -404,9 +403,6 @@
         "-Wl,--Bsymbolic-functions",
     ],
 
-    // b/120614316, non-critical readibility check
-    tidy_checks: ["-cert-dcl16-c"],
-
     include_dirs: ["bionic/libc"],
     target: {
         bionic: {
diff --git a/linker/Android.bp b/linker/Android.bp
index 395b195..8300f01 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -559,3 +559,32 @@
         },
     },
 }
+
+cc_fuzz {
+    name: "ElfReader_fuzzer",
+    srcs: [
+        "ElfReader_fuzzer.cpp",
+        "linker.cpp",
+        "linker_block_allocator.cpp",
+        "linker_debug.cpp",
+        "linker_dlwarning.cpp",
+        "linker_globals.cpp",
+        "linker_mapped_file_fragment.cpp",
+        "linker_phdr.cpp",
+        "linker_phdr_16kib_compat.cpp",
+        "linker_sdk_versions.cpp",
+        "linker_utils.cpp",
+        ":elf_note_sources",
+    ],
+    static_libs: [
+        "libasync_safe",
+        "libbase",
+        "libziparchive",
+    ],
+    include_dirs: ["bionic/libc"],
+    // TODO: use all the architectures' files.
+    // We'll either need to give them unique names across architectures,
+    // or change soong to preserve subdirectories in `corpus:`,
+    // and maybe also the [deprecated] LLVM fuzzer infrastructure?
+    corpus: [":bionic_prebuilt_test_elf_files_arm64"],
+}
diff --git a/libc/bionic/strnlen.cpp b/linker/ElfReader_fuzzer.cpp
similarity index 73%
rename from libc/bionic/strnlen.cpp
rename to linker/ElfReader_fuzzer.cpp
index 7101b21..a23132b 100644
--- a/libc/bionic/strnlen.cpp
+++ b/linker/ElfReader_fuzzer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,21 @@
  * SUCH DAMAGE.
  */
 
-#include <string.h>
+#include "linker_phdr.h"
 
-size_t strnlen(const char* s, size_t n) {
-  const char* p = static_cast<const char*>(memchr(s, 0, n));
-  return p ? (p - s) : n;
+#include <stddef.h>
+#include <stdint.h>
+
+#include <android-base/file.h>
+
+// See current fuzz coverage here:
+// https://android-coverage.googleplex.com/fuzz_targets/ElfReader_fuzzer/index.html
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  TemporaryFile tf;
+  android::base::WriteFully(tf.fd, data, size);
+
+  ElfReader er;
+  er.Read(tf.path, tf.fd, 0, size);
+  return 0;
 }
diff --git a/linker/linker_note_gnu_property.cpp b/linker/linker_note_gnu_property.cpp
index 082a604..d221b8d 100644
--- a/linker/linker_note_gnu_property.cpp
+++ b/linker/linker_note_gnu_property.cpp
@@ -137,7 +137,7 @@
     // Loop on program property array.
     const ElfW(Prop)* property = reinterpret_cast<const ElfW(Prop)*>(&note_nhdr->n_desc[offset]);
     const ElfW(Word) property_size =
-        align_up(sizeof(ElfW(Prop)) + property->pr_datasz, sizeof(ElfW(Addr)));
+        __builtin_align_up(sizeof(ElfW(Prop)) + property->pr_datasz, sizeof(ElfW(Addr)));
     if ((note_nhdr->nhdr.n_descsz - offset) < property_size) {
       DL_ERR_AND_LOG(
           "\"%s\" .note.gnu.property: property descriptor size is "
diff --git a/linker/linker_note_gnu_property_test.cpp b/linker/linker_note_gnu_property_test.cpp
index 960118c..2a5eddc 100644
--- a/linker/linker_note_gnu_property_test.cpp
+++ b/linker/linker_note_gnu_property_test.cpp
@@ -107,7 +107,7 @@
   template <typename T>
   bool push(ElfW(Word) pr_type, ElfW(Word) pr_datasz, const T* pr_data) {
     // Must be aligned.
-    const uintptr_t addition = align_up(pr_datasz, sizeof(ElfW(Addr)));
+    const uintptr_t addition = __builtin_align_up(pr_datasz, sizeof(ElfW(Addr)));
     if ((offset() + addition) > kMaxSectionSize) {
       return false;
     }
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 8bcd76c..086c867 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -575,9 +575,7 @@
       continue;
     }
 
-#if defined(__LP64__) // TODO: remove this historical accident #if
     max_align_ = std::max(max_align_, static_cast<size_t>(phdr->p_align));
-#endif
 
     if (phdr->p_align > 1) {
       min_align_ = std::min(min_align_, static_cast<size_t>(phdr->p_align));
@@ -606,23 +604,22 @@
   // page size of the platform.
 #if defined(__LP64__)
   constexpr size_t kGapAlignment = 2 * 1024 * 1024;
-#else
-  constexpr size_t kGapAlignment = 0;
 #endif
   // Maximum gap size, in the units of kGapAlignment.
   constexpr size_t kMaxGapUnits = 32;
   // Allocate enough space so that the end of the desired region aligned up is still inside the
   // mapping.
-  size_t mmap_size = align_up(size, mapping_align) + mapping_align - page_size();
+  size_t mmap_size = __builtin_align_up(size, mapping_align) + mapping_align - page_size();
   uint8_t* mmap_ptr =
       reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
   if (mmap_ptr == MAP_FAILED) {
     return nullptr;
   }
   size_t gap_size = 0;
-  size_t first_byte = reinterpret_cast<size_t>(align_up(mmap_ptr, mapping_align));
-  size_t last_byte = reinterpret_cast<size_t>(align_down(mmap_ptr + mmap_size, mapping_align) - 1);
-  if (kGapAlignment && first_byte / kGapAlignment != last_byte / kGapAlignment) {
+  size_t first_byte = reinterpret_cast<size_t>(__builtin_align_up(mmap_ptr, mapping_align));
+  size_t last_byte = reinterpret_cast<size_t>(__builtin_align_down(mmap_ptr + mmap_size, mapping_align) - 1);
+#if defined(__LP64__)
+  if (first_byte / kGapAlignment != last_byte / kGapAlignment) {
     // This library crosses a 2MB boundary and will fragment a new huge page.
     // Lets take advantage of that and insert a random number of inaccessible huge pages before that
     // to improve address randomization and make it harder to locate this library code by probing.
@@ -630,23 +627,24 @@
     mapping_align = std::max(mapping_align, kGapAlignment);
     gap_size =
         kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
-    mmap_size = align_up(size + gap_size, mapping_align) + mapping_align - page_size();
+    mmap_size = __builtin_align_up(size + gap_size, mapping_align) + mapping_align - page_size();
     mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
     if (mmap_ptr == MAP_FAILED) {
       return nullptr;
     }
   }
+#endif
 
-  uint8_t *gap_end, *gap_start;
+  uint8_t* gap_end = mmap_ptr + mmap_size;
+#if defined(__LP64__)
   if (gap_size) {
-    gap_end = align_down(mmap_ptr + mmap_size, kGapAlignment);
-    gap_start = gap_end - gap_size;
-  } else {
-    gap_start = gap_end = mmap_ptr + mmap_size;
+    gap_end = __builtin_align_down(gap_end, kGapAlignment);
   }
+#endif
+  uint8_t* gap_start = gap_end - gap_size;
 
-  uint8_t* first = align_up(mmap_ptr, mapping_align);
-  uint8_t* last = align_down(gap_start, mapping_align) - size;
+  uint8_t* first = __builtin_align_up(mmap_ptr, mapping_align);
+  uint8_t* last = __builtin_align_down(gap_start, mapping_align) - size;
 
   // arc4random* is not available in first stage init because /dev/urandom hasn't yet been
   // created. Don't randomize then.
@@ -768,22 +766,23 @@
       continue;
     }
 
-    // If the PT_NOTE extends beyond the file. The ELF is doing something
-    // strange -- obfuscation, embedding hidden loaders, ...
-    //
-    // It doesn't contain the pad_segment note. Skip it to avoid SIGBUS
-    // by accesses beyond the file.
-    off64_t note_end_off = file_offset_ + phdr->p_offset + phdr->p_filesz;
-    if (note_end_off > file_size_) {
-      continue;
+    // Reject notes that claim to extend past the end of the file.
+    off64_t note_end_off = file_offset_;
+    if (__builtin_add_overflow(note_end_off, phdr->p_offset, &note_end_off) ||
+        __builtin_add_overflow(note_end_off, phdr->p_filesz, &note_end_off) ||
+        phdr->p_filesz != phdr->p_memsz ||
+        note_end_off > file_size_) {
+      DL_ERR("\"%s\": NT_ANDROID_TYPE_PAD_SEGMENT note runs off end of file",
+             name_.c_str());
+      return false;
     }
 
-    // note_fragment is scoped to within the loop so that there is
-    // at most 1 PT_NOTE mapped at anytime during this search.
+    // We scope note_fragment to within the loop so that there is
+    // at most one PT_NOTE mapped at any time.
     MappedFileFragment note_fragment;
-    if (!note_fragment.Map(fd_, file_offset_, phdr->p_offset, phdr->p_memsz)) {
+    if (!note_fragment.Map(fd_, file_offset_, phdr->p_offset, phdr->p_filesz)) {
       DL_ERR("\"%s\": PT_NOTE mmap(nullptr, %p, PROT_READ, MAP_PRIVATE, %d, %p) failed: %m",
-             name_.c_str(), reinterpret_cast<void*>(phdr->p_memsz), fd_,
+             name_.c_str(), reinterpret_cast<void*>(phdr->p_filesz), fd_,
              reinterpret_cast<void*>(page_start(file_offset_ + phdr->p_offset)));
       return false;
     }
@@ -797,7 +796,7 @@
     }
 
     if (note_hdr->n_descsz != sizeof(ElfW(Word))) {
-      DL_ERR("\"%s\" NT_ANDROID_TYPE_PAD_SEGMENT note has unexpected n_descsz: %u",
+      DL_ERR("\"%s\": NT_ANDROID_TYPE_PAD_SEGMENT note has unexpected n_descsz: %u",
              name_.c_str(), reinterpret_cast<unsigned int>(note_hdr->n_descsz));
       return false;
     }
@@ -1017,7 +1016,7 @@
     ElfW(Addr) seg_start = phdr->p_vaddr + load_bias_;
     ElfW(Addr) seg_end = seg_start + p_memsz;
 
-    ElfW(Addr) seg_page_end = align_up(seg_end, seg_align);
+    ElfW(Addr) seg_page_end = __builtin_align_up(seg_end, seg_align);
 
     ElfW(Addr) seg_file_end = seg_start + p_filesz;
 
@@ -1025,7 +1024,7 @@
     ElfW(Addr) file_start = phdr->p_offset;
     ElfW(Addr) file_end = file_start + p_filesz;
 
-    ElfW(Addr) file_page_start = align_down(file_start, seg_align);
+    ElfW(Addr) file_page_start = __builtin_align_down(file_start, seg_align);
     ElfW(Addr) file_length = file_end - file_page_start;
 
     if (file_size_ <= 0) {
diff --git a/linker/linker_phdr_16kib_compat.cpp b/linker/linker_phdr_16kib_compat.cpp
index bad20ba..d3783cf 100644
--- a/linker/linker_phdr_16kib_compat.cpp
+++ b/linker/linker_phdr_16kib_compat.cpp
@@ -158,7 +158,7 @@
   }
 
   if (!relro_phdr) {
-    *vaddr = align_down(first_rw->p_vaddr, kCompatPageSize);
+    *vaddr = __builtin_align_down(first_rw->p_vaddr, kCompatPageSize);
     return true;
   }
 
@@ -175,7 +175,7 @@
     return false;
   }
 
-  *vaddr = align_up(end, kCompatPageSize);
+  *vaddr = __builtin_align_up(end, kCompatPageSize);
   return true;
 }
 
@@ -227,11 +227,11 @@
   // will lead to overwriting adjacent segments since the ELF's segment(s)
   // are not 16KiB aligned.
 
-  void* start = reinterpret_cast<void*>(align_down(phdr->p_vaddr + load_bias_, kCompatPageSize));
+  void* start = reinterpret_cast<void*>(__builtin_align_down(phdr->p_vaddr + load_bias_, kCompatPageSize));
 
   // The ELF could be being loaded directly from a zipped APK,
   // the zip offset must be added to find the segment offset.
-  const ElfW(Addr) offset = file_offset_ + align_down(phdr->p_offset, kCompatPageSize);
+  const ElfW(Addr) offset = file_offset_ + __builtin_align_down(phdr->p_offset, kCompatPageSize);
 
   CHECK(should_use_16kib_app_compat_);
 
diff --git a/tests/Android.bp b/tests/Android.bp
index a97f5a8..e2ac09a 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -94,6 +94,13 @@
 // Prebuilt shared libraries for use in tests.
 // -----------------------------------------------------------------------------
 
+filegroup {
+    name: "bionic_prebuilt_test_elf_files_arm64",
+    srcs: [
+        "prebuilt-elf-files/arm64/*.so",
+    ],
+}
+
 cc_prebuilt_test_library_shared {
     name: "libtest_invalid-rw_load_segment",
     strip: {
@@ -372,9 +379,6 @@
         "bionic_tests_defaults",
         "large_system_property_node_defaults",
     ],
-    tidy_disabled_srcs: [
-        "malloc_test.cpp", // timed out with clang-tidy, and too many warnings
-    ],
     srcs: [
         "__aeabi_read_tp_test.cpp",
         "__cxa_atexit_test.cpp",
@@ -650,7 +654,6 @@
     static_libs: [
         "libbase",
     ],
-    tidy: false,
     target: {
         musl: {
             // Musl doesn't have fortify
@@ -659,12 +662,12 @@
     },
 }
 
-// Ensure we don't use FORTIFY'ed functions with the static analyzer/clang-tidy:
+// Ensure we don't use FORTIFY'ed functions with the clang static analyzer:
 // it can confuse these tools pretty easily. If this builds successfully, then
 // __clang_analyzer__ overrode FORTIFY. Otherwise, FORTIFY was incorrectly
 // enabled. The library that results from building this is meant to be unused.
 cc_test_library {
-    name: "fortify_disabled_for_tidy",
+    name: "fortify_disabled_for_clang_analyzer",
     defaults: [
         "bionic_clang_fortify_tests_w_flags",
     ],
@@ -674,7 +677,6 @@
         "-D__clang_analyzer__",
     ],
     srcs: ["clang_fortify_tests.cpp"],
-    tidy: false,
 }
 
 cc_test_library {
@@ -716,7 +718,6 @@
         "-U_FORTIFY_SOURCE",
     ],
     srcs: ["clang_fortify_tests.cpp"],
-    tidy: false,
 }
 
 cc_test_library {
@@ -765,7 +766,6 @@
     srcs: [
         "clang_fortify_c_only_tests.c",
     ],
-    tidy: false,
     shared: {
         enabled: false,
     },
@@ -1421,7 +1421,6 @@
             enabled: true,
         },
     },
-    tidy: false,
     clang_verify: true,
     cflags: [
         "-Wall",
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index ed0109a..456efa7 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -28,6 +28,10 @@
 // have to be naughty.
 #include "../libc/include/complex.h"
 
+// Ensure that libc++'s complex.h and __fwd/complex.h headers are no-ops.
+#define _LIBCPP_COMPLEX_H
+#define _LIBCPP___FWD_COMPLEX_H
+
 // (libc++ also seems to have really bad implementations of its own that ignore
 // the intricacies of floating point math.)
 // http://llvm.org/bugs/show_bug.cgi?id=21504
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index cb96f9f..7b64fbf 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -58,8 +58,7 @@
 }
 
 TEST_F(DEATHTEST, stpncpy2_fortified2) {
-  foo myfoo;
-  memset(&myfoo, 0, sizeof(myfoo));
+  foo myfoo = {};
   myfoo.one[0] = 'A'; // not null terminated string
   ASSERT_FORTIFY(stpncpy(myfoo.b, myfoo.one, sizeof(myfoo.b)));
 }
@@ -71,8 +70,7 @@
 }
 
 TEST_F(DEATHTEST, strncpy2_fortified2) {
-  foo myfoo;
-  memset(&myfoo, 0, sizeof(myfoo));
+  foo myfoo = {};
   myfoo.one[0] = 'A'; // not null terminated string
   ASSERT_FORTIFY(strncpy(myfoo.b, myfoo.one, sizeof(myfoo.b)));
 }
@@ -572,8 +570,7 @@
 
 TEST_F(DEATHTEST, FD_ISSET_fortified) {
 #if defined(__BIONIC__) // glibc catches this at compile-time.
-  fd_set set;
-  memset(&set, 0, sizeof(set));
+  fd_set set = {};
   ASSERT_FORTIFY(FD_ISSET(-1, &set));
 #endif
 }
diff --git a/tests/ifaddrs_test.cpp b/tests/ifaddrs_test.cpp
index da64770..01779f7 100644
--- a/tests/ifaddrs_test.cpp
+++ b/tests/ifaddrs_test.cpp
@@ -116,9 +116,7 @@
 
 static void CheckAddressIsInSet(const std::string& if_name, bool unicast,
                                 const std::set<in_addr_t>& addrs) {
-  ifreq ifr;
-  memset(&ifr, 0, sizeof(ifr));
-  ifr.ifr_addr.sa_family = AF_INET;
+  ifreq ifr = {.ifr_addr.sa_family = AF_INET};
   if_name.copy(ifr.ifr_name, IFNAMSIZ - 1);
 
   int fd = socket(AF_INET, SOCK_DGRAM, 0);
diff --git a/tests/libs/testbinary_is_stack_mte.cpp b/tests/libs/testbinary_is_stack_mte.cpp
index 0cdc466..3b6c79c 100644
--- a/tests/libs/testbinary_is_stack_mte.cpp
+++ b/tests/libs/testbinary_is_stack_mte.cpp
@@ -35,7 +35,7 @@
 
 #if defined(__BIONIC__) && defined(__aarch64__)
 
-extern "C" int main(int, char**) {
+int main(int, char**) {
   void* mte_tls_ptr = mte_tls();
   *reinterpret_cast<uintptr_t*>(mte_tls_ptr) = 1;
   int ret = is_stack_mte_on() && mte_tls_ptr != nullptr ? 0 : 1;
@@ -45,7 +45,7 @@
 
 #else
 
-extern "C" int main(int, char**) {
+int main(int, char**) {
   printf("RAN\n");
   return 1;
 }
diff --git a/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp b/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
index 35af8f4..93b6670 100644
--- a/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
+++ b/tests/libs/testbinary_is_stack_mte_after_dlopen.cpp
@@ -84,7 +84,7 @@
   // Useless, but should defeat TCO.
   return new_low + fault_new_stack_page(low, f);
 }
-extern "C" int main(int argc, char** argv) {
+int main(int argc, char** argv) {
   if (argc < 2) {
     return 1;
   }
@@ -150,7 +150,7 @@
 }
 
 #else
-extern "C" int main(int, char**) {
+int main(int, char**) {
   return 1;
 }
 #endif
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
index 1cb569c..f6e8a32 100644
--- a/tests/netdb_test.cpp
+++ b/tests/netdb_test.cpp
@@ -79,11 +79,7 @@
 }
 
 TEST(netdb, getaddrinfo_hints) {
-  addrinfo hints;
-  memset(&hints, 0, sizeof(hints));
-  hints.ai_family = AF_INET;
-  hints.ai_socktype = SOCK_STREAM;
-  hints.ai_protocol = IPPROTO_TCP;
+  addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP};
 
   addrinfo* ai = nullptr;
   ASSERT_EQ(0, getaddrinfo( "localhost", "9999", &hints, &ai));
@@ -113,8 +109,7 @@
 }
 
 TEST(netdb, getnameinfo_salen) {
-  sockaddr_storage ss;
-  memset(&ss, 0, sizeof(ss));
+  sockaddr_storage ss = {};
   sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
   char tmp[16];
 
@@ -142,11 +137,8 @@
 }
 
 TEST(netdb, getnameinfo_localhost) {
-  sockaddr_in addr;
   char host[NI_MAXHOST];
-  memset(&addr, 0, sizeof(sockaddr_in));
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = htonl(0x7f000001);
+  sockaddr_in addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(0x7f000001)};
   ASSERT_EQ(0, getnameinfo(reinterpret_cast<sockaddr*>(&addr), sizeof(addr),
                            host, sizeof(host), nullptr, 0, 0));
   ASSERT_STREQ(host, "localhost");
@@ -160,11 +152,8 @@
 }
 
 TEST(netdb, getnameinfo_ip6_localhost) {
-  sockaddr_in6 addr;
   char host[NI_MAXHOST];
-  memset(&addr, 0, sizeof(sockaddr_in6));
-  addr.sin6_family = AF_INET6;
-  addr.sin6_addr = in6addr_loopback;
+  sockaddr_in6 addr = {.sin6_family = AF_INET6, .sin6_addr = in6addr_loopback};
   ASSERT_EQ(0, getnameinfo(reinterpret_cast<sockaddr*>(&addr), sizeof(addr),
                            host, sizeof(host), nullptr, 0, 0));
   VerifyLocalhostName(host);
diff --git a/tests/netinet_ether_test.cpp b/tests/netinet_ether_test.cpp
index d7b81eb..a9de9bf 100644
--- a/tests/netinet_ether_test.cpp
+++ b/tests/netinet_ether_test.cpp
@@ -32,8 +32,7 @@
 }
 
 TEST(netinet_ether, ether_aton_r__ether_ntoa_r) {
-  ether_addr addr;
-  memset(&addr, 0, sizeof(addr));
+  ether_addr addr = {};
   ether_addr* a = ether_aton_r("12:34:56:78:9a:Bc", &addr);
   ASSERT_EQ(&addr, a);
   ASSERT_EQ(0x12, addr.ether_addr_octet[0]);
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index c1719dc..f8bfcef 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -804,10 +804,7 @@
 
   ASSERT_EQ(0, sigaction(SIGUSR1, &handler, nullptr));
 
-  siginfo sent;
-  memset(&sent, 0, sizeof(sent));
-
-  sent.si_code = SI_TKILL;
+  siginfo sent = {.si_code = SI_TKILL};
   ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
     << "rt_tgsigqueueinfo failed: " << strerror(errno) << error_msg;
   ASSERT_EQ(sent.si_code, received.si_code) << "rt_tgsigqueueinfo modified si_code, expected "
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index 2f891a6..fc6c25c 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -43,8 +43,7 @@
   const char* symbol = "<unknown>";
   int offset = 0;
 
-  Dl_info info;
-  memset(&info, 0, sizeof(info));
+  Dl_info info = {};
   if (dladdr(ip, &info) != 0) {
     symbol = info.dli_sname;
     if (info.dli_saddr != nullptr) {
diff --git a/tests/sys_msg_test.cpp b/tests/sys_msg_test.cpp
index b2d855d..26e4559 100644
--- a/tests/sys_msg_test.cpp
+++ b/tests/sys_msg_test.cpp
@@ -45,8 +45,7 @@
   ASSERT_NE(id, -1);
 
   // Queue should be empty.
-  msqid_ds ds;
-  memset(&ds, 0, sizeof(ds));
+  msqid_ds ds = {};
   ASSERT_EQ(0, msgctl(id, IPC_STAT, &ds));
   ASSERT_EQ(0U, ds.msg_qnum);
   ASSERT_EQ(0U, ds.msg_cbytes);
@@ -64,7 +63,7 @@
   ASSERT_EQ(sizeof(msg.data), ds.msg_cbytes);
 
   // Read the message.
-  memset(&msg, 0, sizeof(msg));
+  msg = {};
   ASSERT_EQ(static_cast<ssize_t>(sizeof(msg.data)),
             msgrcv(id, &msg, sizeof(msg.data), 0, 0));
   ASSERT_EQ(1, msg.type);
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
index 4a64742..d707c5d 100644
--- a/tests/sys_procfs_test.cpp
+++ b/tests/sys_procfs_test.cpp
@@ -20,20 +20,11 @@
 #include <sys/procfs.h>
 
 TEST(sys_procfs, types) {
-  elf_greg_t reg;
-  memset(&reg, 0, sizeof(reg));
-
-  elf_gregset_t regs;
-  memset(&regs, 0, sizeof(regs));
-
-  elf_fpregset_t fp_regs;
-  memset(&fp_regs, 0, sizeof(fp_regs));
-
-  prgregset_t pr_g_regs;
-  memset(&pr_g_regs, 0, sizeof(pr_g_regs));
-
-  prfpregset_t pr_fp_regs;
-  memset(&pr_fp_regs, 0, sizeof(pr_fp_regs));
+  elf_greg_t reg = {};
+  elf_gregset_t regs = {};
+  elf_fpregset_t fp_regs = {};
+  prgregset_t pr_g_regs = {};
+  prfpregset_t pr_fp_regs = {};
 
   static_assert(sizeof(prgregset_t) == sizeof(elf_gregset_t), "");
   static_assert(sizeof(prfpregset_t) == sizeof(elf_fpregset_t), "");
diff --git a/tests/sys_ptrace_test.cpp b/tests/sys_ptrace_test.cpp
index 499adbb..1f9c2a2 100644
--- a/tests/sys_ptrace_test.cpp
+++ b/tests/sys_ptrace_test.cpp
@@ -116,8 +116,7 @@
   ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, -1, &address)) << strerror(errno);
   ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, -2, &control)) << strerror(errno);
 #else // aarch64
-  user_hwdebug_state dreg_state;
-  memset(&dreg_state, 0, sizeof dreg_state);
+  user_hwdebug_state dreg_state = {};
   dreg_state.dbg_regs[0].addr = address;
   dreg_state.dbg_regs[0].ctrl = control;
 
@@ -304,8 +303,7 @@
   ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, 1, &address)) << strerror(errno);
   ASSERT_EQ(0, ptrace(PTRACE_SETHBPREGS, child, 2, &control)) << strerror(errno);
 #else  // aarch64
-  user_hwdebug_state dreg_state;
-  memset(&dreg_state, 0, sizeof dreg_state);
+  user_hwdebug_state dreg_state = {};
   dreg_state.dbg_regs[0].addr = reinterpret_cast<uintptr_t>(address);
   dreg_state.dbg_regs[0].ctrl = control;
 
diff --git a/tests/sys_sem_test.cpp b/tests/sys_sem_test.cpp
index 27943cf..0b7a7ff 100644
--- a/tests/sys_sem_test.cpp
+++ b/tests/sys_sem_test.cpp
@@ -47,8 +47,7 @@
   ASSERT_NE(id, -1);
 
   // Check semaphore info.
-  semid_ds ds;
-  memset(&ds, 0, sizeof(ds));
+  semid_ds ds = {};
   ASSERT_EQ(0, semctl(id, 0, IPC_STAT, &ds));
   ASSERT_EQ(1U, ds.sem_nsems);
 
diff --git a/tests/sys_shm_test.cpp b/tests/sys_shm_test.cpp
index 65f9eba..74d13b5 100644
--- a/tests/sys_shm_test.cpp
+++ b/tests/sys_shm_test.cpp
@@ -44,8 +44,7 @@
   ASSERT_NE(id, -1);
 
   // Check segment info.
-  shmid_ds ds;
-  memset(&ds, 0, sizeof(ds));
+  shmid_ds ds = {};
   ASSERT_EQ(0, shmctl(id, IPC_STAT, &ds));
   ASSERT_EQ(1234U, ds.shm_segsz);
 
diff --git a/tests/sys_socket_test.cpp b/tests/sys_socket_test.cpp
index 1cfbfb2..559ee7d 100644
--- a/tests/sys_socket_test.cpp
+++ b/tests/sys_socket_test.cpp
@@ -42,10 +42,7 @@
     return reinterpret_cast<void*>(-1);
   }
 
-  struct sockaddr_un addr;
-  memset(&addr, 0, sizeof(addr));
-  addr.sun_family = AF_UNIX;
-  addr.sun_path[0] = '\0';
+  struct sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path[0] = '\0'};
   strcpy(addr.sun_path + 1, pdata->sock_path);
 
   if (connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) {
@@ -66,10 +63,7 @@
   int fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
   ASSERT_NE(fd, -1) << strerror(errno);
 
-  struct sockaddr_un addr;
-  memset(&addr, 0, sizeof(addr));
-  addr.sun_family = AF_UNIX;
-  addr.sun_path[0] = '\0';
+  struct sockaddr_un addr = {.sun_family = AF_UNIX, .sun_path[0] = '\0'};
   strcpy(addr.sun_path + 1, sock_path);
 
   ASSERT_NE(-1, bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))) << strerror(errno);
@@ -141,9 +135,7 @@
   int fd_acc = accept(fd, reinterpret_cast<struct sockaddr*>(addr), &len);
   ASSERT_NE(fd_acc, -1) << strerror(errno);
 
-  struct mmsghdr msgs[NUM_RECV_MSGS];
-  memset(msgs, 0, sizeof(struct mmsghdr)*NUM_RECV_MSGS);
-
+  struct mmsghdr msgs[NUM_RECV_MSGS] = {};
   struct iovec io[NUM_RECV_MSGS];
   char bufs[NUM_RECV_MSGS][100];
   for (size_t i = 0; i < NUM_RECV_MSGS; i++) {
@@ -155,10 +147,7 @@
     msgs[i].msg_len = sizeof(struct msghdr);
   }
 
-  struct timespec ts;
-  memset(&ts, 0, sizeof(ts));
-  ts.tv_sec = 5;
-  ts.tv_nsec = 0;
+  struct timespec ts = {.tv_sec = 5, .tv_nsec = 0};
   ASSERT_EQ(NUM_RECV_MSGS,
             static_cast<size_t>(recvmmsg(fd_acc, msgs, NUM_RECV_MSGS, 0, &ts)))
            << strerror(errno);
@@ -189,8 +178,7 @@
 #define NUM_SEND_MSGS (sizeof(g_SendMsgs)/sizeof(const char*))
 
 static bool SendMMsg(int fd) {
-  struct mmsghdr msgs[NUM_SEND_MSGS];
-  memset(msgs, 0, sizeof(struct mmsghdr)*NUM_SEND_MSGS);
+  struct mmsghdr msgs[NUM_SEND_MSGS] = {};
   struct iovec io[NUM_SEND_MSGS];
   for (size_t i = 0; i < NUM_SEND_MSGS; i++) {
     io[i].iov_base = reinterpret_cast<void*>(const_cast<char*>(g_SendMsgs[i]));
diff --git a/tests/sys_sysinfo_test.cpp b/tests/sys_sysinfo_test.cpp
index 69656ad..b8bcf92 100644
--- a/tests/sys_sysinfo_test.cpp
+++ b/tests/sys_sysinfo_test.cpp
@@ -39,8 +39,7 @@
 }
 
 TEST(sys_sysinfo, sysinfo) {
-  struct sysinfo si;
-  memset(&si, 0, sizeof(si));
+  struct sysinfo si = {};
   ASSERT_EQ(0, sysinfo(&si));
 
   ASSERT_GT(static_cast<long>(si.uptime), 10);  // You're not running CTS within 10s of booting!
diff --git a/tests/sys_timex_test.cpp b/tests/sys_timex_test.cpp
index 44b73c9..627c1ee 100644
--- a/tests/sys_timex_test.cpp
+++ b/tests/sys_timex_test.cpp
@@ -21,15 +21,13 @@
 #include <gtest/gtest.h>
 
 TEST(sys_timex, adjtimex_smoke) {
-  timex t;
-  memset(&t, 0, sizeof(t));
+  timex t = {};
   // adjtimex/clock_adjtime return the clock state on success, -1 on failure.
   ASSERT_NE(-1, adjtimex(&t));
 }
 
 TEST(sys_timex, clock_adjtime_smoke) {
-  timex t;
-  memset(&t, 0, sizeof(t));
+  timex t = {};
   // adjtimex/clock_adjtime return the clock state on success, -1 on failure.
   ASSERT_NE(-1, clock_adjtime(CLOCK_REALTIME, &t));
 }
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index baafbf6..cf4de06 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -126,8 +126,7 @@
   // tzcode used to have a bug where it didn't reinitialize some internal state.
 
   // Choose a time where DST is set.
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
+  struct tm t = {};
   t.tm_year = 1980 - 1900;
   t.tm_mon = 6;
   t.tm_mday = 2;
@@ -136,7 +135,7 @@
   tzset();
   ASSERT_EQ(static_cast<time_t>(331372800U), mktime(&t));
 
-  memset(&t, 0, sizeof(tm));
+  t = {};
   t.tm_year = 1980 - 1900;
   t.tm_mon = 6;
   t.tm_mday = 2;
@@ -173,8 +172,7 @@
 TEST(time, mktime_EOVERFLOW) {
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
+  struct tm t = {};
 
   // LP32 year range is 1901-2038, so this year is guaranteed not to overflow.
   t.tm_year = 2016 - 1900;
@@ -212,8 +210,7 @@
 TEST(time, mktime_invalid_tm_TZ_combination) {
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
+  struct tm t = {};
   t.tm_year = 2022 - 1900;
   t.tm_mon = 11;
   t.tm_mday = 31;
@@ -248,8 +245,7 @@
 TEST(time, strftime) {
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
+  struct tm t = {};
   t.tm_year = 200;
   t.tm_mon = 2;
   t.tm_mday = 10;
@@ -270,8 +266,7 @@
 TEST(time, strftime_second_before_epoch) {
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
+  struct tm t = {};
   t.tm_year = 1969 - 1900;
   t.tm_mon = 11;
   t.tm_mday = 31;
@@ -287,9 +282,7 @@
 
 TEST(time, strftime_Z_null_tm_zone) {
   // Netflix on Nexus Player wouldn't start (http://b/25170306).
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
-
+  struct tm t = {};
   char buf[64];
 
   setenv("TZ", "America/Los_Angeles", 1);
@@ -409,8 +402,7 @@
 
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
+  struct tm t = {};
   t.tm_year = 200;
   t.tm_mon = 2;
   t.tm_mday = 10;
@@ -427,15 +419,14 @@
 TEST(time, strptime) {
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
+  struct tm t = {};
   char buf[64];
 
-  memset(&t, 0, sizeof(t));
   strptime("11:14", "%R", &t);
   strftime(buf, sizeof(buf), "%H:%M", &t);
   EXPECT_STREQ("11:14", buf);
 
-  memset(&t, 0, sizeof(t));
+  t = {};
   strptime("09:41:53", "%T", &t);
   strftime(buf, sizeof(buf), "%H:%M:%S", &t);
   EXPECT_STREQ("09:41:53", buf);
@@ -445,15 +436,14 @@
 #if !defined(ANDROID_HOST_MUSL)
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
+  struct tm t = {};
   char buf[64];
 
-  memset(&t, 0, sizeof(t));
   strptime_l("11:14", "%R", &t, LC_GLOBAL_LOCALE);
   strftime_l(buf, sizeof(buf), "%H:%M", &t, LC_GLOBAL_LOCALE);
   EXPECT_STREQ("11:14", buf);
 
-  memset(&t, 0, sizeof(t));
+  t = {};
   strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
   strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
   EXPECT_STREQ("09:41:53", buf);
@@ -637,8 +627,7 @@
 }
 
 TEST(time, timer_create) {
-  sigevent se;
-  memset(&se, 0, sizeof(se));
+  sigevent se = {};
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = NoOpNotifyFunction;
   timer_t timer_id;
@@ -666,8 +655,7 @@
 }
 
 TEST(time, timer_create_SIGEV_SIGNAL) {
-  sigevent se;
-  memset(&se, 0, sizeof(se));
+  sigevent se = {};
   se.sigev_notify = SIGEV_SIGNAL;
   se.sigev_signo = SIGUSR1;
 
@@ -705,10 +693,7 @@
 
  public:
   explicit Counter(void (*fn)(sigval)) : value(0), timer_valid(false) {
-    memset(&se, 0, sizeof(se));
-    se.sigev_notify = SIGEV_THREAD;
-    se.sigev_notify_function = fn;
-    se.sigev_value.sival_ptr = this;
+    se = {.sigev_notify = SIGEV_THREAD, .sigev_notify_function = fn, .sigev_value.sival_ptr = this};
     Create();
   }
   void DeleteTimer() {
@@ -909,9 +894,7 @@
 
 TEST(time, timer_delete_from_timer_thread) {
   TimerDeleteData tdd;
-  sigevent se;
-
-  memset(&se, 0, sizeof(se));
+  sigevent se = {};
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = TimerDeleteCallback;
   se.sigev_value.sival_ptr = &tdd;
@@ -1252,11 +1235,9 @@
   strftime(buf, sizeof(buf), "<%s>", &tm0);
   EXPECT_STREQ("<378691200>", buf);
 
-  struct tm tm;
-
   setenv("TZ", "America/Los_Angeles", 1);
   tzset();
-  memset(&tm, 0xff, sizeof(tm));
+  struct tm tm = {};
   char* p = strptime("378720000x", "%s", &tm);
   ASSERT_EQ('x', *p);
   EXPECT_EQ(0, tm.tm_sec);
@@ -1271,7 +1252,7 @@
 
   setenv("TZ", "UTC", 1);
   tzset();
-  memset(&tm, 0xff, sizeof(tm));
+  tm = {};
   p = strptime("378691200x", "%s", &tm);
   ASSERT_EQ('x', *p);
   EXPECT_EQ(0, tm.tm_sec);
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index fd3b332..b554ee5 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -73,9 +73,8 @@
   uselocale(LC_GLOBAL_LOCALE);
 
   char out[MB_LEN_MAX];
-  mbstate_t ps;
+  mbstate_t ps = {};
 
-  memset(&ps, 0, sizeof(ps));
   EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xc2", 1, &ps));
   errno = 0;
   EXPECT_EQ(static_cast<size_t>(-1), c32rtomb(out, 0x00a2, &ps));
@@ -86,12 +85,12 @@
 
   // If the first argument to c32rtomb is nullptr or the second is L'\0' the shift
   // state should be reset.
-  memset(&ps, 0, sizeof(ps));
+  ps = {};
   EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xc2", 1, &ps));
   EXPECT_EQ(1U, c32rtomb(nullptr, 0x00a2, &ps));
   EXPECT_TRUE(mbsinit(&ps));
 
-  memset(&ps, 0, sizeof(ps));
+  ps = {};
   EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xf0\xa4", 1, &ps));
   EXPECT_EQ(1U, c32rtomb(out, L'\0', &ps));
   EXPECT_TRUE(mbsinit(&ps));
@@ -299,8 +298,7 @@
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
-  mbstate_t ps;
-  memset(&ps, 0, sizeof(ps));
+  mbstate_t ps = {};
 
   test_mbrtoc16_incomplete(&ps);
   test_mbrtoc16_incomplete(nullptr);
@@ -475,8 +473,7 @@
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
-  mbstate_t ps;
-  memset(&ps, 0, sizeof(ps));
+  mbstate_t ps = {};
 
   test_mbrtoc32_incomplete(&ps);
   test_mbrtoc32_incomplete(nullptr);
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 9ad3b6d..3143c23 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1393,9 +1393,7 @@
 }
 
 TEST(UNISTD_TEST, setdomainname) {
-  __user_cap_header_struct header;
-  memset(&header, 0, sizeof(header));
-  header.version = _LINUX_CAPABILITY_VERSION_3;
+  __user_cap_header_struct header = {.version = _LINUX_CAPABILITY_VERSION_3};
 
   __user_cap_data_struct old_caps[_LINUX_CAPABILITY_U32S_3];
   ASSERT_EQ(0, capget(&header, &old_caps[0]));
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index a811fd8..ba2a4d8 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -130,22 +130,21 @@
   uselocale(LC_GLOBAL_LOCALE);
 
   char out[MB_LEN_MAX];
-  mbstate_t ps;
+  mbstate_t ps = {};
 
   // Any non-initial state is invalid when calling wcrtomb.
-  memset(&ps, 0, sizeof(ps));
   EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps));
   EXPECT_EQ(static_cast<size_t>(-1), wcrtomb(out, 0x00a2, &ps));
   EXPECT_ERRNO(EILSEQ);
 
   // If the first argument to wcrtomb is NULL or the second is L'\0' the shift
   // state should be reset.
-  memset(&ps, 0, sizeof(ps));
+  ps = {};
   EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps));
   EXPECT_EQ(1U, wcrtomb(nullptr, 0x00a2, &ps));
   EXPECT_TRUE(mbsinit(&ps));
 
-  memset(&ps, 0, sizeof(ps));
+  ps = {};
   EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xf0\xa4", 1, &ps));
   EXPECT_EQ(1U, wcrtomb(out, L'\0', &ps));
   EXPECT_TRUE(mbsinit(&ps));
@@ -253,9 +252,8 @@
   EXPECT_STREQ("hix", bytes);
 
   // Any non-initial state is invalid when calling wcsrtombs.
-  mbstate_t ps;
+  mbstate_t ps = {};
   src = chars;
-  memset(&ps, 0, sizeof(ps));
   ASSERT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "\xc2", 1, &ps));
   EXPECT_EQ(static_cast<size_t>(-1), wcsrtombs(nullptr, &src, 0, &ps));
   EXPECT_ERRNO(EILSEQ);
@@ -449,8 +447,7 @@
 }
 
 TEST(wchar, mbrtowc_incomplete) {
-  mbstate_t ps;
-  memset(&ps, 0, sizeof(ps));
+  mbstate_t ps = {};
 
   test_mbrtowc_incomplete(&ps);
   test_mbrtowc_incomplete(nullptr);
@@ -508,8 +505,7 @@
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
-  mbstate_t ps;
-  memset(&ps, 0, sizeof(ps));
+  mbstate_t ps = {};
   test_mbsrtowcs(&ps);
   test_mbsrtowcs(nullptr);
 
@@ -659,12 +655,7 @@
 TEST(wchar, wcsftime__wcsftime_l) {
   setenv("TZ", "UTC", 1);
 
-  struct tm t;
-  memset(&t, 0, sizeof(tm));
-  t.tm_year = 200;
-  t.tm_mon = 2;
-  t.tm_mday = 10;
-
+  struct tm t = {.tm_year = 200, .tm_mon = 2, .tm_mday = 10};
   wchar_t buf[64];
 
   EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t));