Merge "Remove ASan test" into main
diff --git a/README.md b/README.md
index 113ffd7..aafbcff 100644
--- a/README.md
+++ b/README.md
@@ -374,6 +374,19 @@
 
     $ ./tests/run-on-host.sh glibc
 
+### Against musl
+
+Another way to verify test behavior is to run against musl on the host. glibc
+musl don't always match, so this can be a good way to find the more complicated
+corners of the spec. If they *do* match, bionic probably should too!
+
+    $ OUT_DIR=$(ANDROID_BUILD_TOP)/musl-out ./tests/run-on-host.sh musl
+
+Note: the alternate OUT_DIR is used to avoid causing excessive rebuilding when
+switching between glibc and musl. The first musl test run will be expensive
+because it will not reuse any already built artifacts, but subsequent runs will
+be cheaper than if you hadn't used it.
+
 ## Gathering test coverage
 
 To get test coverage for bionic, use `//bionic/build/coverage.sh`. Before
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 8ffd96f..ab3b247 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -146,8 +146,8 @@
 (on a 4096-byte boundary) in the zip file and stored uncompressed.
 Current versions of the zipalign tool take care of alignment.
 
-Note that in API level 23 and above dlopen(3) will open a library from
-any zip file, not just your APK. Just give dlopen(3) a path of the form
+Note that in API level 23 and above dlopen(3) can open a library from
+any zip file, not just an APK. Just give dlopen(3) a path of the form
 "my_zip_file.zip!/libs/libstuff.so". As with APKs, the library must be
 page-aligned and stored uncompressed for this to work.
 
@@ -479,3 +479,20 @@
 You can read more about relative relocations
 and their long and complicated history at
 https://maskray.me/blog/2021-10-31-relative-relocations-and-relr.
+
+## No more sentinels in .preinit_array/.init_array/.fini_array sections of executables (in All API levels)
+
+In Android <= U and NDK <= 26, Android used sentinels in these sections of
+executables to locate the start and end of arrays. However, when building with
+LTO, the function pointers in the arrays can be reordered, making sentinels no
+longer work. This prevents constructors for global C++ variables from being
+called in static executables when using LTO.
+
+To fix this, in Android >= V and NDK >= 27, we removed sentinels and switched
+to using symbols inserted by LLD (like `__init_array_start`,
+`__init_array_end`) to locate the arrays. This also avoids keeping a section
+when there are no corresponding functions.
+
+For dynamic executables, we kept sentinel support in crtbegin_dynamic.o and
+libc.so. This ensures that executables built with newer crtbegin_dynamic.o
+(in NDK >= 27) work with older libc.so (in Android <= U), and vice versa.
diff --git a/benchmarks/malloc_map_benchmark.cpp b/benchmarks/malloc_map_benchmark.cpp
index 5757325..04c9a07 100644
--- a/benchmarks/malloc_map_benchmark.cpp
+++ b/benchmarks/malloc_map_benchmark.cpp
@@ -52,7 +52,7 @@
         android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
       android::meminfo::Vma update_vma(vma);
       if (!proc_mem.FillInVmaStats(update_vma)) {
-        err(1, "FillInVmaStats failed\n");
+        err(1, "FillInVmaStats failed");
       }
       *rss_bytes += update_vma.usage.rss;
     }
diff --git a/docs/status.md b/docs/status.md
index 1838b85..3c5d1ba 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -56,12 +56,19 @@
 Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
 
 New libc functions in V (API level 35):
+  * `tcgetwinsize`, `tcsetwinsize` (POSIX Issue 8 additions).
   * `timespec_getres` (C23 addition).
   * `localtime_rz`, `mktime_z`, `tzalloc`, and `tzfree` (NetBSD
     extensions implemented in tzcode, and the "least non-standard"
     functions for avoiding $TZ if you need to use multiple timezones in
     multi-threaded C).
   * `mbsrtowcs_l` and `wcsrtombs_l` aliases for `mbsrtowcs` and `wcsrtombs`.
+  * New system call wrappers: `__riscv_flush_icache` (`<sys/cachectl.h>`),
+    `__riscv_hwprobe` (`<sys/hwprobe.h>`), `epoll_pwait2`/`epoll_pwait2_64` (`<sys/epoll.h>`).
+
+New libc behavior in V (API level 35):
+  * Added `LD_SHOW_AUXV` to the dynamic linker to dump the ELF auxiliary
+    vector if the environment variable is set.
 
 New libc functions in U (API level 34):
   * `close_range` and `copy_file_range` (Linux-specific GNU extensions).
diff --git a/libc/Android.bp b/libc/Android.bp
index dc3c73f..68a0838 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -55,6 +55,7 @@
     "-Wno-deprecated-declarations",
     "-Wno-gcc-compat",
     "-Wframe-larger-than=2048",
+    "-Wno-reorder-init-list",
 
     // Try to catch typical 32-bit assumptions that break with 64-bit pointers.
     "-Werror=pointer-to-int-cast",
@@ -133,6 +134,8 @@
     lto: {
         never: true,
     },
+
+    apex_available: ["com.android.runtime"],
 }
 
 libc_scudo_product_variables = {
@@ -334,10 +337,16 @@
 // automatically included.
 
 cc_library_static {
+    name: "libc_freebsd_ldexp",
+    defaults: ["libc_defaults"],
+    cflags: ["-Dscalbn=ldexp"],
+    srcs: [":libc_ldexp_srcs"],
+}
+
+cc_library_static {
     defaults: ["libc_defaults"],
     tidy_disabled_srcs: ["upstream-*/**/*.c"],
     srcs: [
-        "upstream-freebsd/lib/libc/gen/ldexp.c",
         "upstream-freebsd/lib/libc/stdlib/getopt_long.c",
         "upstream-freebsd/lib/libc/stdlib/hcreate.c",
         "upstream-freebsd/lib/libc/stdlib/hcreate_r.c",
@@ -1276,9 +1285,6 @@
     srcs: [
         "bionic/bionic_systrace.cpp",
     ],
-    apex_available: [
-        "com.android.runtime",
-    ],
 }
 
 // ========================================================
@@ -1475,6 +1481,7 @@
         "libc_fortify",
         "libc_freebsd",
         "libc_freebsd_large_stack",
+        "libc_freebsd_ldexp",
         "libc_gdtoa",
         "libc_netbsd",
         "libc_openbsd_large_stack",
@@ -1509,6 +1516,7 @@
         "libc_fortify",
         "libc_freebsd",
         "libc_freebsd_large_stack",
+        "libc_freebsd_ldexp",
         "libc_gdtoa",
         "libc_netbsd",
         "libc_openbsd",
@@ -1831,7 +1839,6 @@
         },
     },
 
-
     apex_available: [
         "//apex_available:platform",
         "com.android.runtime",
@@ -2095,6 +2102,9 @@
     name: "libstdc++",
     static_ndk_lib: true,
     static_libs: ["libasync_safe"],
+    apex_available: [
+        "//apex_available:platform",
+    ],
 
     static: {
         system_shared_libs: [],
@@ -2273,6 +2283,8 @@
         "bionic", // crtbegin.c includes bionic/libc_init_common.h
     ],
 
+    cflags: [ "-DCRTBEGIN_STATIC", ],
+
     srcs: ["arch-common/bionic/crtbegin.c"],
     objs: [
         "crtbrand",
@@ -2478,8 +2490,6 @@
     name: "libc",
     symbol_file: "libc.map.txt",
     first_version: "9",
-    // APIs implemented in asm don't have debug info: http://b/190554910.
-    allow_untyped_symbols: true,
     export_header_libs: [
         "common_libc",
         "libc_uapi",
diff --git a/libc/SECCOMP_ALLOWLIST_COMMON.TXT b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
index efbf28b..1d58475 100644
--- a/libc/SECCOMP_ALLOWLIST_COMMON.TXT
+++ b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
@@ -11,12 +11,15 @@
 # Syscalls used internally by bionic, but not exposed directly.
 pid_t	gettid()	all
 int	futex(int*, int, int, const timespec*, int*, int)	all
-int	clone(int (*)(void*), void*, int, void*, ...) all
+pid_t	clone(int (*)(void*), void*, int, void*, ...) all
 int	sigreturn(unsigned long)	lp32
 int	rt_sigreturn(unsigned long)	all
 int	rt_tgsigqueueinfo(pid_t, pid_t, int, siginfo_t*)	all
 int	restart_syscall()	all
 
+# The public API doesn't set errno, so we call this via inline assembler.
+int riscv_hwprobe(riscv_hwprobe*, size_t, size_t, unsigned long*, unsigned) riscv64
+
 # vfork is used by bionic (and java.lang.ProcessBuilder) on some
 # architectures. (The others use clone(2) directly instead.)
 pid_t	vfork()	arm,x86,x86_64
@@ -53,6 +56,7 @@
 int execveat(int, const char*, char* const*, char* const*, int)  all
 # Since Linux 4.3, not in glibc. Probed for and conditionally used by ART.
 int membarrier(int, int) all
+int userfaultfd(int) all
 # Since Linux 5.1, not in glibc. Not used by bionic, and not likely ever
 # to be (because the last thing anyone needs is a new 32-bit ABI in the
 # 2020s!) but http://b/138781460 showed cuttlefish needed at least the
@@ -73,5 +77,8 @@
 int rt_sigtimedwait_time64(const sigset64_t*, siginfo_t*, const timespec64*, size_t) lp32
 int futex_time64(int*, int, int, const timespec64*, int*, int) lp32
 int sched_rr_get_interval_time64(pid_t, timespec64*) lp32
-# Since Linux 5.4, not in glibc. Probed for and conditionally used by ART.
-int userfaultfd(int) all
+# Since Linux 5.3, not in glibc. Not used by bionic, but increasingly
+# likely to be useful as new features are added. In particular, cgroups
+# support seems potentially useful for Android (though the struct that
+# changes size over time is obviously problematic).
+pid_t clone3(clone_args*, size_t) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 08017f1..0db5d79 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -161,7 +161,7 @@
 int linkat(int, const char*, int, const char*, int)  all
 int mkdirat(int, const char*, mode_t)  all
 int mknodat(int, const char*, mode_t, dev_t)  all
-int readlinkat(int, const char*, char*, size_t)  all
+ssize_t readlinkat(int, const char*, char*, size_t)  all
 int renameat2(int, const char*, int, const char*, unsigned)  all
 int symlinkat(const char*, int, const char*)  all
 int unlinkat(int, const char*, int)   all
@@ -322,6 +322,7 @@
 int __epoll_create1:epoll_create1(int)  all
 int epoll_ctl(int, int op, int, struct epoll_event*)  all
 int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset64_t*, size_t)  all
+int __epoll_pwait2:epoll_pwait2(int, struct epoll_event*, int, const timespec64*, const sigset64_t*, size_t)  all
 
 int __eventfd:eventfd2(unsigned int, int)  all
 
@@ -356,7 +357,7 @@
 int     cacheflush:__ARM_NR_cacheflush(long start, long end, long flags)  arm
 
 # riscv64-specific
-int _flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
+int __riscv_flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
 
 # x86-specific
 int     __set_thread_area:set_thread_area(void*) x86
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index b87db64..127896a 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -30,17 +30,53 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#define SECTION(name) __attribute__((__section__(name)))
-SECTION(".preinit_array") init_func_t* __PREINIT_ARRAY__ = (init_func_t*)-1;
-SECTION(".init_array.0") init_func_t* __INIT_ARRAY__ = (init_func_t*)-1;
-SECTION(".fini_array.0") fini_func_t* __FINI_ARRAY__ = (fini_func_t*)-1;
-#undef SECTION
+extern init_func_t* __preinit_array_start[];
+extern init_func_t* __preinit_array_end[];
+extern init_func_t* __init_array_start[];
+extern init_func_t* __init_array_end[];
+extern fini_func_t* __fini_array_start[];
+extern fini_func_t* __fini_array_end[];
+
+#if !defined(CRTBEGIN_STATIC)
+/* This function will be called during normal program termination
+ * to run the destructors that are listed in the .fini_array section
+ * of the executable, if any.
+ *
+ * 'fini_array' points to a list of function addresses.
+ */
+static void call_fini_array() {
+  fini_func_t** array = __fini_array_start;
+  size_t count = __fini_array_end - __fini_array_start;
+  // Call fini functions in reverse order.
+  while (count-- > 0) {
+    fini_func_t* function = array[count];
+    (*function)();
+  }
+}
+
+// libc.so needs fini_array with sentinels. So create a fake fini_array with sentinels.
+// It contains a function to call functions in real fini_array.
+static fini_func_t* fini_array_with_sentinels[] = {
+    (fini_func_t*)-1,
+    &call_fini_array,
+    (fini_func_t*)0,
+};
+#endif  // !defined(CRTBEGIN_STATIC)
 
 __used static void _start_main(void* raw_args) {
-  structors_array_t array;
-  array.preinit_array = &__PREINIT_ARRAY__;
-  array.init_array = &__INIT_ARRAY__;
-  array.fini_array = &__FINI_ARRAY__;
+  structors_array_t array = {};
+#if defined(CRTBEGIN_STATIC)
+  array.preinit_array = __preinit_array_start;
+  array.preinit_array_count = __preinit_array_end - __preinit_array_start;
+  array.init_array = __init_array_start;
+  array.init_array_count = __init_array_end - __init_array_start;
+  array.fini_array = __fini_array_start;
+  array.fini_array_count = __fini_array_end - __fini_array_start;
+#else
+  if (__fini_array_end - __fini_array_start > 0) {
+    array.fini_array = fini_array_with_sentinels;
+  }
+#endif  // !defined(CRTBEGIN_STATIC)
 
   __libc_init(raw_args, NULL, &main, &array);
 }
diff --git a/libc/arch-common/bionic/crtend.S b/libc/arch-common/bionic/crtend.S
index 49c729f..74b3aa9 100644
--- a/libc/arch-common/bionic/crtend.S
+++ b/libc/arch-common/bionic/crtend.S
@@ -34,18 +34,6 @@
 __bionic_asm_custom_note_gnu_section()
 #endif
 
-	.section .preinit_array, "aw"
-	ASM_ALIGN_TO_PTR_SIZE
-	ASM_PTR_SIZE(0)
-
-	.section .init_array, "aw"
-	ASM_ALIGN_TO_PTR_SIZE
-	ASM_PTR_SIZE(0)
-
-	.section .fini_array, "aw"
-	ASM_ALIGN_TO_PTR_SIZE
-	ASM_PTR_SIZE(0)
-
 	.section .note.GNU-stack, "", %progbits
 
 #if !defined(__arm__)
diff --git a/libc/arch-riscv64/string/memchr_vext.S b/libc/arch-riscv64/string/memchr_vext.S
index 3761265..ed76a05 100644
--- a/libc/arch-riscv64/string/memchr_vext.S
+++ b/libc/arch-riscv64/string/memchr_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define iResult a0
 
diff --git a/libc/arch-riscv64/string/memcmp_vext.S b/libc/arch-riscv64/string/memcmp_vext.S
index d8e7a06..1bb381c 100644
--- a/libc/arch-riscv64/string/memcmp_vext.S
+++ b/libc/arch-riscv64/string/memcmp_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define iResult a0
 
diff --git a/libc/arch-riscv64/string/memcpy_vext.S b/libc/arch-riscv64/string/memcpy_vext.S
index 100f538..668973f 100644
--- a/libc/arch-riscv64/string/memcpy_vext.S
+++ b/libc/arch-riscv64/string/memcpy_vext.S
@@ -52,9 +52,10 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define pSrc a1
diff --git a/libc/arch-riscv64/string/memmove_vext.S b/libc/arch-riscv64/string/memmove_vext.S
index 722ffd1..03f10c5 100644
--- a/libc/arch-riscv64/string/memmove_vext.S
+++ b/libc/arch-riscv64/string/memmove_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define pSrc a1
diff --git a/libc/arch-riscv64/string/memset_vext.S b/libc/arch-riscv64/string/memset_vext.S
index ef8387d..554d6bd 100644
--- a/libc/arch-riscv64/string/memset_vext.S
+++ b/libc/arch-riscv64/string/memset_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define iValue a1
diff --git a/libc/arch-riscv64/string/strcat_vext.S b/libc/arch-riscv64/string/strcat_vext.S
index 790c07a..05e0dfc 100644
--- a/libc/arch-riscv64/string/strcat_vext.S
+++ b/libc/arch-riscv64/string/strcat_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define pSrc a1
diff --git a/libc/arch-riscv64/string/strchr_vext.S b/libc/arch-riscv64/string/strchr_vext.S
index 89828ea..4c7bac1 100644
--- a/libc/arch-riscv64/string/strchr_vext.S
+++ b/libc/arch-riscv64/string/strchr_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pStr a0
 #define iCh a1
diff --git a/libc/arch-riscv64/string/strcmp_vext.S b/libc/arch-riscv64/string/strcmp_vext.S
index d6ad96e..b793c9a 100644
--- a/libc/arch-riscv64/string/strcmp_vext.S
+++ b/libc/arch-riscv64/string/strcmp_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define iResult a0
 
diff --git a/libc/arch-riscv64/string/strcpy_vext.S b/libc/arch-riscv64/string/strcpy_vext.S
index 9c11f7d..ab8da48 100644
--- a/libc/arch-riscv64/string/strcpy_vext.S
+++ b/libc/arch-riscv64/string/strcpy_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define pSrc a1
diff --git a/libc/arch-riscv64/string/strlen_vext.S b/libc/arch-riscv64/string/strlen_vext.S
index 393af58..694f95c 100644
--- a/libc/arch-riscv64/string/strlen_vext.S
+++ b/libc/arch-riscv64/string/strlen_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define iResult a0
 #define pStr a0
diff --git a/libc/arch-riscv64/string/strncat_vext.S b/libc/arch-riscv64/string/strncat_vext.S
index e9da434..9fcd37d 100644
--- a/libc/arch-riscv64/string/strncat_vext.S
+++ b/libc/arch-riscv64/string/strncat_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define pSrc a1
diff --git a/libc/arch-riscv64/string/strncmp_vext.S b/libc/arch-riscv64/string/strncmp_vext.S
index 88f0f3e..ec3ec50 100644
--- a/libc/arch-riscv64/string/strncmp_vext.S
+++ b/libc/arch-riscv64/string/strncmp_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define iResult a0
 
diff --git a/libc/arch-riscv64/string/strncpy_vext.S b/libc/arch-riscv64/string/strncpy_vext.S
index 1aedaf9..eff6293 100644
--- a/libc/arch-riscv64/string/strncpy_vext.S
+++ b/libc/arch-riscv64/string/strncpy_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pDst a0
 #define pSrc a1
diff --git a/libc/arch-riscv64/string/strnlen_vext.S b/libc/arch-riscv64/string/strnlen_vext.S
index f546689..ca07231 100644
--- a/libc/arch-riscv64/string/strnlen_vext.S
+++ b/libc/arch-riscv64/string/strnlen_vext.S
@@ -55,7 +55,7 @@
 
 #if defined(__riscv_v)
 
-#include "sys/asm.h"
+#include <private/bionic_asm.h>
 
 #define pStr a0
 #define pCopyStr a2
diff --git a/libc/arch-riscv64/string/sys/asm.h b/libc/arch-riscv64/string/sys/asm.h
deleted file mode 100644
index cc76dc5..0000000
--- a/libc/arch-riscv64/string/sys/asm.h
+++ /dev/null
@@ -1,76 +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.
- */
-/*
- * Copyright (c) 2023 SiFive, Inc.
- * 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. The name of the company may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- *
- * THIS SOFTWARE IS PROVIDED BY SIFIVE INC ``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 SIFIVE INC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _SYS_ASM_H
-#define _SYS_ASM_H
-
-#undef LEAF
-#define LEAF(symbol)       \
-  .globl symbol;           \
-  .align 2;                \
-  .type symbol, @function; \
-  symbol:                  \
-  .cfi_startproc;
-
-#undef END
-#define END(function) \
-  .cfi_endproc;       \
-  .size function, .- function
-
-#define ENTRY(name) LEAF(name)
-
-#define L(label) .L##label
-
-#endif /* _SYS_ASM_H */
diff --git a/libc/arch-x86_64/bionic/__bionic_clone.S b/libc/arch-x86_64/bionic/__bionic_clone.S
index a4245b8..c293020 100644
--- a/libc/arch-x86_64/bionic/__bionic_clone.S
+++ b/libc/arch-x86_64/bionic/__bionic_clone.S
@@ -48,8 +48,8 @@
 
         # Check result.
         testq   %rax, %rax
-        jz      .L_bc_child
-        jg      .L_bc_parent
+        jz      L(bc_child)
+        jg      L(bc_parent)
 
         # An error occurred, set errno and return -1.
         negl    %eax
@@ -57,7 +57,7 @@
         call    __set_errno_internal
         ret
 
-.L_bc_child:
+L(bc_child):
         # We don't want anyone to unwind past this point.
         .cfi_undefined %rip
         .cfi_undefined %rbp
@@ -70,7 +70,7 @@
         call    __start_thread
         hlt
 
-.L_bc_parent:
+L(bc_parent):
         # We're the parent; nothing to do.
         ret
 END(__bionic_clone)
diff --git a/libc/arch-x86_64/string/avx2-memset-kbl.S b/libc/arch-x86_64/string/avx2-memset-kbl.S
index 09dd07d..ca62a9f 100644
--- a/libc/arch-x86_64/string/avx2-memset-kbl.S
+++ b/libc/arch-x86_64/string/avx2-memset-kbl.S
@@ -63,10 +63,9 @@
 	testb	$2, %dl
 	jnz	L(2_3bytes)
 	testb	$1, %dl
-	jz	L(return)
+	jz	1f
 	movb	%cl, (%rdi)
-L(return):
-	ret
+1:	ret
 
 L(8_15bytes):
 	movq	%rcx, (%rdi)
@@ -90,59 +89,54 @@
 	movdqu	%xmm0, (%rdi)
 	movdqu	%xmm0, -16(%rdi, %rdx)
 	cmpq	$32, %rdx
-	jbe	L(32bytesless)
+	jbe	L(done)
 	movdqu	%xmm0, 16(%rdi)
 	movdqu	%xmm0, -32(%rdi, %rdx)
 	cmpq	$64, %rdx
-	jbe	L(64bytesless)
+	jbe	L(done)
 	movdqu	%xmm0, 32(%rdi)
 	movdqu	%xmm0, 48(%rdi)
 	movdqu	%xmm0, -64(%rdi, %rdx)
 	movdqu	%xmm0, -48(%rdi, %rdx)
 	cmpq	$128, %rdx
-	jbe	L(128bytesless)
-        vpbroadcastb %xmm0, %ymm0
+	jbe	L(done)
+	vpbroadcastb %xmm0, %ymm0
 	vmovdqu	%ymm0, 64(%rdi)
 	vmovdqu	%ymm0, 96(%rdi)
 	vmovdqu	%ymm0, -128(%rdi, %rdx)
 	vmovdqu	%ymm0, -96(%rdi, %rdx)
 	cmpq	$256, %rdx
-        ja      L(256bytesmore)
-L(32bytesless):
-L(64bytesless):
-L(128bytesless):
-	ret
+	jbe	L(done)
 
 	ALIGN (4)
-L(256bytesmore):
 	leaq	128(%rdi), %rcx
 	andq	$-128, %rcx
 	movq	%rdx, %r8
 	addq	%rdi, %rdx
 	andq	$-128, %rdx
 	cmpq	%rcx, %rdx
-	je	L(return)
+	je	L(done)
 
 #ifdef SHARED_CACHE_SIZE
 	cmp	$SHARED_CACHE_SIZE, %r8
 #else
 	cmp	__x86_64_shared_cache_size(%rip), %r8
 #endif
-	ja	L(256bytesmore_nt)
+	ja	L(non_temporal_loop)
 
 	ALIGN (4)
-L(256bytesmore_normal):
+L(normal_loop):
 	vmovdqa	%ymm0, (%rcx)
 	vmovdqa	%ymm0, 32(%rcx)
 	vmovdqa	%ymm0, 64(%rcx)
 	vmovdqa	%ymm0, 96(%rcx)
 	addq	$128, %rcx
 	cmpq	%rcx, %rdx
-	jne	L(256bytesmore_normal)
-	ret
+	jne	L(normal_loop)
+	jmp	L(done)
 
 	ALIGN (4)
-L(256bytesmore_nt):
+L(non_temporal_loop):
 	movntdq	 %xmm0, (%rcx)
 	movntdq	 %xmm0, 16(%rcx)
 	movntdq	 %xmm0, 32(%rcx)
@@ -153,8 +147,14 @@
 	movntdq	 %xmm0, 112(%rcx)
 	leaq	128(%rcx), %rcx
 	cmpq	%rcx, %rdx
-	jne	L(256bytesmore_nt)
+	jne	L(non_temporal_loop)
+	# We used non-temporal stores, so we need a fence here.
 	sfence
+
+L(done):
+	# We used the ymm registers, and that can break SSE2 performance
+	# unless you do this.
+	vzeroupper
 	ret
 
 END(memset_avx2)
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 420560f..2bff616 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -207,10 +207,12 @@
   // Decode the conversion specifier.
   int is_signed = (conversion == 'd' || conversion == 'i' || conversion == 'o');
   int base = 10;
-  if (conversion == 'x' || conversion == 'X') {
+  if (tolower(conversion) == 'x') {
     base = 16;
   } else if (conversion == 'o') {
     base = 8;
+  } else if (tolower(conversion) == 'b') {
+    base = 2;
   }
   bool caps = (conversion == 'X');
 
@@ -360,7 +362,8 @@
       format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
     } else if (c == 'm') {
       strerror_r(errno, buffer, sizeof(buffer));
-    } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
+    } else if (tolower(c) == 'b' || c == 'd' || c == 'i' || c == 'o' || c == 'u' ||
+               tolower(c) == 'x') {
       /* integers - first read value from stack */
       uint64_t value;
       int is_signed = (c == 'd' || c == 'i' || c == 'o');
@@ -391,10 +394,10 @@
         value = static_cast<uint64_t>((static_cast<int64_t>(value << shift)) >> shift);
       }
 
-      if (alternate && value != 0 && (c == 'x' || c == 'o')) {
-        if (c == 'x') {
+      if (alternate && value != 0 && (tolower(c) == 'x' || c == 'o' || tolower(c) == 'b')) {
+        if (tolower(c) == 'x' || tolower(c) == 'b') {
           buffer[0] = '0';
-          buffer[1] = 'x';
+          buffer[1] = c;
           format_integer(buffer + 2, sizeof(buffer) - 2, value, c);
         } else {
           buffer[0] = '0';
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 95f46e9..1b539f2 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -150,7 +150,7 @@
   // stack.)
   ThreadMapping mapping = __allocate_thread_mapping(0, PTHREAD_GUARD_SIZE);
   if (mapping.mmap_base == nullptr) {
-    async_safe_fatal("failed to mmap main thread static TLS: %s", strerror(errno));
+    async_safe_fatal("failed to mmap main thread static TLS: %m");
   }
 
   const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 8c9127e..849d04b 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -126,15 +126,14 @@
 static void HandleTracedPerfSignal() {
   ScopedFd sock_fd{ socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0 /*protocol*/) };
   if (sock_fd.get() == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create socket: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create socket: %m");
     return;
   }
 
   sockaddr_un saddr{ AF_UNIX, "/dev/socket/traced_perf" };
   size_t addrlen = sizeof(sockaddr_un);
   if (connect(sock_fd.get(), reinterpret_cast<const struct sockaddr*>(&saddr), addrlen) == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to traced_perf socket: %s",
-                          strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to traced_perf socket: %m");
     return;
   }
 
@@ -153,13 +152,11 @@
   }
 
   if (maps_fd.get() == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %s",
-                          strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %m");
     return;
   }
   if (mem_fd.get() == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %s",
-                          strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %m");
     return;
   }
 
@@ -183,7 +180,7 @@
   memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
 
   if (sendmsg(sock_fd.get(), &msg_hdr, 0) == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to sendmsg: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to sendmsg: %m");
   }
 }
 
diff --git a/libc/bionic/android_unsafe_frame_pointer_chase.cpp b/libc/bionic/android_unsafe_frame_pointer_chase.cpp
index 1a59718..58b7cd8 100644
--- a/libc/bionic/android_unsafe_frame_pointer_chase.cpp
+++ b/libc/bionic/android_unsafe_frame_pointer_chase.cpp
@@ -74,7 +74,9 @@
   while (1) {
 #if defined(__riscv)
     // Frame addresses seem to have been implemented incorrectly for RISC-V.
-    // See https://reviews.llvm.org/D87579.
+    // See https://reviews.llvm.org/D87579. We did at least manage to get this
+    // documented in the RISC-V psABI though:
+    // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#frame-pointer-convention
     auto* frame = reinterpret_cast<frame_record*>(begin - 16);
 #else
     auto* frame = reinterpret_cast<frame_record*>(begin);
diff --git a/libc/bionic/atexit.cpp b/libc/bionic/atexit.cpp
index dae15e0..29f9c7b 100644
--- a/libc/bionic/atexit.cpp
+++ b/libc/bionic/atexit.cpp
@@ -158,7 +158,7 @@
 
   const int prot = PROT_READ | (writable ? PROT_WRITE : 0);
   if (mprotect(reinterpret_cast<char*>(array_) + start_byte, byte_len, prot) != 0) {
-    async_safe_fatal("mprotect failed on atexit array: %s", strerror(errno));
+    async_safe_fatal("mprotect failed on atexit array: %m");
   }
 }
 
@@ -198,8 +198,8 @@
   }
   if (new_pages == MAP_FAILED) {
     async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                          "__cxa_atexit: mmap/mremap failed to allocate %zu bytes: %s",
-                          new_capacity_bytes, strerror(errno));
+                          "__cxa_atexit: mmap/mremap failed to allocate %zu bytes: %m",
+                          new_capacity_bytes);
   } else {
     result = true;
     prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, new_pages, new_capacity_bytes, "atexit handlers");
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index 53f944f..80e8b08 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -192,7 +192,7 @@
   void* const map_ptr =
       mmap(nullptr, page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (map_ptr == MAP_FAILED) {
-    async_safe_fatal("mmap failed: %s", strerror(errno));
+    async_safe_fatal("mmap failed: %m");
   }
 
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, page_size(), "bionic_alloc_small_objects");
@@ -273,7 +273,7 @@
                        -1, 0);
 
   if (map_ptr == MAP_FAILED) {
-    async_safe_fatal("mmap failed: %s", strerror(errno));
+    async_safe_fatal("mmap failed: %m");
   }
 
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, allocated_size, "bionic_alloc_lob");
diff --git a/libc/bionic/bionic_call_ifunc_resolver.cpp b/libc/bionic/bionic_call_ifunc_resolver.cpp
index 437de78..3cfb8b5 100644
--- a/libc/bionic/bionic_call_ifunc_resolver.cpp
+++ b/libc/bionic/bionic_call_ifunc_resolver.cpp
@@ -57,6 +57,13 @@
     hwcap = getauxval(AT_HWCAP);
   }
   return reinterpret_cast<ifunc_resolver_t>(resolver_addr)(hwcap);
+#elif defined(__riscv)
+  // The pointer argument is currently unused, but reserved for future
+  // expansion. If we pass nullptr from the beginning, it'll be easier
+  // to recognize if/when we pass actual data (and matches glibc).
+  typedef ElfW(Addr) (*ifunc_resolver_t)(uint64_t, void*);
+  static uint64_t hwcap = getauxval(AT_HWCAP);
+  return reinterpret_cast<ifunc_resolver_t>(resolver_addr)(hwcap, nullptr);
 #else
   typedef ElfW(Addr) (*ifunc_resolver_t)(void);
   return reinterpret_cast<ifunc_resolver_t>(resolver_addr)();
diff --git a/libc/bionic/c32rtomb.cpp b/libc/bionic/c32rtomb.cpp
index 4fa76ff..a7cd207 100644
--- a/libc/bionic/c32rtomb.cpp
+++ b/libc/bionic/c32rtomb.cpp
@@ -78,7 +78,7 @@
     length = 4;
   } else {
     errno = EILSEQ;
-    return __MB_ERR_ILLEGAL_SEQUENCE;
+    return BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE;
   }
 
   // Output the octets representing the character in chunks
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 3eb8c19..84d2c94 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -87,7 +87,7 @@
     void* allocation =
         mmap(nullptr, aligned_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     if (allocation == MAP_FAILED) {
-      async_safe_fatal("fdsan: mmap failed: %s", strerror(errno));
+      async_safe_fatal("fdsan: mmap failed: %m");
     }
 
     FdTableOverflow* new_overflow = reinterpret_cast<FdTableOverflow*>(allocation);
diff --git a/libc/bionic/iconv.cpp b/libc/bionic/iconv.cpp
index 79a429c..5bff50a 100644
--- a/libc/bionic/iconv.cpp
+++ b/libc/bionic/iconv.cpp
@@ -160,9 +160,9 @@
 
       case UTF_8:
         src_bytes_used = mbrtoc32(&wc, *src_buf, *src_bytes_left, &ps);
-        if (src_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
+        if (src_bytes_used == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
           break;  // EILSEQ already set.
-        } else if (src_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
+        } else if (src_bytes_used == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
           errno = EINVAL;
           return false;
         }
@@ -235,9 +235,9 @@
 
       case UTF_8:
         dst_bytes_used = c32rtomb(buf, wc, &ps);
-        if (dst_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
+        if (dst_bytes_used == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
           break;  // EILSEQ already set.
-        } else if (dst_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
+        } else if (dst_bytes_used == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
           errno = EINVAL;
           return false;
         }
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
index 0c80f4e..cb36cc6 100644
--- a/libc/bionic/ifaddrs.cpp
+++ b/libc/bionic/ifaddrs.cpp
@@ -281,8 +281,7 @@
   ScopedFd s(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
   if (s.get() == -1) {
     async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                          "socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC) failed in ifaddrs: %s",
-                          strerror(errno));
+                          "socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC) failed in ifaddrs: %m");
     return;
   }
 
@@ -294,8 +293,8 @@
       addr->ifa.ifa_flags = ifr.ifr_flags;
     } else {
       async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                            "ioctl(SIOCGIFFLAGS) for \"%s\" failed in ifaddrs: %s",
-                            addr->ifa.ifa_name, strerror(errno));
+                            "ioctl(SIOCGIFFLAGS) for \"%s\" failed in ifaddrs: %m",
+                            addr->ifa.ifa_name);
     }
   }
 }
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index d922641..7ef79b6 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -340,11 +340,11 @@
 #if !defined(__LP64__)
   int old_value = personality(0xffffffff);
   if (old_value == -1) {
-    async_safe_fatal("error getting old personality value: %s", strerror(errno));
+    async_safe_fatal("error getting old personality value: %m");
   }
 
   if (personality((static_cast<unsigned int>(old_value) & ~PER_MASK) | PER_LINUX32) == -1) {
-    async_safe_fatal("error setting PER_LINUX32 personality: %s", strerror(errno));
+    async_safe_fatal("error setting PER_LINUX32 personality: %m");
   }
 #endif
 }
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 6b39d6d..126f002 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -38,6 +38,10 @@
   init_func_t** preinit_array;
   init_func_t** init_array;
   fini_func_t** fini_array;
+  // Below fields are only available in static executables.
+  size_t preinit_array_count;
+  size_t init_array_count;
+  size_t fini_array_count;
 } structors_array_t;
 
 __BEGIN_DECLS
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 3b0ab82..1591785 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -69,10 +69,21 @@
 extern "C" int __cxa_atexit(void (*)(void *), void *, void *);
 extern "C" const char* __gnu_basename(const char* path);
 
-static void call_array(init_func_t** list, int argc, char* argv[], char* envp[]) {
-  // First element is -1, list is null-terminated
-  while (*++list) {
-    (*list)(argc, argv, envp);
+static void call_array(init_func_t** list, size_t count, int argc, char* argv[], char* envp[]) {
+  while (count-- > 0) {
+    init_func_t* function = *list++;
+    (*function)(argc, argv, envp);
+  }
+}
+
+static void call_fini_array(void* arg) {
+  structors_array_t* structors = reinterpret_cast<structors_array_t*>(arg);
+  fini_func_t** array = structors->fini_array;
+  size_t count = structors->fini_array_count;
+  // Now call each destructor in reverse order.
+  while (count-- > 0) {
+    fini_func_t* function = array[count];
+    (*function)();
   }
 }
 
@@ -356,9 +367,8 @@
       if (memtag_stack) {
         void* pg_start =
             reinterpret_cast<void*>(page_start(reinterpret_cast<uintptr_t>(stack_top)));
-        if (mprotect(pg_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
-          async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %s\n",
-                           strerror(errno));
+        if (mprotect(pg_start, page_size(), PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
+          async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %m");
         }
       }
 
@@ -414,14 +424,15 @@
   // Several Linux ABIs don't pass the onexit pointer, and the ones that
   // do never use it.  Therefore, we ignore it.
 
-  call_array(structors->preinit_array, args.argc, args.argv, args.envp);
-  call_array(structors->init_array, args.argc, args.argv, args.envp);
+  call_array(structors->preinit_array, structors->preinit_array_count, args.argc, args.argv,
+             args.envp);
+  call_array(structors->init_array, structors->init_array_count, args.argc, args.argv, args.envp);
 
   // The executable may have its own destructors listed in its .fini_array
   // so we need to ensure that these are called when the program exits
   // normally.
-  if (structors->fini_array != nullptr) {
-    __cxa_atexit(__libc_fini,structors->fini_array,nullptr);
+  if (structors->fini_array_count > 0) {
+    __cxa_atexit(call_fini_array, const_cast<structors_array_t*>(structors), nullptr);
   }
 
   __libc_init_mte_late();
diff --git a/libc/bionic/malloc_limit.cpp b/libc/bionic/malloc_limit.cpp
index 1405a39..deb63f4 100644
--- a/libc/bionic/malloc_limit.cpp
+++ b/libc/bionic/malloc_limit.cpp
@@ -278,7 +278,7 @@
   // being called, allow a short period for the signal handler to complete
   // before failing.
   bool enabled = false;
-  size_t num_tries = 20;
+  size_t num_tries = 200;
   while (true) {
     if (!atomic_exchange(&gGlobalsMutating, true)) {
       __libc_globals.mutate([](libc_globals* globals) {
@@ -328,9 +328,16 @@
     current_allocated = Malloc(mallinfo)().uordblks;
   }
 #endif
+  // This has to be set before the enable occurs since "gAllocated" is used
+  // to compute the limit. If the enable fails, "gAllocated" is never used.
   atomic_store(&gAllocated, current_allocated);
 
-  return EnableLimitDispatchTable();
+  if (!EnableLimitDispatchTable()) {
+    // Failed to enable, reset so a future enable will pass.
+    atomic_store(&limit_enabled, false);
+    return false;
+  }
+  return true;
 }
 
 static size_t LimitUsableSize(const void* mem) {
diff --git a/libc/bionic/mbrtoc16.cpp b/libc/bionic/mbrtoc16.cpp
index 154b8a3..e87991a 100644
--- a/libc/bionic/mbrtoc16.cpp
+++ b/libc/bionic/mbrtoc16.cpp
@@ -47,15 +47,36 @@
   mbstate_set_byte(state, 3, nconv & 0xff);
 
   *pc16 = ((c32 & 0xffc00) >> 10) | 0xd800;
-  // Defined by POSIX as return value for first surrogate character.
-  return static_cast<size_t>(-3);
+  // https://issuetracker.google.com/289419882
+  //
+  // We misread the spec when implementing this. The first call should return
+  // the length of the decoded character, and the second call should return -3
+  // to indicate that the output is a continuation of the character decoded by
+  // the first call.
+  //
+  // C23 7.30.1.3.4:
+  //
+  //     between 1 and n inclusive if the next n or fewer bytes complete a valid
+  //     multibyte character (which is the value stored); the value returned is
+  //     the number of bytes that complete the multibyte character.
+  //
+  //     (size_t)(-3) if the next character resulting from a previous call has
+  //     been stored (no bytes from the input have been consumed by this call).
+  //
+  // The first call returns the number of bytes consumed, and the second call
+  // returns -3.
+  //
+  // All UTF-8 sequences that encode a surrogate pair are 4 bytes, but we may
+  // not have seen the full sequence yet.
+  return nconv;
 }
 
 static size_t finish_surrogate(char16_t* pc16, mbstate_t* state) {
   char16_t trail = mbstate_get_byte(state, 1) << 8 |
                    mbstate_get_byte(state, 0);
   *pc16 = trail;
-  return mbstate_reset_and_return(mbstate_get_byte(state, 3), state);
+  mbstate_reset(state);
+  return static_cast<size_t>(-3);
 }
 
 size_t mbrtoc16(char16_t* pc16, const char* s, size_t n, mbstate_t* ps) {
diff --git a/libc/bionic/mbrtoc32.cpp b/libc/bionic/mbrtoc32.cpp
index d37ca66..74deb40 100644
--- a/libc/bionic/mbrtoc32.cpp
+++ b/libc/bionic/mbrtoc32.cpp
@@ -51,7 +51,21 @@
   }
 
   if (n == 0) {
-    return 0;
+    // C23 7.30.1 (for each `mbrtoc*` function) says:
+    //
+    // Returns:
+    //
+    //     0 if the next n or fewer bytes complete the multibyte character that
+    //     corresponds to the null wide character (which is the value stored).
+    //
+    //     (size_t)(-2) if the next n bytes contribute to an incomplete (but
+    //     potentially valid) multibyte character, and all n bytes have been
+    //     processed (no value is stored).
+    //
+    // Bionic historically interpreted the behavior when n is 0 to be the next 0
+    // bytes decoding to the null. That's a pretty bad interpretation, and both
+    // glibc and musl return -2 for that case.
+    return BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE;
   }
 
   uint8_t ch;
@@ -109,7 +123,7 @@
     mbstate_set_byte(state, bytes_so_far + i, *s++);
   }
   if (i < bytes_wanted) {
-    return __MB_ERR_INCOMPLETE_SEQUENCE;
+    return BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE;
   }
 
   // Decode the octet sequence representing the character in chunks
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index 3290315..7d80b4c 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -50,14 +50,8 @@
 
 int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) {
   // The underlying `__ppoll` system call only takes `sigset64_t`.
-  SigSetConverter set;
-  sigset64_t* ss_ptr = nullptr;
-  if (ss != nullptr) {
-    set = {};
-    set.sigset = *ss;
-    ss_ptr = &set.sigset64;
-  }
-  return ppoll64(fds, fd_count, ts, ss_ptr);
+  SigSetConverter set{ss};
+  return ppoll64(fds, fd_count, ts, set.ptr);
 }
 
 int ppoll64(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset64_t* ss) {
@@ -99,14 +93,8 @@
 int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
             const timespec* ts, const sigset_t* ss) {
   // The underlying `__pselect6` system call only takes `sigset64_t`.
-  SigSetConverter set;
-  sigset64_t* ss_ptr = nullptr;
-  if (ss != nullptr) {
-    set = {};
-    set.sigset = *ss;
-    ss_ptr = &set.sigset64;
-  }
-  return pselect64(fd_count, read_fds, write_fds, error_fds, ts, ss_ptr);
+  SigSetConverter set{ss};
+  return pselect64(fd_count, read_fds, write_fds, error_fds, ts, set.ptr);
 }
 
 int pselect64(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index cdae72c..de4cc9e 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -158,12 +158,12 @@
 static uintptr_t __get_main_stack_startstack() {
   FILE* fp = fopen("/proc/self/stat", "re");
   if (fp == nullptr) {
-    async_safe_fatal("couldn't open /proc/self/stat: %s", strerror(errno));
+    async_safe_fatal("couldn't open /proc/self/stat: %m");
   }
 
   char line[BUFSIZ];
   if (fgets(line, sizeof(line), fp) == nullptr) {
-    async_safe_fatal("couldn't read /proc/self/stat: %s", strerror(errno));
+    async_safe_fatal("couldn't read /proc/self/stat: %m");
   }
 
   fclose(fp);
@@ -205,7 +205,7 @@
   // Hunt for the region that contains that address.
   FILE* fp = fopen("/proc/self/maps", "re");
   if (fp == nullptr) {
-    async_safe_fatal("couldn't open /proc/self/maps: %s", strerror(errno));
+    async_safe_fatal("couldn't open /proc/self/maps: %m");
   }
   char line[BUFSIZ];
   while (fgets(line, sizeof(line), fp) != nullptr) {
@@ -219,7 +219,7 @@
       }
     }
   }
-  async_safe_fatal("Stack not found in /proc/self/maps");
+  async_safe_fatal("stack not found in /proc/self/maps");
 }
 
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index b46c6cf..194db18 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -78,8 +78,7 @@
                           MAP_PRIVATE | MAP_ANONYMOUS,
                           -1, 0);
   if (allocation == MAP_FAILED) {
-    // Avoid strerror because it might need bionic_tls.
-    async_safe_fatal("failed to allocate bionic_tls: error %d", errno);
+    async_safe_fatal("failed to allocate bionic_tls: %m");
   }
   return static_cast<bionic_tls*>(allocation);
 }
@@ -137,7 +136,9 @@
   // Make the stack read-write, and store its address in the register we're using as the shadow
   // stack pointer. This is deliberately the only place where the address is stored.
   char* scs = scs_aligned_guard_region + scs_offset;
-  mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
+  if (mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE) == -1) {
+    async_safe_fatal("shadow stack read-write mprotect(%p, %d) failed: %m", scs, SCS_SIZE);
+  }
 #if defined(__aarch64__)
   __asm__ __volatile__("mov x18, %0" ::"r"(scs));
 #elif defined(__riscv)
@@ -171,12 +172,11 @@
     if (need_set) {
       if (policy == -1) {
         async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                              "pthread_create sched_getscheduler failed: %s", strerror(errno));
+                              "pthread_create sched_getscheduler failed: %m");
         return errno;
       }
       if (sched_getparam(0, &param) == -1) {
-        async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                              "pthread_create sched_getparam failed: %s", strerror(errno));
+        async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create sched_getparam failed: %m");
         return errno;
       }
     }
@@ -192,8 +192,8 @@
   if (need_set) {
     if (sched_setscheduler(thread->tid, policy, &param) == -1) {
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "pthread_create sched_setscheduler(%d, {%d}) call failed: %s", policy,
-                            param.sched_priority, strerror(errno));
+                            "pthread_create sched_setscheduler(%d, {%d}) call failed: %m", policy,
+                            param.sched_priority);
 #if defined(__LP64__)
       // For backwards compatibility reasons, we only report failures on 64-bit devices.
       return errno;
@@ -228,10 +228,9 @@
   const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
   char* const space = static_cast<char*>(mmap(nullptr, mmap_size, PROT_NONE, flags, -1, 0));
   if (space == MAP_FAILED) {
-    async_safe_format_log(ANDROID_LOG_WARN,
-                          "libc",
-                          "pthread_create failed: couldn't allocate %zu-bytes mapped space: %s",
-                          mmap_size, strerror(errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                          "pthread_create failed: couldn't allocate %zu-bytes mapped space: %m",
+                          mmap_size);
     return {};
   }
   const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE;
@@ -246,8 +245,8 @@
   if (mprotect(space + stack_guard_size, writable_size, prot) != 0) {
     async_safe_format_log(
         ANDROID_LOG_WARN, "libc",
-        "pthread_create failed: couldn't mprotect %s %zu-byte thread mapping region: %s", prot_str,
-        writable_size, strerror(errno));
+        "pthread_create failed: couldn't mprotect %s %zu-byte thread mapping region: %m", prot_str,
+        writable_size);
     munmap(space, mmap_size);
     return {};
   }
@@ -458,8 +457,7 @@
     if (thread->mmap_size != 0) {
       munmap(thread->mmap_base, thread->mmap_size);
     }
-    async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s",
-                          strerror(clone_errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %m");
     return clone_errno;
   }
 
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 7efbf6d..3b9e6a4 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -38,6 +38,8 @@
 #define __hwasan_thread_exit()
 #endif
 
+#include "platform/bionic/page.h"
+
 #include "private/bionic_elf_tls.h"
 #include "private/bionic_lock.h"
 #include "private/bionic_tls.h"
@@ -236,7 +238,7 @@
 // On LP64, we could use more but there's no obvious advantage to doing
 // so, and the various media processes use RLIMIT_AS as a way to limit
 // the amount of allocation they'll do.
-#define PTHREAD_GUARD_SIZE PAGE_SIZE
+#define PTHREAD_GUARD_SIZE max_page_size()
 
 // SIGSTKSZ (8KiB) is not big enough.
 // An snprintf to a stack buffer of size PATH_MAX consumes ~7KiB of stack.
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index b581b5a..2cf9940 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -76,13 +76,23 @@
   return SigAddSet(set, sig);
 }
 
-// This isn't in our header files, but is exposed on all architectures.
+union BsdSigSet {
+  int mask;
+  sigset64_t set;
+};
+
+// This isn't in our header files, but is exposed on all architectures except riscv64.
 extern "C" int sigblock(int mask) {
-  SigSetConverter in, out;
-  sigemptyset(&in.sigset);
-  in.bsd = mask;
-  if (sigprocmask(SIG_BLOCK, &in.sigset, &out.sigset) == -1) return -1;
-  return out.bsd;
+  BsdSigSet in{.mask = mask}, out;
+  if (sigprocmask64(SIG_BLOCK, &in.set, &out.set) == -1) return -1;
+  return out.mask;
+}
+
+// This isn't in our header files, but is exposed on all architectures except riscv64.
+extern "C" int sigsetmask(int mask) {
+  BsdSigSet in{.mask = mask}, out;
+  if (sigprocmask64(SIG_SETMASK, &in.set, &out.set) == -1) return -1;
+  return out.mask;
 }
 
 template <typename SigSetT>
@@ -198,10 +208,9 @@
 }
 
 int sigpending(sigset_t* bionic_set) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  if (__rt_sigpending(&set.sigset64, sizeof(set.sigset64)) == -1) return -1;
-  *bionic_set = set.sigset;
+  SigSetConverter set{bionic_set};
+  if (__rt_sigpending(set.ptr, sizeof(sigset64_t)) == -1) return -1;
+  set.copy_out();
   return 0;
 }
 
@@ -245,19 +254,9 @@
   return sigismember64(&old_mask, sig) ? SIG_HOLD : old_sa.sa_handler;
 }
 
-// This isn't in our header files, but is exposed on all architectures.
-extern "C" int sigsetmask(int mask) {
-  SigSetConverter in, out;
-  sigemptyset(&in.sigset);
-  in.bsd = mask;
-  if (sigprocmask(SIG_SETMASK, &in.sigset, &out.sigset) == -1) return -1;
-  return out.bsd;
-}
-
 int sigsuspend(const sigset_t* bionic_set) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  return sigsuspend64(&set.sigset64);
+  SigSetConverter set{bionic_set};
+  return sigsuspend64(set.ptr);
 }
 
 int sigsuspend64(const sigset64_t* set) {
@@ -271,9 +270,8 @@
 }
 
 int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  return sigtimedwait64(&set.sigset64, info, timeout);
+  SigSetConverter set{bionic_set};
+  return sigtimedwait64(set.ptr, info, timeout);
 }
 
 int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) {
@@ -287,9 +285,8 @@
 }
 
 int sigwait(const sigset_t* bionic_set, int* sig) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  return sigwait64(&set.sigset64, sig);
+  SigSetConverter set{bionic_set};
+  return sigwait64(set.ptr, sig);
 }
 
 int sigwait64(const sigset64_t* set, int* sig) {
diff --git a/libc/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
index 8781c9b..6d436a6 100644
--- a/libc/bionic/sigprocmask.cpp
+++ b/libc/bionic/sigprocmask.cpp
@@ -44,24 +44,13 @@
 int sigprocmask(int how,
                 const sigset_t* bionic_new_set,
                 sigset_t* bionic_old_set) __attribute__((__noinline__)) {
-  SigSetConverter new_set;
-  sigset64_t* new_set_ptr = nullptr;
-  if (bionic_new_set != nullptr) {
-    sigemptyset64(&new_set.sigset64);
-    new_set.sigset = *bionic_new_set;
-    new_set_ptr = &new_set.sigset64;
+  SigSetConverter new_set{bionic_new_set};
+  SigSetConverter old_set{bionic_old_set};
+  int rc = sigprocmask64(how, new_set.ptr, old_set.ptr);
+  if (rc == 0 && bionic_old_set != nullptr) {
+    old_set.copy_out();
   }
-
-  SigSetConverter old_set;
-  if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) {
-    return -1;
-  }
-
-  if (bionic_old_set != nullptr) {
-    *bionic_old_set = old_set.sigset;
-  }
-
-  return 0;
+  return rc;
 }
 
 int sigprocmask64(int how,
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 5d76f77..38f99ad 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -41,7 +41,6 @@
 #include <android/fdsan.h>
 
 #include "private/ScopedSignalBlocker.h"
-#include "private/SigSetConverter.h"
 
 static int set_cloexec(int i) {
   int v = fcntl(i, F_GETFD);
@@ -131,8 +130,10 @@
   pid_t pgroup;
   sched_param schedparam;
   int schedpolicy;
-  SigSetConverter sigmask;
-  SigSetConverter sigdefault;
+  union {
+    sigset_t sigset;
+    sigset64_t sigset64;
+  } sigmask, sigdefault;
 };
 
 static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) {
diff --git a/libc/bionic/sys_epoll.cpp b/libc/bionic/sys_epoll.cpp
index 22d0a98..be97818 100644
--- a/libc/bionic/sys_epoll.cpp
+++ b/libc/bionic/sys_epoll.cpp
@@ -34,6 +34,8 @@
 
 extern "C" int __epoll_create1(int flags);
 extern "C" int __epoll_pwait(int, epoll_event*, int, int, const sigset64_t*, size_t);
+extern "C" int __epoll_pwait2(int, epoll_event*, int, const __kernel_timespec*, const sigset64_t*,
+                              size_t);
 
 int epoll_create(int size) {
   if (size <= 0) {
@@ -48,20 +50,39 @@
 }
 
 int epoll_pwait(int fd, epoll_event* events, int max_events, int timeout, const sigset_t* ss) {
-  SigSetConverter set;
-  sigset64_t* ss_ptr = nullptr;
-  if (ss != nullptr) {
-    set = {};
-    set.sigset = *ss;
-    ss_ptr = &set.sigset64;
-  }
-  return epoll_pwait64(fd, events, max_events, timeout, ss_ptr);
+  SigSetConverter set{ss};
+  return epoll_pwait64(fd, events, max_events, timeout, set.ptr);
 }
 
 int epoll_pwait64(int fd, epoll_event* events, int max_events, int timeout, const sigset64_t* ss) {
   return __epoll_pwait(fd, events, max_events, timeout, ss, sizeof(*ss));
 }
 
+int epoll_pwait2(int fd, epoll_event* events, int max_events, const timespec* timeout,
+                 const sigset_t* ss) {
+  SigSetConverter set{ss};
+  return epoll_pwait2_64(fd, events, max_events, timeout, set.ptr);
+}
+
+int epoll_pwait2_64(int fd, epoll_event* events, int max_events, const timespec* timeout,
+                    const sigset64_t* ss) {
+  // epoll_pwait2() is our first syscall that assumes a 64-bit time_t even for
+  // 32-bit processes, so for ILP32 we need to convert.
+  // TODO: factor this out into a TimeSpecConverter as/when we get more syscalls like this.
+#if __LP64__
+  const __kernel_timespec* kts_ptr = reinterpret_cast<const __kernel_timespec*>(timeout);
+#else
+  __kernel_timespec kts;
+  const __kernel_timespec* kts_ptr = nullptr;
+  if (timeout) {
+    kts.tv_sec = timeout->tv_sec;
+    kts.tv_nsec = timeout->tv_nsec;
+    kts_ptr = &kts;
+  }
+#endif
+  return __epoll_pwait2(fd, events, max_events, kts_ptr, ss, sizeof(*ss));
+}
+
 int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) {
   return epoll_pwait64(fd, events, max_events, timeout, nullptr);
 }
diff --git a/libc/bionic/sys_signalfd.cpp b/libc/bionic/sys_signalfd.cpp
index 53d1f25..1e62cf4 100644
--- a/libc/bionic/sys_signalfd.cpp
+++ b/libc/bionic/sys_signalfd.cpp
@@ -32,12 +32,12 @@
 
 extern "C" int __signalfd4(int, const sigset64_t*, size_t, int);
 
-int signalfd(int fd, const sigset_t* mask, int flags) {
-  SigSetConverter set = {};
-  set.sigset = *mask;
-  return signalfd64(fd, &set.sigset64, flags);
-}
-
 int signalfd64(int fd, const sigset64_t* mask, int flags) {
   return __signalfd4(fd, mask, sizeof(*mask), flags);
 }
+
+int signalfd(int fd, const sigset_t* mask, int flags) {
+  // The underlying `__signalfd4` system call only takes `sigset64_t`.
+  SigSetConverter set{mask};
+  return signalfd64(fd, set.ptr, flags);
+}
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 3906e2e..edbdef1 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -41,6 +41,107 @@
 #include "platform/bionic/page.h"
 #include "private/bionic_tls.h"
 
+struct sysconf_cache {
+  long size, assoc, linesize;
+
+  static sysconf_cache from_size_and_geometry(int size_id, int geometry_id) {
+    sysconf_cache result;
+    result.size = getauxval(size_id);
+    unsigned long geometry = getauxval(geometry_id);
+    result.assoc = geometry >> 16;
+    result.linesize = geometry & 0xffff;
+    return result;
+  }
+};
+
+struct sysconf_caches {
+  sysconf_cache l1_i, l1_d, l2, l3, l4;
+};
+
+#if defined(__riscv)
+
+static sysconf_caches* __sysconf_caches() {
+  static sysconf_caches cached = []{
+    sysconf_caches info = {};
+    // riscv64 kernels conveniently hand us all this information.
+    info.l1_i = sysconf_cache::from_size_and_geometry(AT_L1I_CACHESIZE, AT_L1I_CACHEGEOMETRY);
+    info.l1_d = sysconf_cache::from_size_and_geometry(AT_L1D_CACHESIZE, AT_L1D_CACHEGEOMETRY);
+    info.l2 = sysconf_cache::from_size_and_geometry(AT_L2_CACHESIZE, AT_L2_CACHEGEOMETRY);
+    info.l3 = sysconf_cache::from_size_and_geometry(AT_L3_CACHESIZE, AT_L3_CACHEGEOMETRY);
+    return info;
+  }();
+  return &cached;
+}
+
+#elif defined(__aarch64__)
+
+static sysconf_caches* __sysconf_caches() {
+  static sysconf_caches cached = []{
+    sysconf_caches info = {};
+    // arm64 is especially limited. We can infer the L1 line sizes, but that's it.
+    uint64_t ctr_el0;
+    __asm__ __volatile__("mrs %0, ctr_el0" : "=r"(ctr_el0));
+    info.l1_i.linesize = 4 << (ctr_el0 & 0xf);
+    info.l1_d.linesize = 4 << ((ctr_el0 >> 16) & 0xf);
+    return info;
+  }();
+  return &cached;
+}
+
+#else
+
+long __sysconf_fread_long(const char* path) {
+  long result = 0;
+  FILE* fp = fopen(path, "re");
+  if (fp != nullptr) {
+    fscanf(fp, "%ld", &result);
+    fclose(fp);
+  }
+  return result;
+}
+
+static sysconf_caches* __sysconf_caches() {
+  static sysconf_caches cached = []{
+    sysconf_caches info = {};
+    char path[64];
+    for (int i = 0; i < 4; i++) {
+      sysconf_cache c;
+
+      snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/size", i);
+      c.size = __sysconf_fread_long(path) * 1024;
+      if (c.size == 0) break;
+
+      snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/ways_of_associativity", i);
+      c.assoc = __sysconf_fread_long(path);
+
+      snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/coherency_line_size", i);
+      c.linesize = __sysconf_fread_long(path);
+
+      snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/level", i);
+      int level = __sysconf_fread_long(path);
+      if (level == 1) {
+        snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/type", i);
+        FILE* fp = fopen(path, "re");
+        char type = fgetc(fp);
+        fclose(fp);
+        if (type == 'D') {
+          info.l1_d = c;
+        } else if (type == 'I') {
+          info.l1_i = c;
+        }
+      } else if (level == 2) {
+        info.l2 = c;
+      } else if (level == 3) {
+        info.l3 = c;
+      }
+    }
+    return info;
+  }();
+  return &cached;
+}
+
+#endif
+
 static long __sysconf_rlimit(int resource) {
   rlimit rl;
   getrlimit(resource, &rl);
@@ -218,23 +319,21 @@
     case _SC_XOPEN_STREAMS:     return -1;            // Obsolescent in POSIX.1-2008.
     case _SC_XOPEN_UUCP:        return -1;
 
-    // We do not have actual implementations for cache queries.
-    // It's valid to return 0 as the result is unknown.
-    case _SC_LEVEL1_ICACHE_SIZE:      return 0;
-    case _SC_LEVEL1_ICACHE_ASSOC:     return 0;
-    case _SC_LEVEL1_ICACHE_LINESIZE:  return 0;
-    case _SC_LEVEL1_DCACHE_SIZE:      return 0;
-    case _SC_LEVEL1_DCACHE_ASSOC:     return 0;
-    case _SC_LEVEL1_DCACHE_LINESIZE:  return 0;
-    case _SC_LEVEL2_CACHE_SIZE:       return 0;
-    case _SC_LEVEL2_CACHE_ASSOC:      return 0;
-    case _SC_LEVEL2_CACHE_LINESIZE:   return 0;
-    case _SC_LEVEL3_CACHE_SIZE:       return 0;
-    case _SC_LEVEL3_CACHE_ASSOC:      return 0;
-    case _SC_LEVEL3_CACHE_LINESIZE:   return 0;
-    case _SC_LEVEL4_CACHE_SIZE:       return 0;
-    case _SC_LEVEL4_CACHE_ASSOC:      return 0;
-    case _SC_LEVEL4_CACHE_LINESIZE:   return 0;
+    case _SC_LEVEL1_ICACHE_SIZE:      return __sysconf_caches()->l1_i.size;
+    case _SC_LEVEL1_ICACHE_ASSOC:     return __sysconf_caches()->l1_i.assoc;
+    case _SC_LEVEL1_ICACHE_LINESIZE:  return __sysconf_caches()->l1_i.linesize;
+    case _SC_LEVEL1_DCACHE_SIZE:      return __sysconf_caches()->l1_d.size;
+    case _SC_LEVEL1_DCACHE_ASSOC:     return __sysconf_caches()->l1_d.assoc;
+    case _SC_LEVEL1_DCACHE_LINESIZE:  return __sysconf_caches()->l1_d.linesize;
+    case _SC_LEVEL2_CACHE_SIZE:       return __sysconf_caches()->l2.size;
+    case _SC_LEVEL2_CACHE_ASSOC:      return __sysconf_caches()->l2.assoc;
+    case _SC_LEVEL2_CACHE_LINESIZE:   return __sysconf_caches()->l2.linesize;
+    case _SC_LEVEL3_CACHE_SIZE:       return __sysconf_caches()->l3.size;
+    case _SC_LEVEL3_CACHE_ASSOC:      return __sysconf_caches()->l3.assoc;
+    case _SC_LEVEL3_CACHE_LINESIZE:   return __sysconf_caches()->l3.linesize;
+    case _SC_LEVEL4_CACHE_SIZE:       return __sysconf_caches()->l4.size;
+    case _SC_LEVEL4_CACHE_ASSOC:      return __sysconf_caches()->l4.assoc;
+    case _SC_LEVEL4_CACHE_LINESIZE:   return __sysconf_caches()->l4.linesize;
 
     default:
       errno = EINVAL;
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index 212aafc..f7999db 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -272,10 +272,9 @@
     PropertyServiceConnection connection;
     if (!connection.IsValid()) {
       errno = connection.GetLastError();
-      async_safe_format_log(
-          ANDROID_LOG_WARN, "libc",
-          "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", key, value,
-          errno, strerror(errno));
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Unable to set property \"%s\" to \"%s\": connection failed: %m", key,
+                            value);
       return -1;
     }
 
@@ -283,8 +282,8 @@
     if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
       errno = connection.GetLastError();
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
-                            key, value, errno, strerror(errno));
+                            "Unable to set property \"%s\" to \"%s\": write failed: %m", key,
+                            value);
       return -1;
     }
 
@@ -292,8 +291,7 @@
     if (!connection.RecvInt32(&result)) {
       errno = connection.GetLastError();
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
-                            key, value, errno, strerror(errno));
+                            "Unable to set property \"%s\" to \"%s\": recv failed: %m", key, value);
       return -1;
     }
 
diff --git a/libc/bionic/termios.cpp b/libc/bionic/termios.cpp
index 5fe8eb0..57b34b7 100644
--- a/libc/bionic/termios.cpp
+++ b/libc/bionic/termios.cpp
@@ -34,6 +34,10 @@
 #define __BIONIC_TERMIOS_INLINE /* Out of line. */
 #include <bits/termios_inlines.h>
 
+// POSIX added a couple more functions much later, so do the same for them.
+#define __BIONIC_TERMIOS_WINSIZE_INLINE /* Out of line. */
+#include <bits/termios_winsize_inlines.h>
+
 // Actually declared in <unistd.h>, present on all API levels.
 pid_t tcgetpgrp(int fd) {
   pid_t pid;
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index dbca9c0..d0f01d0 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -22,10 +22,16 @@
 #include <string.h>
 #include <sys/auxv.h>
 #include <sys/cdefs.h>
+#include <sys/hwprobe.h>
 #include <sys/time.h>
+#include <syscall.h>
 #include <time.h>
 #include <unistd.h>
 
+extern "C" int __clock_gettime(int, struct timespec*);
+extern "C" int __clock_getres(int, struct timespec*);
+extern "C" int __gettimeofday(struct timeval*, struct timezone*);
+
 static inline int vdso_return(int result) {
   if (__predict_true(result == 0)) return 0;
 
@@ -61,10 +67,13 @@
 }
 
 time_t time(time_t* t) {
+  // Only x86/x86-64 actually have time() in the vdso.
+#if defined(VDSO_TIME_SYMBOL)
   auto vdso_time = reinterpret_cast<decltype(&time)>(__libc_globals->vdso[VDSO_TIME].fn);
   if (__predict_true(vdso_time)) {
     return vdso_time(t);
   }
+#endif
 
   // We can't fallback to the time(2) system call because it doesn't exist for most architectures.
   timeval tv;
@@ -73,12 +82,41 @@
   return tv.tv_sec;
 }
 
+#if defined(__riscv)
+int __riscv_hwprobe(struct riscv_hwprobe* _Nonnull pairs, size_t pair_count, size_t cpu_count,
+                    unsigned long* _Nullable cpus, unsigned flags) {
+  auto vdso_riscv_hwprobe =
+      reinterpret_cast<decltype(&__riscv_hwprobe)>(__libc_globals->vdso[VDSO_RISCV_HWPROBE].fn);
+  if (__predict_true(vdso_riscv_hwprobe)) {
+    return -vdso_riscv_hwprobe(pairs, pair_count, cpu_count, cpus, flags);
+  }
+  // Inline the syscall directly in case someone's calling it from an
+  // ifunc resolver where we won't be able to set errno on failure.
+  // (Rather than our usual trick of letting the python-generated
+  // wrapper set errno but saving/restoring errno in cases where the API
+  // is to return an error value rather than setting errno.)
+  register long a0 __asm__("a0") = reinterpret_cast<long>(pairs);
+  register long a1 __asm__("a1") = pair_count;
+  register long a2 __asm__("a2") = cpu_count;
+  register long a3 __asm__("a3") = reinterpret_cast<long>(cpus);
+  register long a4 __asm__("a4") = flags;
+  register long a7 __asm__("a7") = __NR_riscv_hwprobe;
+  __asm__ volatile("ecall" : "=r"(a0) : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a7));
+  return -a0;
+}
+#endif
+
 void __libc_init_vdso(libc_globals* globals) {
   auto&& vdso = globals->vdso;
-  vdso[VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, nullptr };
-  vdso[VDSO_CLOCK_GETRES] = { VDSO_CLOCK_GETRES_SYMBOL, nullptr };
-  vdso[VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL, nullptr };
-  vdso[VDSO_TIME] = { VDSO_TIME_SYMBOL, nullptr };
+  vdso[VDSO_CLOCK_GETTIME] = {VDSO_CLOCK_GETTIME_SYMBOL, nullptr};
+  vdso[VDSO_CLOCK_GETRES] = {VDSO_CLOCK_GETRES_SYMBOL, nullptr};
+  vdso[VDSO_GETTIMEOFDAY] = {VDSO_GETTIMEOFDAY_SYMBOL, nullptr};
+#if defined(VDSO_TIME_SYMBOL)
+  vdso[VDSO_TIME] = {VDSO_TIME_SYMBOL, nullptr};
+#endif
+#if defined(VDSO_RISCV_HWPROBE_SYMBOL)
+  vdso[VDSO_RISCV_HWPROBE] = {VDSO_RISCV_HWPROBE_SYMBOL, nullptr};
+#endif
 
   // Do we have a vdso?
   uintptr_t vdso_ehdr_addr = getauxval(AT_SYSINFO_EHDR);
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index bb97b3e..b8c4432 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -27,10 +27,10 @@
  */
 
 #include <errno.h>
-#include <sys/param.h>
 #include <string.h>
-#include <wchar.h>
+#include <sys/param.h>
 #include <uchar.h>
+#include <wchar.h>
 
 #include "private/bionic_mbstate.h"
 
@@ -88,10 +88,10 @@
         r = 1;
       } else {
         r = mbrtowc(nullptr, *src + i, nmc - i, state);
-        if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+        if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
           return mbstate_reset_and_return_illegal(EILSEQ, state);
         }
-        if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
+        if (r == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
           return mbstate_reset_and_return_illegal(EILSEQ, state);
         }
         if (r == 0) {
@@ -114,11 +114,11 @@
       }
     } else {
       r = mbrtowc(dst + o, *src + i, nmc - i, state);
-      if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+      if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
         *src += i;
         return mbstate_reset_and_return_illegal(EILSEQ, state);
       }
-      if (r == __MB_ERR_INCOMPLETE_SEQUENCE) {
+      if (r == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
         *src += nmc;
         return mbstate_reset_and_return_illegal(EILSEQ, state);
       }
@@ -166,7 +166,7 @@
         r = 1;
       } else {
         r = wcrtomb(buf, wc, state);
-        if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+        if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
           return r;
         }
       }
@@ -187,14 +187,14 @@
     } else if (len - o >= sizeof(buf)) {
       // Enough space to translate in-place.
       r = wcrtomb(dst + o, wc, state);
-      if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+      if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
         *src += i;
         return r;
       }
     } else {
       // May not be enough space; use temp buffer.
       r = wcrtomb(buf, wc, state);
-      if (r == __MB_ERR_ILLEGAL_SEQUENCE) {
+      if (r == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
         *src += i;
         return r;
       }
diff --git a/libc/include/android/legacy_termios_inlines.h b/libc/include/android/legacy_termios_inlines.h
index 6222786..a816b40 100644
--- a/libc/include/android/legacy_termios_inlines.h
+++ b/libc/include/android/legacy_termios_inlines.h
@@ -43,3 +43,10 @@
 #include <bits/termios_inlines.h>
 
 #endif
+
+#if __ANDROID_API__ < 35
+
+#define __BIONIC_TERMIOS_WINSIZE_INLINE static __inline
+#include <bits/termios_winsize_inlines.h>
+
+#endif
diff --git a/libc/include/bits/bionic_multibyte_result.h b/libc/include/bits/bionic_multibyte_result.h
new file mode 100644
index 0000000..0d5cf21
--- /dev/null
+++ b/libc/include/bits/bionic_multibyte_result.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+/**
+ * @file bits/bionic_multibyte_result.h
+ * @brief Named values for the magic number return values of multibyte
+ * conversion APIs defined by C.
+ */
+
+#include <stddef.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * @brief The error values defined by C for multibyte conversion APIs.
+ *
+ * Refer to C23 7.30.1 Restartable multibyte/wide character conversion functions
+ * for more details.
+ */
+enum : size_t {
+  /// @brief An encoding error occurred. The bytes read are not a valid unicode
+  /// character, nor are they a partially valid character.
+  BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE = -1UL,
+#define BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE
+
+  /// @brief The bytes read may produce a valid unicode character, but the
+  /// sequence is incomplete. Future calls may complete the character.
+  BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE = -2UL,
+#define BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE
+
+  /// @brief The output of the call was the result of a previous successful
+  /// decoding. No new bytes were consumed.
+  ///
+  /// The common case for this return value is when mbrtoc16 returns the low
+  /// surrogate of a pair.
+  BIONIC_MULTIBYTE_RESULT_NO_BYTES_CONSUMED = -3UL,
+#define BIONIC_MULTIBYTE_RESULT_NO_BYTES_CONSUMED BIONIC_MULTIBYTE_RESULT_NO_BYTES_CONSUMED
+};
+
+__END_DECLS
diff --git a/libc/include/bits/elf_common.h b/libc/include/bits/elf_common.h
index b3c57a2..ac89dd6 100644
--- a/libc/include/bits/elf_common.h
+++ b/libc/include/bits/elf_common.h
@@ -1248,6 +1248,7 @@
 
 /*
  * RISC-V relocation types.
+ * https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#relocations
  */
 
 /* Relocation types used by the dynamic linker. */
@@ -1304,6 +1305,9 @@
 #define	R_RISCV_SET32		56
 #define	R_RISCV_32_PCREL	57
 #define	R_RISCV_IRELATIVE	58
+#define	R_RISCV_PLT32		59
+#define	R_RISCV_SET_ULEB128	60
+#define	R_RISCV_SUB_ULEB128	61
 
 #define	R_SPARC_NONE		0
 #define	R_SPARC_8		1
diff --git a/libc/include/bits/getentropy.h b/libc/include/bits/getentropy.h
new file mode 100644
index 0000000..a5a14f7
--- /dev/null
+++ b/libc/include/bits/getentropy.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+/**
+ * @file bits/getentropy.h
+ * @brief The getentropy() function.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/**
+ * [getentropy(3)](http://man7.org/linux/man-pages/man3/getentropy.3.html) fills the given buffer
+ * with random bytes.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 28.
+ *
+ * See also arc4random_buf() which is available in all API levels.
+ */
+int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+
+__END_DECLS
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index 79f7da0..50817af 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -60,6 +60,9 @@
 #if defined(__NR_brk)
   #define SYS_brk __NR_brk
 #endif
+#if defined(__NR_cachestat)
+  #define SYS_cachestat __NR_cachestat
+#endif
 #if defined(__NR_capget)
   #define SYS_capget __NR_capget
 #endif
@@ -909,6 +912,9 @@
 #if defined(__NR_riscv_flush_icache)
   #define SYS_riscv_flush_icache __NR_riscv_flush_icache
 #endif
+#if defined(__NR_riscv_hwprobe)
+  #define SYS_riscv_hwprobe __NR_riscv_hwprobe
+#endif
 #if defined(__NR_rmdir)
   #define SYS_rmdir __NR_rmdir
 #endif
diff --git a/libc/include/bits/page_size.h b/libc/include/bits/page_size.h
new file mode 100644
index 0000000..ca434e5
--- /dev/null
+++ b/libc/include/bits/page_size.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#if !defined(__BIONIC_NO_PAGE_SIZE_MACRO)
+#define PAGE_SIZE 4096
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+#endif
+
+__END_DECLS
diff --git a/libc/include/bits/termios_winsize_inlines.h b/libc/include/bits/termios_winsize_inlines.h
new file mode 100644
index 0000000..ae246e4
--- /dev/null
+++ b/libc/include/bits/termios_winsize_inlines.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <linux/termios.h>
+
+#if !defined(__BIONIC_TERMIOS_WINSIZE_INLINE)
+#define __BIONIC_TERMIOS_WINSIZE_INLINE static __inline
+#endif
+
+__BEGIN_DECLS
+
+__BIONIC_TERMIOS_WINSIZE_INLINE int tcgetwinsize(int __fd, struct winsize* _Nonnull __size) {
+  return ioctl(__fd, TIOCGWINSZ, __size);
+}
+
+__BIONIC_TERMIOS_WINSIZE_INLINE int tcsetwinsize(int __fd, const struct winsize* _Nonnull __size) {
+  return ioctl(__fd, TIOCSWINSZ, __size);
+}
+
+__END_DECLS
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 1f08628..4feade5 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -34,6 +34,7 @@
  */
 
 #include <limits.h>
+#include <bits/page_size.h>
 #include <bits/pthread_types.h>
 #include <sched.h>
 #include <sys/cdefs.h>
@@ -73,9 +74,14 @@
 #define PTHREAD_BARRIER_SERIAL_THREAD (-1)
 #endif
 
+
 #if defined(__LP64__)
+#if defined(PAGE_SIZE)
 #define PTHREAD_STACK_MIN (4 * PAGE_SIZE)
 #else
+#define PTHREAD_STACK_MIN 65536
+#endif
+#else
 #define PTHREAD_STACK_MIN (2 * PAGE_SIZE)
 #endif
 
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 6d047ae..0aaaac5 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -66,12 +66,14 @@
 /**
  * The size in words of a riscv64 jmp_buf. Room for callee-saved registers,
  * including floating point, stack pointer and program counter, various
- * internal implementation details, and leaving some free space.
+ * internal implementation details, and leaving lots of free space.
  *
- * Coincidentally matches OpenBSD, though they also save/restore the
- * floating point status register too.
+ * Deliberately very large given the uncertainty around the final form of
+ * hardware shadow stack, and the fact that x86-64 glibc needed to steal
+ * space from their enormous sigset_t (which we don't have) to be able to
+ * implement the CET shadow stack.
  */
-#define _JBLEN 32
+#define _JBLEN 64
 #elif defined(__x86_64__)
 /** The size in words of an x86-64 jmp_buf. Inherited from OpenBSD. */
 #define _JBLEN 11
diff --git a/libc/include/sys/cachectl.h b/libc/include/sys/cachectl.h
index 5ec295d..b5fabe3 100644
--- a/libc/include/sys/cachectl.h
+++ b/libc/include/sys/cachectl.h
@@ -28,6 +28,32 @@
 
 #pragma once
 
+/*
+ * @file sys/cachectl.h
+ * @brief Architecture-specific cache control.
+ */
+
 #include <sys/cdefs.h>
 
-/* This header file is obsolete. */
+__BEGIN_DECLS
+
+#if defined(__riscv)
+
+/**
+ * Flag for __riscv_flush_icache() to indicate that only the current
+ * thread's instruction cache needs to be flushed (rather than the
+ * default of all threads).
+ */
+#define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL
+
+/**
+ * __riscv_flush_icache(2) flushes the instruction cache for the given range of addresses.
+ * The address range is currently (Linux 6.4) ignored, so both pointers may be null.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
+int __riscv_flush_icache(void* _Nullable __start, void* _Nullable __end, unsigned long __flags);
+
+#endif
+
+__END_DECLS
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index 2091b90..2bad655 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -26,8 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_EPOLL_H_
-#define _SYS_EPOLL_H_
+#pragma once
+
+/**
+ * @file sys/epoll.h
+ * @brief I/O event file descriptors.
+ */
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
@@ -37,14 +41,67 @@
 
 __BEGIN_DECLS
 
+/**
+ * [epoll_create(2)](http://man7.org/linux/man-pages/man2/epoll_create.2.html)
+ * creates a new [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html)
+ * file descriptor.
+ *
+ * Returns a new file descriptor on success and returns -1 and sets `errno` on
+ * failure.
+ */
 int epoll_create(int __size);
+
+/**
+ * [epoll_create1(2)](http://man7.org/linux/man-pages/man2/epoll_create1.2.html)
+ * creates a new [epoll](http://man7.org/linux/man-pages/man7/epoll.7.html)
+ * file descriptor with the given flags.
+ *
+ * Returns a new file descriptor on success and returns -1 and sets `errno` on
+ * failure.
+ */
 int epoll_create1(int __flags);
 
+/**
+ * [epoll_ctl(2)](http://man7.org/linux/man-pages/man2/epoll_ctl.2.html)
+ * adds/modifies/removes file descriptors from the given epoll file descriptor.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __BIONIC_COMPLICATED_NULLNESS __event);
+
+/**
+ * [epoll_wait(2)](http://man7.org/linux/man-pages/man2/epoll_wait.2.html)
+ * waits for an event on the given epoll file descriptor.
+ *
+ * Returns the number of ready file descriptors on success, 0 on timeout,
+ * or -1 and sets `errno` on failure.
+ */
 int epoll_wait(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, int __timeout_ms);
+
+/**
+ * Like epoll_wait() but atomically applying the given signal mask.
+ */
 int epoll_pwait(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, int __timeout_ms, const sigset_t* _Nullable __mask);
+
+/**
+ * Like epoll_pwait() but using a 64-bit signal mask even on 32-bit systems.
+ *
+ * Available since API level 28.
+ */
 int epoll_pwait64(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, int __timeout_ms, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(28);
 
-__END_DECLS
+/**
+ * Like epoll_pwait() but with a `struct timespec` timeout, for nanosecond resolution.
+ *
+ * Available since API level 35.
+ */
+int epoll_pwait2(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, const struct timespec* _Nullable __timeout, const sigset_t* _Nullable __mask) __INTRODUCED_IN(35);
 
-#endif
+/**
+ * Like epoll_pwait2() but using a 64-bit signal mask even on 32-bit systems.
+ *
+ * Available since API level 35.
+ */
+int epoll_pwait2_64(int __epoll_fd, struct epoll_event* _Nonnull __events, int __event_count, const struct timespec* _Nullable __timeout, const sigset64_t* _Nullable __mask) __INTRODUCED_IN(35);
+
+__END_DECLS
diff --git a/libc/include/sys/hwprobe.h b/libc/include/sys/hwprobe.h
new file mode 100644
index 0000000..b1a8400
--- /dev/null
+++ b/libc/include/sys/hwprobe.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if __riscv
+
+/**
+ * @file sys/hwprobe.h
+ * @brief RISC-V hardware probing.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/* Pull in struct riscv_hwprobe and corresponding constants. */
+#include <asm/hwprobe.h>
+
+__BEGIN_DECLS
+
+/**
+ * [__riscv_hwprobe(2)](https://docs.kernel.org/riscv/hwprobe.html)
+ * queries hardware characteristics.
+ *
+ * A `__cpu_count` of 0 and null `__cpus` means "all online cpus".
+ *
+ * Returns 0 on success and returns an error number on failure.
+ */
+int __riscv_hwprobe(struct riscv_hwprobe* _Nonnull __pairs, size_t __pair_count, size_t __cpu_count, unsigned long* _Nullable __cpus, unsigned __flags);
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index 0251176..2ff5349 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -38,19 +38,9 @@
 
 #include <linux/random.h>
 
-__BEGIN_DECLS
+#include <bits/getentropy.h>
 
-/**
- * [getentropy(3)](http://man7.org/linux/man-pages/man3/getentropy.3.html) fills the given buffer
- * with random bytes.
- *
- * Returns 0 on success, and returns -1 and sets `errno` on failure.
- *
- * Available since API level 28.
- *
- * See also arc4random_buf() which is available in all API levels.
- */
-int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+__BEGIN_DECLS
 
 /**
  * [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
diff --git a/libc/include/sys/user.h b/libc/include/sys/user.h
index 432c7cb..1d20034 100644
--- a/libc/include/sys/user.h
+++ b/libc/include/sys/user.h
@@ -32,10 +32,9 @@
 #include <stddef.h> /* For size_t. */
 #include <stdint.h>
 
-__BEGIN_DECLS
+#include <bits/page_size.h>
 
-#define PAGE_SIZE 4096
-#define PAGE_MASK (~(PAGE_SIZE - 1))
+__BEGIN_DECLS
 
 #if defined(__i386__)
 
diff --git a/libc/include/termios.h b/libc/include/termios.h
index 853b4eb..7abff5d 100644
--- a/libc/include/termios.h
+++ b/libc/include/termios.h
@@ -149,6 +149,25 @@
 
 #endif
 
+#if __ANDROID_API__ >= 35
+// These two functions were POSIX Issue 8 additions that we can also trivially
+// implement as inlines for older OS version.
+
+/**
+ * tcgetwinsize(3) gets the window size of the given terminal.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int tcgetwinsize(int __fd, struct winsize* _Nonnull __size);
+
+/**
+ * tcsetwinsize(3) sets the window size of the given terminal.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int tcsetwinsize(int __fd, const struct winsize* _Nonnull __size);
+#endif
+
 __END_DECLS
 
 #include <android/legacy_termios_inlines.h>
diff --git a/libc/include/uchar.h b/libc/include/uchar.h
index 0c7424d..626372a 100644
--- a/libc/include/uchar.h
+++ b/libc/include/uchar.h
@@ -35,6 +35,8 @@
 
 #include <stddef.h>
 #include <sys/cdefs.h>
+
+#include <bits/bionic_multibyte_result.h>
 #include <bits/mbstate_t.h>
 
 __BEGIN_DECLS
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 9385264..dcad630 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -34,6 +34,7 @@
 #include <sys/select.h>
 
 #include <bits/fcntl.h>
+#include <bits/getentropy.h>
 #include <bits/getopt.h>
 #include <bits/ioctl.h>
 #include <bits/lockf.h>
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 2671580..c4e9679 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -37,6 +37,7 @@
 #include <time.h>
 #include <xlocale.h>
 
+#include <bits/bionic_multibyte_result.h>
 #include <bits/mbstate_t.h>
 #include <bits/wchar_limits.h>
 #include <bits/wctype.h>
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
index 71b25e7..b9ea9bc 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
@@ -421,4 +421,5 @@
 #define __NR_process_mrelease (__NR_SYSCALL_BASE + 448)
 #define __NR_futex_waitv (__NR_SYSCALL_BASE + 449)
 #define __NR_set_mempolicy_home_node (__NR_SYSCALL_BASE + 450)
+#define __NR_cachestat (__NR_SYSCALL_BASE + 451)
 #endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
index 08b3b9a..f7eb7ca 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
@@ -433,4 +433,5 @@
 #define __NR_process_mrelease (__NR_SYSCALL_BASE + 448)
 #define __NR_futex_waitv (__NR_SYSCALL_BASE + 449)
 #define __NR_set_mempolicy_home_node (__NR_SYSCALL_BASE + 450)
+#define __NR_cachestat (__NR_SYSCALL_BASE + 451)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 3ec1354..7852454 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -93,4 +93,5 @@
 #define HWCAP2_SME_BI32I32 (1UL << 40)
 #define HWCAP2_SME_B16B16 (1UL << 41)
 #define HWCAP2_SME_F16F16 (1UL << 42)
+#define HWCAP2_MOPS (1UL << 43)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index a413b36..ea690eb 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -126,6 +126,10 @@
   __u64 flags;
   __u64 reserved[2];
 };
+struct kvm_arm_counter_offset {
+  __u64 counter_offset;
+  __u64 reserved;
+};
 #define KVM_ARM_TAGS_TO_GUEST 0
 #define KVM_ARM_TAGS_FROM_GUEST 1
 #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
@@ -204,6 +208,8 @@
   KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
   KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
 };
+#define KVM_ARM_VM_SMCCC_CTRL 0
+#define KVM_ARM_VM_SMCCC_FILTER 0
 #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
@@ -237,6 +243,8 @@
 #define KVM_ARM_VCPU_TIMER_CTRL 1
 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
+#define KVM_ARM_VCPU_TIMER_IRQ_HVTIMER 2
+#define KVM_ARM_VCPU_TIMER_IRQ_HPTIMER 3
 #define KVM_ARM_VCPU_PVTIME_CTRL 2
 #define KVM_ARM_VCPU_PVTIME_IPA 0
 #define KVM_ARM_IRQ_VCPU2_SHIFT 28
@@ -266,5 +274,18 @@
 #define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
 #define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0)
 #define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0)
+enum kvm_smccc_filter_action {
+  KVM_SMCCC_FILTER_HANDLE = 0,
+  KVM_SMCCC_FILTER_DENY,
+  KVM_SMCCC_FILTER_FWD_TO_USER,
+};
+struct kvm_smccc_filter {
+  __u32 base;
+  __u32 nr_functions;
+  __u8 action;
+  __u8 pad[15];
+};
+#define KVM_HYPERCALL_EXIT_SMC (1U << 0)
+#define KVM_HYPERCALL_EXIT_16BIT (1U << 1)
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-generic/bitsperlong.h b/libc/kernel/uapi/asm-generic/bitsperlong.h
index 8fb379f..e8945e3 100644
--- a/libc/kernel/uapi/asm-generic/bitsperlong.h
+++ b/libc/kernel/uapi/asm-generic/bitsperlong.h
@@ -19,6 +19,10 @@
 #ifndef _UAPI__ASM_GENERIC_BITS_PER_LONG
 #define _UAPI__ASM_GENERIC_BITS_PER_LONG
 #ifndef __BITS_PER_LONG
+#if defined(__CHAR_BIT__) && defined(__SIZEOF_LONG__)
+#define __BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__)
+#else
 #define __BITS_PER_LONG 32
 #endif
 #endif
+#endif
diff --git a/libc/kernel/uapi/asm-generic/fcntl.h b/libc/kernel/uapi/asm-generic/fcntl.h
index ea8c108..84c0481 100644
--- a/libc/kernel/uapi/asm-generic/fcntl.h
+++ b/libc/kernel/uapi/asm-generic/fcntl.h
@@ -78,7 +78,6 @@
 #define __O_TMPFILE 020000000
 #endif
 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
 #ifndef O_NDELAY
 #define O_NDELAY O_NONBLOCK
 #endif
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 1a321bf..ec7e78a 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -102,6 +102,8 @@
 #define SO_RESERVE_MEM 73
 #define SO_TXREHASH 74
 #define SO_RCVMARK 75
+#define SO_PASSPIDFD 76
+#define SO_PEERPIDFD 77
 #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-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index d23958b..24b3222 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -413,8 +413,9 @@
 #define __NR_process_mrelease 448
 #define __NR_futex_waitv 449
 #define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
 #undef __NR_syscalls
-#define __NR_syscalls 451
+#define __NR_syscalls 452
 #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
 #define __NR_fcntl __NR3264_fcntl
 #define __NR_statfs __NR3264_statfs
diff --git a/libc/kernel/uapi/asm-riscv/asm/auxvec.h b/libc/kernel/uapi/asm-riscv/asm/auxvec.h
index c70be17..30c8bec 100644
--- a/libc/kernel/uapi/asm-riscv/asm/auxvec.h
+++ b/libc/kernel/uapi/asm-riscv/asm/auxvec.h
@@ -28,4 +28,5 @@
 #define AT_L3_CACHESIZE 46
 #define AT_L3_CACHEGEOMETRY 47
 #define AT_VECTOR_SIZE_ARCH 9
+#define AT_MINSIGSTKSZ 51
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwcap.h b/libc/kernel/uapi/asm-riscv/asm/hwcap.h
index d130cf7..e22e14a 100644
--- a/libc/kernel/uapi/asm-riscv/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-riscv/asm/hwcap.h
@@ -24,4 +24,5 @@
 #define COMPAT_HWCAP_ISA_F (1 << ('F' - 'A'))
 #define COMPAT_HWCAP_ISA_D (1 << ('D' - 'A'))
 #define COMPAT_HWCAP_ISA_C (1 << ('C' - 'A'))
+#define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A'))
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
new file mode 100644
index 0000000..04c9213
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_HWPROBE_H
+#define _UAPI_ASM_HWPROBE_H
+#include <linux/types.h>
+struct riscv_hwprobe {
+  __s64 key;
+  __u64 value;
+};
+#define RISCV_HWPROBE_KEY_MVENDORID 0
+#define RISCV_HWPROBE_KEY_MARCHID 1
+#define RISCV_HWPROBE_KEY_MIMPID 2
+#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
+#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
+#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
+#define RISCV_HWPROBE_IMA_FD (1 << 0)
+#define RISCV_HWPROBE_IMA_C (1 << 1)
+#define RISCV_HWPROBE_IMA_V (1 << 2)
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
+#define RISCV_HWPROBE_KEY_CPUPERF_0 5
+#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
+#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
+#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
+#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
+#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
+#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/kvm.h b/libc/kernel/uapi/asm-riscv/asm/kvm.h
index b49e3a0..c595872 100644
--- a/libc/kernel/uapi/asm-riscv/asm/kvm.h
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -20,7 +20,9 @@
 #define __LINUX_KVM_RISCV_H
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+#include <asm/bitsperlong.h>
 #include <asm/ptrace.h>
+#define __KVM_HAVE_IRQ_LINE
 #define __KVM_HAVE_READONLY_MEM
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 #define KVM_INTERRUPT_SET - 1U
@@ -43,6 +45,7 @@
   unsigned long mvendorid;
   unsigned long marchid;
   unsigned long mimpid;
+  unsigned long zicboz_block_size;
 };
 struct kvm_riscv_core {
   struct user_regs_struct regs;
@@ -62,6 +65,15 @@
   unsigned long satp;
   unsigned long scounteren;
 };
+struct kvm_riscv_aia_csr {
+  unsigned long siselect;
+  unsigned long iprio1;
+  unsigned long iprio2;
+  unsigned long sieh;
+  unsigned long siph;
+  unsigned long iprio1h;
+  unsigned long iprio2h;
+};
 struct kvm_riscv_timer {
   __u64 frequency;
   __u64 time;
@@ -81,19 +93,41 @@
   KVM_RISCV_ISA_EXT_SVINVAL,
   KVM_RISCV_ISA_EXT_ZIHINTPAUSE,
   KVM_RISCV_ISA_EXT_ZICBOM,
+  KVM_RISCV_ISA_EXT_ZICBOZ,
+  KVM_RISCV_ISA_EXT_ZBB,
+  KVM_RISCV_ISA_EXT_SSAIA,
+  KVM_RISCV_ISA_EXT_V,
+  KVM_RISCV_ISA_EXT_SVNAPOT,
   KVM_RISCV_ISA_EXT_MAX,
 };
+enum KVM_RISCV_SBI_EXT_ID {
+  KVM_RISCV_SBI_EXT_V01 = 0,
+  KVM_RISCV_SBI_EXT_TIME,
+  KVM_RISCV_SBI_EXT_IPI,
+  KVM_RISCV_SBI_EXT_RFENCE,
+  KVM_RISCV_SBI_EXT_SRST,
+  KVM_RISCV_SBI_EXT_HSM,
+  KVM_RISCV_SBI_EXT_PMU,
+  KVM_RISCV_SBI_EXT_EXPERIMENTAL,
+  KVM_RISCV_SBI_EXT_VENDOR,
+  KVM_RISCV_SBI_EXT_MAX,
+};
 #define KVM_RISCV_TIMER_STATE_OFF 0
 #define KVM_RISCV_TIMER_STATE_ON 1
 #define KVM_REG_SIZE(id) (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
 #define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000
 #define KVM_REG_RISCV_TYPE_SHIFT 24
+#define KVM_REG_RISCV_SUBTYPE_MASK 0x0000000000FF0000
+#define KVM_REG_RISCV_SUBTYPE_SHIFT 16
 #define KVM_REG_RISCV_CONFIG (0x01 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_CONFIG_REG(name) (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_CORE (0x02 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_CORE_REG(name) (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT)
 #define KVM_REG_RISCV_CSR_REG(name) (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
+#define KVM_REG_RISCV_CSR_AIA_REG(name) (offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_TIMER_REG(name) (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
 #define KVM_REG_RISCV_FP_F (0x05 << KVM_REG_RISCV_TYPE_SHIFT)
@@ -101,5 +135,53 @@
 #define KVM_REG_RISCV_FP_D (0x06 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_FP_D_REG(name) (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
 #define KVM_REG_RISCV_ISA_EXT (0x07 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_EXT (0x08 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_SINGLE (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_MULTI_EN (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_MULTI_DIS (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_MULTI_REG(__ext_id) ((__ext_id) / __BITS_PER_LONG)
+#define KVM_REG_RISCV_SBI_MULTI_MASK(__ext_id) (1UL << ((__ext_id) % __BITS_PER_LONG))
+#define KVM_REG_RISCV_SBI_MULTI_REG_LAST KVM_REG_RISCV_SBI_MULTI_REG(KVM_RISCV_SBI_EXT_MAX - 1)
+#define KVM_REG_RISCV_VECTOR (0x09 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_VECTOR_CSR_REG(name) (offsetof(struct __riscv_v_ext_state, name) / sizeof(unsigned long))
+#define KVM_REG_RISCV_VECTOR_REG(n) ((n) + sizeof(struct __riscv_v_ext_state) / sizeof(unsigned long))
+#define KVM_DEV_RISCV_APLIC_ALIGN 0x1000
+#define KVM_DEV_RISCV_APLIC_SIZE 0x4000
+#define KVM_DEV_RISCV_APLIC_MAX_HARTS 0x4000
+#define KVM_DEV_RISCV_IMSIC_ALIGN 0x1000
+#define KVM_DEV_RISCV_IMSIC_SIZE 0x1000
+#define KVM_DEV_RISCV_AIA_GRP_CONFIG 0
+#define KVM_DEV_RISCV_AIA_CONFIG_MODE 0
+#define KVM_DEV_RISCV_AIA_CONFIG_IDS 1
+#define KVM_DEV_RISCV_AIA_CONFIG_SRCS 2
+#define KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS 3
+#define KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT 4
+#define KVM_DEV_RISCV_AIA_CONFIG_HART_BITS 5
+#define KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS 6
+#define KVM_DEV_RISCV_AIA_MODE_EMUL 0
+#define KVM_DEV_RISCV_AIA_MODE_HWACCEL 1
+#define KVM_DEV_RISCV_AIA_MODE_AUTO 2
+#define KVM_DEV_RISCV_AIA_IDS_MIN 63
+#define KVM_DEV_RISCV_AIA_IDS_MAX 2048
+#define KVM_DEV_RISCV_AIA_SRCS_MAX 1024
+#define KVM_DEV_RISCV_AIA_GROUP_BITS_MAX 8
+#define KVM_DEV_RISCV_AIA_GROUP_SHIFT_MIN 24
+#define KVM_DEV_RISCV_AIA_GROUP_SHIFT_MAX 56
+#define KVM_DEV_RISCV_AIA_HART_BITS_MAX 16
+#define KVM_DEV_RISCV_AIA_GUEST_BITS_MAX 8
+#define KVM_DEV_RISCV_AIA_GRP_ADDR 1
+#define KVM_DEV_RISCV_AIA_ADDR_APLIC 0
+#define KVM_DEV_RISCV_AIA_ADDR_IMSIC(__vcpu) (1 + (__vcpu))
+#define KVM_DEV_RISCV_AIA_ADDR_MAX (1 + KVM_DEV_RISCV_APLIC_MAX_HARTS)
+#define KVM_DEV_RISCV_AIA_GRP_CTRL 2
+#define KVM_DEV_RISCV_AIA_CTRL_INIT 0
+#define KVM_DEV_RISCV_AIA_GRP_APLIC 3
+#define KVM_DEV_RISCV_AIA_GRP_IMSIC 4
+#define KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS 12
+#define KVM_DEV_RISCV_AIA_IMSIC_ISEL_MASK ((1U << KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS) - 1)
+#define KVM_DEV_RISCV_AIA_IMSIC_MKATTR(__vcpu,__isel) (((__vcpu) << KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS) | ((__isel) & KVM_DEV_RISCV_AIA_IMSIC_ISEL_MASK))
+#define KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(__attr) ((__attr) & KVM_DEV_RISCV_AIA_IMSIC_ISEL_MASK)
+#define KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(__attr) ((__attr) >> KVM_DEV_RISCV_AIA_IMSIC_ISEL_BITS)
+#define KVM_NR_IRQCHIPS 1
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/ptrace.h b/libc/kernel/uapi/asm-riscv/asm/ptrace.h
index 94e4ac9..f491908 100644
--- a/libc/kernel/uapi/asm-riscv/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-riscv/asm/ptrace.h
@@ -67,10 +67,28 @@
   __u32 fcsr;
   __u32 reserved[3];
 };
+struct __riscv_ctx_hdr {
+  __u32 magic;
+  __u32 size;
+};
+struct __riscv_extra_ext_header {
+  __u32 __padding[129] __attribute__((aligned(16)));
+  __u32 reserved;
+  struct __riscv_ctx_hdr hdr;
+};
 union __riscv_fp_state {
   struct __riscv_f_ext_state f;
   struct __riscv_d_ext_state d;
   struct __riscv_q_ext_state q;
 };
+struct __riscv_v_ext_state {
+  unsigned long vstart;
+  unsigned long vl;
+  unsigned long vtype;
+  unsigned long vcsr;
+  unsigned long vlenb;
+  void * datap;
+};
+#define RISCV_MAX_VLENB (8192)
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/sigcontext.h b/libc/kernel/uapi/asm-riscv/asm/sigcontext.h
index 0553b94..bf00435 100644
--- a/libc/kernel/uapi/asm-riscv/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-riscv/asm/sigcontext.h
@@ -19,8 +19,19 @@
 #ifndef _UAPI_ASM_RISCV_SIGCONTEXT_H
 #define _UAPI_ASM_RISCV_SIGCONTEXT_H
 #include <asm/ptrace.h>
+#define RISCV_V_MAGIC 0x53465457
+#define END_MAGIC 0x0
+#define END_HDR_SIZE 0x0
+#ifndef __ASSEMBLY__
+struct __sc_riscv_v_state {
+  struct __riscv_v_ext_state v_state;
+} __attribute__((aligned(16)));
 struct sigcontext {
   struct user_regs_struct sc_regs;
-  union __riscv_fp_state sc_fpregs;
+  union {
+    union __riscv_fp_state sc_fpregs;
+    struct __riscv_extra_ext_header sc_extdesc;
+  };
 };
 #endif
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/unistd.h b/libc/kernel/uapi/asm-riscv/asm/unistd.h
index 665b820..b321ead 100644
--- a/libc/kernel/uapi/asm-riscv/asm/unistd.h
+++ b/libc/kernel/uapi/asm-riscv/asm/unistd.h
@@ -27,3 +27,7 @@
 #define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
 #endif
 __SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
+#ifndef __NR_riscv_hwprobe
+#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14)
+#endif
+__SYSCALL(__NR_riscv_hwprobe, sys_riscv_hwprobe)
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 5c8f5a6..105a8e1 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -420,4 +420,5 @@
 #define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT (56)
 #define KVM_VCPU_TSC_CTRL 0
 #define KVM_VCPU_TSC_OFFSET 0
+#define KVM_EXIT_HYPERCALL_LONG_MODE BIT(0)
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/mtrr.h b/libc/kernel/uapi/asm-x86/asm/mtrr.h
index c709a70..9d596ba 100644
--- a/libc/kernel/uapi/asm-x86/asm/mtrr.h
+++ b/libc/kernel/uapi/asm-x86/asm/mtrr.h
@@ -57,13 +57,6 @@
 typedef __u8 mtrr_type;
 #define MTRR_NUM_FIXED_RANGES 88
 #define MTRR_MAX_VAR_RANGES 256
-struct mtrr_state_type {
-  struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
-  mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
-  unsigned char enabled;
-  unsigned char have_fixed;
-  mtrr_type def_type;
-};
 #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
 #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
 #define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry)
diff --git a/libc/kernel/uapi/asm-x86/asm/prctl.h b/libc/kernel/uapi/asm-x86/asm/prctl.h
index c5ba2d6..e2fe9df 100644
--- a/libc/kernel/uapi/asm-x86/asm/prctl.h
+++ b/libc/kernel/uapi/asm-x86/asm/prctl.h
@@ -29,7 +29,13 @@
 #define ARCH_REQ_XCOMP_PERM 0x1023
 #define ARCH_GET_XCOMP_GUEST_PERM 0x1024
 #define ARCH_REQ_XCOMP_GUEST_PERM 0x1025
+#define ARCH_XCOMP_TILECFG 17
+#define ARCH_XCOMP_TILEDATA 18
 #define ARCH_MAP_VDSO_X32 0x2001
 #define ARCH_MAP_VDSO_32 0x2002
 #define ARCH_MAP_VDSO_64 0x2003
+#define ARCH_GET_UNTAG_MASK 0x4001
+#define ARCH_ENABLE_TAGGED_ADDR 0x4002
+#define ARCH_GET_MAX_TAG_BITS 0x4003
+#define ARCH_FORCE_TAGGED_SVA 0x4004
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index 0a95afd..759b9e3 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -83,6 +83,10 @@
 #define X86_CR3_PCD _BITUL(X86_CR3_PCD_BIT)
 #define X86_CR3_PCID_BITS 12
 #define X86_CR3_PCID_MASK (_AC((1UL << X86_CR3_PCID_BITS) - 1, UL))
+#define X86_CR3_LAM_U57_BIT 61
+#define X86_CR3_LAM_U57 _BITULL(X86_CR3_LAM_U57_BIT)
+#define X86_CR3_LAM_U48_BIT 62
+#define X86_CR3_LAM_U48 _BITULL(X86_CR3_LAM_U48_BIT)
 #define X86_CR3_PCID_NOFLUSH_BIT 63
 #define X86_CR3_PCID_NOFLUSH _BITULL(X86_CR3_PCID_NOFLUSH_BIT)
 #define X86_CR4_VME_BIT 0
@@ -129,6 +133,8 @@
 #define X86_CR4_PKE _BITUL(X86_CR4_PKE_BIT)
 #define X86_CR4_CET_BIT 23
 #define X86_CR4_CET _BITUL(X86_CR4_CET_BIT)
+#define X86_CR4_LAM_SUP_BIT 28
+#define X86_CR4_LAM_SUP _BITUL(X86_CR4_LAM_SUP_BIT)
 #define X86_CR8_TPR _AC(0x0000000f, UL)
 #define CX86_PCR0 0x20
 #define CX86_GCR 0xb8
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index 8e57516..f9d8dbd 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -458,4 +458,5 @@
 #define __NR_process_mrelease 448
 #define __NR_futex_waitv 449
 #define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index 54ff16f..34a9ecc 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -380,4 +380,5 @@
 #define __NR_process_mrelease 448
 #define __NR_futex_waitv 449
 #define __NR_set_mempolicy_home_node 450
+#define __NR_cachestat 451
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index 1e05d75..de6c857 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -333,6 +333,7 @@
 #define __NR_process_mrelease (__X32_SYSCALL_BIT + 448)
 #define __NR_futex_waitv (__X32_SYSCALL_BIT + 449)
 #define __NR_set_mempolicy_home_node (__X32_SYSCALL_BIT + 450)
+#define __NR_cachestat (__X32_SYSCALL_BIT + 451)
 #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
 #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
 #define __NR_ioctl (__X32_SYSCALL_BIT + 514)
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 8d0d0b0..d4ae7d4 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -126,6 +126,7 @@
 #define AMDGPU_CTX_QUERY2_FLAGS_GUILTY (1 << 2)
 #define AMDGPU_CTX_QUERY2_FLAGS_RAS_CE (1 << 3)
 #define AMDGPU_CTX_QUERY2_FLAGS_RAS_UE (1 << 4)
+#define AMDGPU_CTX_QUERY2_FLAGS_RESET_IN_PROGRESS (1 << 5)
 #define AMDGPU_CTX_PRIORITY_UNSET - 2048
 #define AMDGPU_CTX_PRIORITY_VERY_LOW - 1023
 #define AMDGPU_CTX_PRIORITY_LOW - 512
@@ -352,6 +353,7 @@
 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
 #define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08
 #define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09
+#define AMDGPU_CHUNK_ID_CP_GFX_SHADOW 0x0a
 struct drm_amdgpu_cs_chunk {
   __u32 chunk_id;
   __u32 length_dw;
@@ -425,6 +427,13 @@
     struct drm_amdgpu_cs_chunk_fence fence_data;
   };
 };
+#define AMDGPU_CS_CHUNK_CP_GFX_SHADOW_FLAGS_INIT_SHADOW 0x1
+struct drm_amdgpu_cs_chunk_cp_gfx_shadow {
+  __u64 shadow_va;
+  __u64 csa_va;
+  __u64 gds_va;
+  __u64 flags;
+};
 #define AMDGPU_IDS_FLAGS_FUSION 0x1
 #define AMDGPU_IDS_FLAGS_PREEMPTION 0x2
 #define AMDGPU_IDS_FLAGS_TMZ 0x4
@@ -509,6 +518,7 @@
 #define AMDGPU_INFO_VIDEO_CAPS 0x21
 #define AMDGPU_INFO_VIDEO_CAPS_DECODE 0
 #define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1
+#define AMDGPU_INFO_MAX_IBS 0x22
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
 #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
@@ -662,6 +672,10 @@
   __u32 gl2c_cache_size;
   __u64 mall_size;
   __u32 enabled_rb_pipes_mask_hi;
+  __u32 shadow_size;
+  __u32 shadow_alignment;
+  __u32 csa_size;
+  __u32 csa_alignment;
 };
 struct drm_amdgpu_info_hw_ip {
   __u32 hw_ip_version_major;
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index ea9525d..006373a 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -179,6 +179,9 @@
 #define I915_FORMAT_MOD_4_TILED_DG2_RC_CCS fourcc_mod_code(INTEL, 10)
 #define I915_FORMAT_MOD_4_TILED_DG2_MC_CCS fourcc_mod_code(INTEL, 11)
 #define I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC fourcc_mod_code(INTEL, 12)
+#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 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/habanalabs_accel.h b/libc/kernel/uapi/drm/habanalabs_accel.h
index d7dccef..75ec293 100644
--- a/libc/kernel/uapi/drm/habanalabs_accel.h
+++ b/libc/kernel/uapi/drm/habanalabs_accel.h
@@ -619,7 +619,8 @@
   HL_SERVER_GAUDI_HLS1H = 2,
   HL_SERVER_GAUDI_TYPE1 = 3,
   HL_SERVER_GAUDI_TYPE2 = 4,
-  HL_SERVER_GAUDI2_HLS2 = 5
+  HL_SERVER_GAUDI2_HLS2 = 5,
+  HL_SERVER_GAUDI2_TYPE1 = 7
 };
 #define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0)
 #define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1)
@@ -630,6 +631,8 @@
 #define HL_NOTIFIER_EVENT_GENERAL_HW_ERR (1ULL << 6)
 #define HL_NOTIFIER_EVENT_RAZWI (1ULL << 7)
 #define HL_NOTIFIER_EVENT_PAGE_FAULT (1ULL << 8)
+#define HL_NOTIFIER_EVENT_CRITICL_HW_ERR (1ULL << 9)
+#define HL_NOTIFIER_EVENT_CRITICL_FW_ERR (1ULL << 10)
 #define HL_INFO_HW_IP_INFO 0
 #define HL_INFO_HW_EVENTS 1
 #define HL_INFO_DRAM_USAGE 2
@@ -663,6 +666,8 @@
 #define HL_INFO_PAGE_FAULT_EVENT 33
 #define HL_INFO_USER_MAPPINGS 34
 #define HL_INFO_FW_GENERIC_REQ 35
+#define HL_INFO_HW_ERR_EVENT 36
+#define HL_INFO_FW_ERR_EVENT 37
 #define HL_INFO_VERSION_MAX_LEN 128
 #define HL_INFO_CARD_NAME_MAX_LEN 16
 #define HL_ENGINES_DATA_MAX_SIZE SZ_1M
@@ -692,15 +697,20 @@
   __u64 dram_page_size;
   __u32 edma_enabled_mask;
   __u16 number_of_user_interrupts;
-  __u16 pad2;
-  __u64 reserved4;
+  __u8 reserved1;
+  __u8 reserved2;
+  __u64 reserved3;
   __u64 device_mem_alloc_default_page_size;
+  __u64 reserved4;
   __u64 reserved5;
-  __u64 reserved6;
-  __u32 reserved7;
-  __u8 reserved8;
+  __u32 reserved6;
+  __u8 reserved7;
   __u8 revision_id;
-  __u8 pad[2];
+  __u16 tpc_interrupt_id;
+  __u32 rotator_enabled_mask;
+  __u32 reserved9;
+  __u64 engine_core_interrupt_reg_addr;
+  __u64 reserved_dram_size;
 };
 struct hl_info_dram_usage {
   __u64 dram_free_mem;
@@ -821,6 +831,21 @@
   __u32 engine_id;
   __u32 stream_id;
 };
+struct hl_info_hw_err_event {
+  __s64 timestamp;
+  __u16 event_id;
+  __u16 pad[3];
+};
+enum hl_info_fw_err_type {
+  HL_INFO_FW_HEARTBEAT_ERR,
+  HL_INFO_FW_REPORTED_ERR,
+};
+struct hl_info_fw_err_event {
+  __s64 timestamp;
+  __u16 err_type;
+  __u16 event_id;
+  __u32 pad;
+};
 struct hl_info_dev_memalloc_page_sizes {
   __u64 page_order_bitmask;
 };
@@ -938,10 +963,16 @@
 #define HL_CS_FLAGS_UNRESERVE_SIGNALS_ONLY 0x2000
 #define HL_CS_FLAGS_ENGINE_CORE_COMMAND 0x4000
 #define HL_CS_FLAGS_FLUSH_PCI_HBW_WRITES 0x8000
+#define HL_CS_FLAGS_ENGINES_COMMAND 0x10000
 #define HL_CS_STATUS_SUCCESS 0
 #define HL_MAX_JOBS_PER_CS 512
-#define HL_ENGINE_CORE_HALT (1 << 0)
-#define HL_ENGINE_CORE_RUN (1 << 1)
+enum hl_engine_command {
+  HL_ENGINE_CORE_HALT = 1,
+  HL_ENGINE_CORE_RUN = 2,
+  HL_ENGINE_STALL = 3,
+  HL_ENGINE_RESUME = 4,
+  HL_ENGINE_COMMAND_MAX
+};
 struct hl_cs_in {
   union {
     struct {
@@ -953,6 +984,11 @@
       __u32 num_engine_cores;
       __u32 core_command;
     };
+    struct {
+      __u64 engines;
+      __u32 num_engines;
+      __u32 engine_command;
+    };
   };
   union {
     __u64 seq;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 794e784..ae79ab3 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -63,13 +63,20 @@
 #define I915_PMU_ENGINE_BUSY(class,instance) __I915_PMU_ENGINE(class, instance, I915_SAMPLE_BUSY)
 #define I915_PMU_ENGINE_WAIT(class,instance) __I915_PMU_ENGINE(class, instance, I915_SAMPLE_WAIT)
 #define I915_PMU_ENGINE_SEMA(class,instance) __I915_PMU_ENGINE(class, instance, I915_SAMPLE_SEMA)
-#define __I915_PMU_OTHER(x) (__I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x))
+#define __I915_PMU_GT_SHIFT (60)
+#define ___I915_PMU_OTHER(gt,x) (((__u64) __I915_PMU_ENGINE(0xff, 0xff, 0xf) + 1 + (x)) | ((__u64) (gt) << __I915_PMU_GT_SHIFT))
+#define __I915_PMU_OTHER(x) ___I915_PMU_OTHER(0, x)
 #define I915_PMU_ACTUAL_FREQUENCY __I915_PMU_OTHER(0)
 #define I915_PMU_REQUESTED_FREQUENCY __I915_PMU_OTHER(1)
 #define I915_PMU_INTERRUPTS __I915_PMU_OTHER(2)
 #define I915_PMU_RC6_RESIDENCY __I915_PMU_OTHER(3)
 #define I915_PMU_SOFTWARE_GT_AWAKE_TIME __I915_PMU_OTHER(4)
 #define I915_PMU_LAST I915_PMU_RC6_RESIDENCY
+#define __I915_PMU_ACTUAL_FREQUENCY(gt) ___I915_PMU_OTHER(gt, 0)
+#define __I915_PMU_REQUESTED_FREQUENCY(gt) ___I915_PMU_OTHER(gt, 1)
+#define __I915_PMU_INTERRUPTS(gt) ___I915_PMU_OTHER(gt, 2)
+#define __I915_PMU_RC6_RESIDENCY(gt) ___I915_PMU_OTHER(gt, 3)
+#define __I915_PMU_SOFTWARE_GT_AWAKE_TIME(gt) ___I915_PMU_OTHER(gt, 4)
 #define I915_NR_TEX_REGIONS 255
 #define I915_LOG_MIN_TEX_REGION_SIZE 14
 typedef struct _drm_i915_init {
@@ -369,6 +376,7 @@
 #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
 #define I915_PARAM_HAS_USERPTR_PROBE 56
 #define I915_PARAM_OA_TIMESTAMP_FREQUENCY 57
+#define I915_PARAM_PXP_STATUS 58
 struct drm_i915_getparam {
   __s32 param;
   int  * value;
@@ -797,7 +805,7 @@
 #define I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE 0
 #define I915_CONTEXT_ENGINES_EXT_BOND 1
 #define I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT 2
-  struct i915_engine_class_instance engines[0];
+  struct i915_engine_class_instance engines[];
 } __attribute__((packed));
 #define I915_DEFINE_CONTEXT_PARAM_ENGINES(name__,N__) struct { __u64 extensions; struct i915_engine_class_instance engines[N__]; \
 } __attribute__((packed)) name__
@@ -849,6 +857,8 @@
   I915_OA_FORMAT_A32u40_A4u32_B8_C8,
   I915_OAR_FORMAT_A32u40_A4u32_B8_C8,
   I915_OA_FORMAT_A24u40_A14u32_B8_C8,
+  I915_OAM_FORMAT_MPEC8u64_B8_C8,
+  I915_OAM_FORMAT_MPEC8u32_B8_C8,
   I915_OA_FORMAT_MAX
 };
 enum drm_i915_perf_property_id {
@@ -860,6 +870,8 @@
   DRM_I915_PERF_PROP_HOLD_PREEMPTION,
   DRM_I915_PERF_PROP_GLOBAL_SSEU,
   DRM_I915_PERF_PROP_POLL_OA_PERIOD,
+  DRM_I915_PERF_PROP_OA_ENGINE_CLASS,
+  DRM_I915_PERF_PROP_OA_ENGINE_INSTANCE,
   DRM_I915_PERF_PROP_MAX
 };
 struct drm_i915_perf_open_param {
@@ -983,6 +995,7 @@
   __u32 flags;
 #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
 #define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
+#define I915_GEM_CREATE_EXT_SET_PAT 2
   __u64 extensions;
 };
 struct drm_i915_gem_create_ext_memory_regions {
@@ -995,6 +1008,11 @@
   struct i915_user_extension base;
   __u32 flags;
 };
+struct drm_i915_gem_create_ext_set_pat {
+  struct i915_user_extension base;
+  __u32 pat_index;
+  __u32 rsvd;
+};
 #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
 #ifdef __cplusplus
 }
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index f5a4627..317796d 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -85,7 +85,8 @@
 #define MSM_PREP_READ 0x01
 #define MSM_PREP_WRITE 0x02
 #define MSM_PREP_NOSYNC 0x04
-#define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC)
+#define MSM_PREP_BOOST 0x08
+#define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC | MSM_PREP_BOOST | 0)
 struct drm_msm_gem_cpu_prep {
   __u32 handle;
   __u32 op;
@@ -96,7 +97,11 @@
 };
 struct drm_msm_gem_submit_reloc {
   __u32 submit_offset;
+#ifdef __cplusplus
+  __u32 _or;
+#else
   __u32 or;
+#endif
   __s32 shift;
   __u32 reloc_idx;
   __u64 reloc_offset;
@@ -154,9 +159,11 @@
   __u32 syncobj_stride;
   __u32 pad;
 };
+#define MSM_WAIT_FENCE_BOOST 0x00000001
+#define MSM_WAIT_FENCE_FLAGS (MSM_WAIT_FENCE_BOOST | 0)
 struct drm_msm_wait_fence {
   __u32 fence;
-  __u32 pad;
+  __u32 flags;
   struct drm_msm_timespec timeout;
   __u32 queueid;
 };
diff --git a/libc/kernel/uapi/drm/qaic_accel.h b/libc/kernel/uapi/drm/qaic_accel.h
new file mode 100644
index 0000000..d2a43cf
--- /dev/null
+++ b/libc/kernel/uapi/drm/qaic_accel.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef QAIC_ACCEL_H_
+#define QAIC_ACCEL_H_
+#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define QAIC_MANAGE_MAX_MSG_LENGTH SZ_4K
+#define QAIC_SEM_INSYNCFENCE 2
+#define QAIC_SEM_OUTSYNCFENCE 1
+#define QAIC_SEM_NOP 0
+#define QAIC_SEM_INIT 1
+#define QAIC_SEM_INC 2
+#define QAIC_SEM_DEC 3
+#define QAIC_SEM_WAIT_EQUAL 4
+#define QAIC_SEM_WAIT_GT_EQ 5
+#define QAIC_SEM_WAIT_GT_0 6
+#define QAIC_TRANS_UNDEFINED 0
+#define QAIC_TRANS_PASSTHROUGH_FROM_USR 1
+#define QAIC_TRANS_PASSTHROUGH_TO_USR 2
+#define QAIC_TRANS_PASSTHROUGH_FROM_DEV 3
+#define QAIC_TRANS_PASSTHROUGH_TO_DEV 4
+#define QAIC_TRANS_DMA_XFER_FROM_USR 5
+#define QAIC_TRANS_DMA_XFER_TO_DEV 6
+#define QAIC_TRANS_ACTIVATE_FROM_USR 7
+#define QAIC_TRANS_ACTIVATE_FROM_DEV 8
+#define QAIC_TRANS_ACTIVATE_TO_DEV 9
+#define QAIC_TRANS_DEACTIVATE_FROM_USR 10
+#define QAIC_TRANS_DEACTIVATE_FROM_DEV 11
+#define QAIC_TRANS_STATUS_FROM_USR 12
+#define QAIC_TRANS_STATUS_TO_USR 13
+#define QAIC_TRANS_STATUS_FROM_DEV 14
+#define QAIC_TRANS_STATUS_TO_DEV 15
+#define QAIC_TRANS_TERMINATE_FROM_DEV 16
+#define QAIC_TRANS_TERMINATE_TO_DEV 17
+#define QAIC_TRANS_DMA_XFER_CONT 18
+#define QAIC_TRANS_VALIDATE_PARTITION_FROM_DEV 19
+#define QAIC_TRANS_VALIDATE_PARTITION_TO_DEV 20
+struct qaic_manage_trans_hdr {
+  __u32 type;
+  __u32 len;
+};
+struct qaic_manage_trans_passthrough {
+  struct qaic_manage_trans_hdr hdr;
+  __u8 data[];
+};
+struct qaic_manage_trans_dma_xfer {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 tag;
+  __u32 pad;
+  __u64 addr;
+  __u64 size;
+};
+struct qaic_manage_trans_activate_to_dev {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 queue_size;
+  __u32 eventfd;
+  __u32 options;
+  __u32 pad;
+};
+struct qaic_manage_trans_activate_from_dev {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 status;
+  __u32 dbc_id;
+  __u64 options;
+};
+struct qaic_manage_trans_deactivate {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 dbc_id;
+  __u32 pad;
+};
+struct qaic_manage_trans_status_to_dev {
+  struct qaic_manage_trans_hdr hdr;
+};
+struct qaic_manage_trans_status_from_dev {
+  struct qaic_manage_trans_hdr hdr;
+  __u16 major;
+  __u16 minor;
+  __u32 status;
+  __u64 status_flags;
+};
+struct qaic_manage_msg {
+  __u32 len;
+  __u32 count;
+  __u64 data;
+};
+struct qaic_create_bo {
+  __u64 size;
+  __u32 handle;
+  __u32 pad;
+};
+struct qaic_mmap_bo {
+  __u32 handle;
+  __u32 pad;
+  __u64 offset;
+};
+struct qaic_sem {
+  __u16 val;
+  __u8 index;
+  __u8 presync;
+  __u8 cmd;
+  __u8 flags;
+  __u16 pad;
+};
+struct qaic_attach_slice_entry {
+  __u64 size;
+  struct qaic_sem sem0;
+  struct qaic_sem sem1;
+  struct qaic_sem sem2;
+  struct qaic_sem sem3;
+  __u64 dev_addr;
+  __u64 db_addr;
+  __u32 db_data;
+  __u32 db_len;
+  __u64 offset;
+};
+struct qaic_attach_slice_hdr {
+  __u32 count;
+  __u32 dbc_id;
+  __u32 handle;
+  __u32 dir;
+  __u64 size;
+};
+struct qaic_attach_slice {
+  struct qaic_attach_slice_hdr hdr;
+  __u64 data;
+};
+struct qaic_execute_entry {
+  __u32 handle;
+  __u32 dir;
+};
+struct qaic_partial_execute_entry {
+  __u32 handle;
+  __u32 dir;
+  __u64 resize;
+};
+struct qaic_execute_hdr {
+  __u32 count;
+  __u32 dbc_id;
+};
+struct qaic_execute {
+  struct qaic_execute_hdr hdr;
+  __u64 data;
+};
+struct qaic_wait {
+  __u32 handle;
+  __u32 timeout;
+  __u32 dbc_id;
+  __u32 pad;
+};
+struct qaic_perf_stats_hdr {
+  __u16 count;
+  __u16 pad;
+  __u32 dbc_id;
+};
+struct qaic_perf_stats {
+  struct qaic_perf_stats_hdr hdr;
+  __u64 data;
+};
+struct qaic_perf_stats_entry {
+  __u32 handle;
+  __u32 queue_level_before;
+  __u32 num_queue_element;
+  __u32 submit_latency_us;
+  __u32 device_latency_us;
+  __u32 pad;
+};
+#define DRM_QAIC_MANAGE 0x00
+#define DRM_QAIC_CREATE_BO 0x01
+#define DRM_QAIC_MMAP_BO 0x02
+#define DRM_QAIC_ATTACH_SLICE_BO 0x03
+#define DRM_QAIC_EXECUTE_BO 0x04
+#define DRM_QAIC_PARTIAL_EXECUTE_BO 0x05
+#define DRM_QAIC_WAIT_BO 0x06
+#define DRM_QAIC_PERF_STATS_BO 0x07
+#define DRM_IOCTL_QAIC_MANAGE DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_MANAGE, struct qaic_manage_msg)
+#define DRM_IOCTL_QAIC_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_CREATE_BO, struct qaic_create_bo)
+#define DRM_IOCTL_QAIC_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_MMAP_BO, struct qaic_mmap_bo)
+#define DRM_IOCTL_QAIC_ATTACH_SLICE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_ATTACH_SLICE_BO, struct qaic_attach_slice)
+#define DRM_IOCTL_QAIC_EXECUTE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_EXECUTE_BO, struct qaic_execute)
+#define DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_PARTIAL_EXECUTE_BO, struct qaic_execute)
+#define DRM_IOCTL_QAIC_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_WAIT_BO, struct qaic_wait)
+#define DRM_IOCTL_QAIC_PERF_STATS_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_PERF_STATS_BO, struct qaic_perf_stats)
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/linux/affs_hardblocks.h b/libc/kernel/uapi/linux/affs_hardblocks.h
index f46bdf1..168f7dc 100644
--- a/libc/kernel/uapi/linux/affs_hardblocks.h
+++ b/libc/kernel/uapi/linux/affs_hardblocks.h
@@ -20,57 +20,57 @@
 #define AFFS_HARDBLOCKS_H
 #include <linux/types.h>
 struct RigidDiskBlock {
-  __u32 rdb_ID;
+  __be32 rdb_ID;
   __be32 rdb_SummedLongs;
-  __s32 rdb_ChkSum;
-  __u32 rdb_HostID;
+  __be32 rdb_ChkSum;
+  __be32 rdb_HostID;
   __be32 rdb_BlockBytes;
-  __u32 rdb_Flags;
-  __u32 rdb_BadBlockList;
+  __be32 rdb_Flags;
+  __be32 rdb_BadBlockList;
   __be32 rdb_PartitionList;
-  __u32 rdb_FileSysHeaderList;
-  __u32 rdb_DriveInit;
-  __u32 rdb_Reserved1[6];
-  __u32 rdb_Cylinders;
-  __u32 rdb_Sectors;
-  __u32 rdb_Heads;
-  __u32 rdb_Interleave;
-  __u32 rdb_Park;
-  __u32 rdb_Reserved2[3];
-  __u32 rdb_WritePreComp;
-  __u32 rdb_ReducedWrite;
-  __u32 rdb_StepRate;
-  __u32 rdb_Reserved3[5];
-  __u32 rdb_RDBBlocksLo;
-  __u32 rdb_RDBBlocksHi;
-  __u32 rdb_LoCylinder;
-  __u32 rdb_HiCylinder;
-  __u32 rdb_CylBlocks;
-  __u32 rdb_AutoParkSeconds;
-  __u32 rdb_HighRDSKBlock;
-  __u32 rdb_Reserved4;
+  __be32 rdb_FileSysHeaderList;
+  __be32 rdb_DriveInit;
+  __be32 rdb_Reserved1[6];
+  __be32 rdb_Cylinders;
+  __be32 rdb_Sectors;
+  __be32 rdb_Heads;
+  __be32 rdb_Interleave;
+  __be32 rdb_Park;
+  __be32 rdb_Reserved2[3];
+  __be32 rdb_WritePreComp;
+  __be32 rdb_ReducedWrite;
+  __be32 rdb_StepRate;
+  __be32 rdb_Reserved3[5];
+  __be32 rdb_RDBBlocksLo;
+  __be32 rdb_RDBBlocksHi;
+  __be32 rdb_LoCylinder;
+  __be32 rdb_HiCylinder;
+  __be32 rdb_CylBlocks;
+  __be32 rdb_AutoParkSeconds;
+  __be32 rdb_HighRDSKBlock;
+  __be32 rdb_Reserved4;
   char rdb_DiskVendor[8];
   char rdb_DiskProduct[16];
   char rdb_DiskRevision[4];
   char rdb_ControllerVendor[8];
   char rdb_ControllerProduct[16];
   char rdb_ControllerRevision[4];
-  __u32 rdb_Reserved5[10];
+  __be32 rdb_Reserved5[10];
 };
 #define IDNAME_RIGIDDISK 0x5244534B
 struct PartitionBlock {
   __be32 pb_ID;
   __be32 pb_SummedLongs;
-  __s32 pb_ChkSum;
-  __u32 pb_HostID;
+  __be32 pb_ChkSum;
+  __be32 pb_HostID;
   __be32 pb_Next;
-  __u32 pb_Flags;
-  __u32 pb_Reserved1[2];
-  __u32 pb_DevFlags;
+  __be32 pb_Flags;
+  __be32 pb_Reserved1[2];
+  __be32 pb_DevFlags;
   __u8 pb_DriveName[32];
-  __u32 pb_Reserved2[15];
+  __be32 pb_Reserved2[15];
   __be32 pb_Environment[17];
-  __u32 pb_EReserved[15];
+  __be32 pb_EReserved[15];
 };
 #define IDNAME_PARTITION 0x50415254
 #define RDB_ALLOCATION_LIMIT 16
diff --git a/libc/kernel/uapi/linux/auto_dev-ioctl.h b/libc/kernel/uapi/linux/auto_dev-ioctl.h
index 23c8096..196bb86 100644
--- a/libc/kernel/uapi/linux/auto_dev-ioctl.h
+++ b/libc/kernel/uapi/linux/auto_dev-ioctl.h
@@ -85,7 +85,7 @@
     struct args_askumount askumount;
     struct args_ismountpoint ismountpoint;
   };
-  char path[0];
+  char path[];
 };
 enum {
   AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 4131ce4..48ec710 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -204,6 +204,7 @@
   BPF_PROG_TYPE_LSM,
   BPF_PROG_TYPE_SK_LOOKUP,
   BPF_PROG_TYPE_SYSCALL,
+  BPF_PROG_TYPE_NETFILTER,
 };
 enum bpf_attach_type {
   BPF_CGROUP_INET_INGRESS,
@@ -250,6 +251,8 @@
   BPF_PERF_EVENT,
   BPF_TRACE_KPROBE_MULTI,
   BPF_LSM_CGROUP,
+  BPF_STRUCT_OPS,
+  BPF_NETFILTER,
   __MAX_BPF_ATTACH_TYPE
 };
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -264,6 +267,7 @@
   BPF_LINK_TYPE_PERF_EVENT = 7,
   BPF_LINK_TYPE_KPROBE_MULTI = 8,
   BPF_LINK_TYPE_STRUCT_OPS = 9,
+  BPF_LINK_TYPE_NETFILTER = 10,
   MAX_BPF_LINK_TYPE,
 };
 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
@@ -305,6 +309,8 @@
   BPF_F_MMAPABLE = (1U << 10),
   BPF_F_PRESERVE_ELEMS = (1U << 11),
   BPF_F_INNER_MAP = (1U << 12),
+  BPF_F_LINK = (1U << 13),
+  BPF_F_PATH_FD = (1U << 14),
 };
 #define BPF_F_QUERY_EFFECTIVE (1U << 0)
 #define BPF_F_TEST_RUN_ON_CPU (1U << 0)
@@ -392,11 +398,13 @@
     __aligned_u64 fd_array;
     __aligned_u64 core_relos;
     __u32 core_relo_rec_size;
+    __u32 log_true_size;
   };
   struct {
     __aligned_u64 pathname;
     __u32 bpf_fd;
     __u32 file_flags;
+    __s32 path_fd;
   };
   struct {
     __u32 target_fd;
@@ -457,6 +465,7 @@
     __u32 btf_size;
     __u32 btf_log_size;
     __u32 btf_log_level;
+    __u32 btf_log_true_size;
   };
   struct {
     __u32 pid;
@@ -470,7 +479,10 @@
     __u64 probe_addr;
   } task_fd_query;
   struct {
-    __u32 prog_fd;
+    union {
+      __u32 prog_fd;
+      __u32 map_fd;
+    };
     union {
       __u32 target_fd;
       __u32 target_ifindex;
@@ -497,13 +509,25 @@
         __u32 target_btf_id;
         __u64 cookie;
       } tracing;
+      struct {
+        __u32 pf;
+        __u32 hooknum;
+        __s32 priority;
+        __u32 flags;
+      } netfilter;
     };
   } link_create;
   struct {
     __u32 link_fd;
-    __u32 new_prog_fd;
+    union {
+      __u32 new_prog_fd;
+      __u32 new_map_fd;
+    };
     __u32 flags;
-    __u32 old_prog_fd;
+    union {
+      __u32 old_prog_fd;
+      __u32 old_map_fd;
+    };
   } link_update;
   struct {
     __u32 link_fd;
@@ -954,6 +978,15 @@
     struct {
       __u32 ifindex;
     } xdp;
+    struct {
+      __u32 map_id;
+    } struct_ops;
+    struct {
+      __u32 pf;
+      __u32 hooknum;
+      __s32 priority;
+      __u32 flags;
+    } netfilter;
   };
 } __attribute__((aligned(8)));
 struct bpf_sock_addr {
@@ -1100,6 +1133,7 @@
   BPF_FIB_LOOKUP_DIRECT = (1U << 0),
   BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
   BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
+  BPF_FIB_LOOKUP_TBID = (1U << 3),
 };
 enum {
   BPF_FIB_LKUP_RET_SUCCESS,
@@ -1135,8 +1169,13 @@
     __be32 ipv4_dst;
     __u32 ipv6_dst[4];
   };
-  __be16 h_vlan_proto;
-  __be16 h_vlan_TCI;
+  union {
+    struct {
+      __be16 h_vlan_proto;
+      __be16 h_vlan_TCI;
+    };
+    __u32 tbid;
+  };
   __u8 smac[6];
   __u8 dmac[6];
 };
@@ -1232,6 +1271,9 @@
   __u64 : 64;
   __u64 : 64;
 } __attribute__((aligned(8)));
+struct bpf_refcount {
+  __u32 : 32;
+} __attribute__((aligned(4)));
 struct bpf_sysctl {
   __u32 write;
   __u32 file_pos;
@@ -1297,4 +1339,10 @@
   __u32 access_str_off;
   enum bpf_core_relo_kind kind;
 };
+enum {
+  BPF_F_TIMER_ABS = (1ULL << 0),
+};
+struct bpf_iter_num {
+  __u64 __opaque[1];
+} __attribute__((aligned(8)));
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 5220647..9a7a6fa 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -107,6 +107,7 @@
   __u64 unverified_errors;
 };
 #define BTRFS_SCRUB_READONLY 1
+#define BTRFS_SCRUB_SUPPORTED_FLAGS (BTRFS_SCRUB_READONLY)
 struct btrfs_ioctl_scrub_args {
   __u64 devid;
   __u64 start;
diff --git a/libc/kernel/uapi/linux/can.h b/libc/kernel/uapi/linux/can.h
index 1365dba..5103f32 100644
--- a/libc/kernel/uapi/linux/can.h
+++ b/libc/kernel/uapi/linux/can.h
@@ -109,5 +109,4 @@
   canid_t can_mask;
 };
 #define CAN_INV_FILTER 0x20000000U
-#define CAN_RAW_FILTER_MAX 512
 #endif
diff --git a/libc/kernel/uapi/linux/can/raw.h b/libc/kernel/uapi/linux/can/raw.h
index f8de179..e461c82 100644
--- a/libc/kernel/uapi/linux/can/raw.h
+++ b/libc/kernel/uapi/linux/can/raw.h
@@ -20,6 +20,7 @@
 #define _UAPI_CAN_RAW_H
 #include <linux/can.h>
 #define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW)
+#define CAN_RAW_FILTER_MAX 512
 enum {
   SCM_CAN_RAW_ERRQUEUE = 1,
 };
diff --git a/libc/kernel/uapi/linux/capability.h b/libc/kernel/uapi/linux/capability.h
index 8f3281e..78cba92 100644
--- a/libc/kernel/uapi/linux/capability.h
+++ b/libc/kernel/uapi/linux/capability.h
@@ -29,11 +29,12 @@
   __u32 version;
   int pid;
 }  * cap_user_header_t;
-typedef struct __user_cap_data_struct {
+struct __user_cap_data_struct {
   __u32 effective;
   __u32 permitted;
   __u32 inheritable;
-}  * cap_user_data_t;
+};
+typedef struct __user_cap_data_struct  * cap_user_data_t;
 #define VFS_CAP_REVISION_MASK 0xFF000000
 #define VFS_CAP_REVISION_SHIFT 24
 #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK
diff --git a/libc/kernel/uapi/linux/cm4000_cs.h b/libc/kernel/uapi/linux/cm4000_cs.h
deleted file mode 100644
index 41b7aa7..0000000
--- a/libc/kernel/uapi/linux/cm4000_cs.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _UAPI_CM4000_H_
-#define _UAPI_CM4000_H_
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#define MAX_ATR 33
-#define CM4000_MAX_DEV 4
-typedef struct atreq {
-  __s32 atr_len;
-  unsigned char atr[64];
-  __s32 power_act;
-  unsigned char bIFSD;
-  unsigned char bIFSC;
-} atreq_t;
-typedef struct ptsreq {
-  __u32 protocol;
-  unsigned char flags;
-  unsigned char pts1;
-  unsigned char pts2;
-  unsigned char pts3;
-} ptsreq_t;
-#define CM_IOC_MAGIC 'c'
-#define CM_IOC_MAXNR 255
-#define CM_IOCGSTATUS _IOR(CM_IOC_MAGIC, 0, unsigned char *)
-#define CM_IOCGATR _IOWR(CM_IOC_MAGIC, 1, atreq_t *)
-#define CM_IOCSPTS _IOW(CM_IOC_MAGIC, 2, ptsreq_t *)
-#define CM_IOCSRDR _IO(CM_IOC_MAGIC, 3)
-#define CM_IOCARDOFF _IO(CM_IOC_MAGIC, 4)
-#define CM_IOSDBGLVL _IOW(CM_IOC_MAGIC, 250, int *)
-#define CM_CARD_INSERTED 0x01
-#define CM_CARD_POWERED 0x02
-#define CM_ATR_PRESENT 0x04
-#define CM_ATR_VALID 0x08
-#define CM_STATE_VALID 0x0f
-#define CM_NO_READER 0x10
-#define CM_BAD_CARD 0x20
-#endif
diff --git a/libc/kernel/uapi/linux/const.h b/libc/kernel/uapi/linux/const.h
index c62a702..d83caad 100644
--- a/libc/kernel/uapi/linux/const.h
+++ b/libc/kernel/uapi/linux/const.h
@@ -30,7 +30,7 @@
 #define _ULL(x) (_AC(x, ULL))
 #define _BITUL(x) (_UL(1) << (x))
 #define _BITULL(x) (_ULL(1) << (x))
-#define __ALIGN_KERNEL(x,a) __ALIGN_KERNEL_MASK(x, (typeof(x)) (a) - 1)
+#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))
 #endif
diff --git a/libc/kernel/uapi/linux/counter.h b/libc/kernel/uapi/linux/counter.h
index f986365..e986601 100644
--- a/libc/kernel/uapi/linux/counter.h
+++ b/libc/kernel/uapi/linux/counter.h
@@ -71,6 +71,12 @@
   COUNTER_COUNT_MODE_RANGE_LIMIT,
   COUNTER_COUNT_MODE_NON_RECYCLE,
   COUNTER_COUNT_MODE_MODULO_N,
+  COUNTER_COUNT_MODE_INTERRUPT_ON_TERMINAL_COUNT,
+  COUNTER_COUNT_MODE_HARDWARE_RETRIGGERABLE_ONESHOT,
+  COUNTER_COUNT_MODE_RATE_GENERATOR,
+  COUNTER_COUNT_MODE_SQUARE_WAVE_MODE,
+  COUNTER_COUNT_MODE_SOFTWARE_TRIGGERED_STROBE,
+  COUNTER_COUNT_MODE_HARDWARE_TRIGGERED_STROBE,
 };
 enum counter_function {
   COUNTER_FUNCTION_INCREASE,
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 5a0a34e..a45ab14 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -21,19 +21,27 @@
 #include <linux/types.h>
 #define CXL_MEM_QUERY_COMMANDS _IOR(0xCE, 1, struct cxl_mem_query_commands)
 #define CXL_MEM_SEND_COMMAND _IOWR(0xCE, 2, struct cxl_send_command)
-#define CXL_CMDS ___C(INVALID, "Invalid Command"), ___C(IDENTIFY, "Identify Command"), ___C(RAW, "Raw device command"), ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), ___C(GET_FW_INFO, "Get FW Info"), ___C(GET_PARTITION_INFO, "Get Partition Information"), ___C(GET_LSA, "Get Label Storage Area"), ___C(GET_HEALTH_INFO, "Get Health Info"), ___C(GET_LOG, "Get Log"), ___C(SET_PARTITION_INFO, "Set Partition Information"), ___C(SET_LSA, "Set Label Storage Area"), ___C(GET_ALERT_CONFIG, "Get Alert Configuration"), ___C(SET_ALERT_CONFIG, "Set Alert Configuration"), ___C(GET_SHUTDOWN_STATE, "Get Shutdown State"), ___C(SET_SHUTDOWN_STATE, "Set Shutdown State"), ___C(GET_POISON, "Get Poison List"), ___C(INJECT_POISON, "Inject Poison"), ___C(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___C(SCAN_MEDIA, "Scan Media"), ___C(GET_SCAN_MEDIA, "Get Scan Media Results"), ___C(MAX, "invalid / last command")
+#define CXL_CMDS ___C(INVALID, "Invalid Command"), ___C(IDENTIFY, "Identify Command"), ___C(RAW, "Raw device command"), ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), ___C(GET_FW_INFO, "Get FW Info"), ___C(GET_PARTITION_INFO, "Get Partition Information"), ___C(GET_LSA, "Get Label Storage Area"), ___C(GET_HEALTH_INFO, "Get Health Info"), ___C(GET_LOG, "Get Log"), ___C(SET_PARTITION_INFO, "Set Partition Information"), ___C(SET_LSA, "Set Label Storage Area"), ___C(GET_ALERT_CONFIG, "Get Alert Configuration"), ___C(SET_ALERT_CONFIG, "Set Alert Configuration"), ___C(GET_SHUTDOWN_STATE, "Get Shutdown State"), ___C(SET_SHUTDOWN_STATE, "Set Shutdown State"), ___DEPRECATED(GET_POISON, "Get Poison List"), ___DEPRECATED(INJECT_POISON, "Inject Poison"), ___DEPRECATED(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___DEPRECATED(SCAN_MEDIA, "Scan Media"), ___DEPRECATED(GET_SCAN_MEDIA, "Get Scan Media Results"), ___C(MAX, "invalid / last command")
 #define ___C(a,b) CXL_MEM_COMMAND_ID_ ##a
+#define ___DEPRECATED(a,b) CXL_MEM_DEPRECATED_ID_ ##a
 enum {
   CXL_CMDS
 };
 #undef ___C
+#undef ___DEPRECATED
 #define ___C(a,b) { b }
+#define ___DEPRECATED(a,b) { "Deprecated " b }
 static const struct {
   const char * name;
 } cxl_command_names[] __attribute__((__unused__)) = {
   CXL_CMDS
 };
 #undef ___C
+#undef ___DEPRECATED
+#define ___C(a,b) (0)
+#define ___DEPRECATED(a,b) (1)
+#undef ___C
+#undef ___DEPRECATED
 struct cxl_command_info {
   __u32 id;
   __u32 flags;
diff --git a/libc/kernel/uapi/linux/dlm_netlink.h b/libc/kernel/uapi/linux/dlm_netlink.h
deleted file mode 100644
index 0c655fa..0000000
--- a/libc/kernel/uapi/linux/dlm_netlink.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _DLM_NETLINK_H
-#define _DLM_NETLINK_H
-#include <linux/types.h>
-#include <linux/dlmconstants.h>
-enum {
-  DLM_STATUS_WAITING = 1,
-  DLM_STATUS_GRANTED = 2,
-  DLM_STATUS_CONVERT = 3,
-};
-#define DLM_LOCK_DATA_VERSION 1
-struct dlm_lock_data {
-  __u16 version;
-  __u32 lockspace_id;
-  int nodeid;
-  int ownpid;
-  __u32 id;
-  __u32 remid;
-  __u64 xid;
-  __s8 status;
-  __s8 grmode;
-  __s8 rqmode;
-  unsigned long timestamp;
-  int resource_namelen;
-  char resource_name[DLM_RESNAME_MAXLEN];
-};
-enum {
-  DLM_CMD_UNSPEC = 0,
-  DLM_CMD_HELLO,
-  DLM_CMD_TIMEOUT,
-  __DLM_CMD_MAX,
-};
-#define DLM_CMD_MAX (__DLM_CMD_MAX - 1)
-enum {
-  DLM_TYPE_UNSPEC = 0,
-  DLM_TYPE_LOCK,
-  __DLM_TYPE_MAX,
-};
-#define DLM_TYPE_MAX (__DLM_TYPE_MAX - 1)
-#define DLM_GENL_VERSION 0x1
-#define DLM_GENL_NAME "DLM"
-#endif
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index f0ff78c..76e331f 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -106,9 +106,9 @@
 #define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
 #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 #define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 47
+#define DM_VERSION_MINOR 48
 #define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2022-07-28)"
+#define DM_VERSION_EXTRA "-ioctl(2023-03-01)"
 #define DM_READONLY_FLAG (1 << 0)
 #define DM_SUSPEND_FLAG (1 << 1)
 #define DM_PERSISTENT_DEV_FLAG (1 << 3)
diff --git a/libc/kernel/uapi/linux/dvb/frontend.h b/libc/kernel/uapi/linux/dvb/frontend.h
index 2ea7d9d..8bd90c4 100644
--- a/libc/kernel/uapi/linux/dvb/frontend.h
+++ b/libc/kernel/uapi/linux/dvb/frontend.h
@@ -138,6 +138,10 @@
   FEC_28_45,
   FEC_32_45,
   FEC_77_90,
+  FEC_11_45,
+  FEC_4_15,
+  FEC_14_45,
+  FEC_7_15,
 };
 enum fe_modulation {
   QPSK,
diff --git a/libc/kernel/uapi/linux/dvb/version.h b/libc/kernel/uapi/linux/dvb/version.h
index 47c8c74..8a32239 100644
--- a/libc/kernel/uapi/linux/dvb/version.h
+++ b/libc/kernel/uapi/linux/dvb/version.h
@@ -19,5 +19,5 @@
 #ifndef _DVBVERSION_H_
 #define _DVBVERSION_H_
 #define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 11
+#define DVB_API_VERSION_MINOR 12
 #endif
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index e4901d1..7eb29df 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -335,6 +335,8 @@
 #define NT_PPC_TM_CPPR 0x10e
 #define NT_PPC_TM_CDSCR 0x10f
 #define NT_PPC_PKEY 0x110
+#define NT_PPC_DEXCR 0x111
+#define NT_PPC_HASHKEYR 0x112
 #define NT_386_TLS 0x200
 #define NT_386_IOPERM 0x201
 #define NT_X86_XSTATE 0x202
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index f1ef896..246ab8a 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -277,6 +277,8 @@
   ETHTOOL_A_RINGS_CQE_SIZE,
   ETHTOOL_A_RINGS_TX_PUSH,
   ETHTOOL_A_RINGS_RX_PUSH,
+  ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
+  ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
   __ETHTOOL_A_RINGS_CNT,
   ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
 };
@@ -576,7 +578,7 @@
   ETHTOOL_A_STATS_GRP_HIST_BKT_HI,
   ETHTOOL_A_STATS_GRP_HIST_VAL,
   __ETHTOOL_A_STATS_GRP_CNT,
-  ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_CNT - 1)
+  ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_GRP_CNT - 1)
 };
 enum {
   ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR,
diff --git a/libc/kernel/uapi/linux/eventfd.h b/libc/kernel/uapi/linux/eventfd.h
new file mode 100644
index 0000000..e4b41d8
--- /dev/null
+++ b/libc/kernel/uapi/linux/eventfd.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_EVENTFD_H
+#define _UAPI_LINUX_EVENTFD_H
+#include <linux/fcntl.h>
+#define EFD_SEMAPHORE (1 << 0)
+#define EFD_CLOEXEC O_CLOEXEC
+#define EFD_NONBLOCK O_NONBLOCK
+#endif
diff --git a/libc/kernel/uapi/linux/ext4.h b/libc/kernel/uapi/linux/ext4.h
new file mode 100644
index 0000000..70a3b1a
--- /dev/null
+++ b/libc/kernel/uapi/linux/ext4.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_EXT4_H
+#define _UAPI_LINUX_EXT4_H
+#include <linux/fiemap.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define EXT4_IOC_GETVERSION _IOR('f', 3, long)
+#define EXT4_IOC_SETVERSION _IOW('f', 4, long)
+#define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION
+#define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION
+#define EXT4_IOC_GETRSVSZ _IOR('f', 5, long)
+#define EXT4_IOC_SETRSVSZ _IOW('f', 6, long)
+#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
+#define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
+#define EXT4_IOC_MIGRATE _IO('f', 9)
+#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12)
+#define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent)
+#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
+#define EXT4_IOC_SWAP_BOOT _IO('f', 17)
+#define EXT4_IOC_PRECACHE_EXTENTS _IO('f', 18)
+#define EXT4_IOC_CLEAR_ES_CACHE _IO('f', 40)
+#define EXT4_IOC_GETSTATE _IOW('f', 41, __u32)
+#define EXT4_IOC_GET_ES_CACHE _IOWR('f', 42, struct fiemap)
+#define EXT4_IOC_CHECKPOINT _IOW('f', 43, __u32)
+#define EXT4_IOC_GETFSUUID _IOR('f', 44, struct fsuuid)
+#define EXT4_IOC_SETFSUUID _IOW('f', 44, struct fsuuid)
+#define EXT4_IOC_SHUTDOWN _IOR('X', 125, __u32)
+#define EXT4_IOC32_GETVERSION _IOR('f', 3, int)
+#define EXT4_IOC32_SETVERSION _IOW('f', 4, int)
+#define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int)
+#define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int)
+#define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)
+#define EXT4_IOC32_GROUP_ADD _IOW('f', 8, struct compat_ext4_new_group_input)
+#define EXT4_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION
+#define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION
+#define EXT4_STATE_FLAG_EXT_PRECACHED 0x00000001
+#define EXT4_STATE_FLAG_NEW 0x00000002
+#define EXT4_STATE_FLAG_NEWENTRY 0x00000004
+#define EXT4_STATE_FLAG_DA_ALLOC_CLOSE 0x00000008
+#define EXT4_IOC_CHECKPOINT_FLAG_DISCARD 0x1
+#define EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT 0x2
+#define EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN 0x4
+#define EXT4_IOC_CHECKPOINT_FLAG_VALID (EXT4_IOC_CHECKPOINT_FLAG_DISCARD | EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT | EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN)
+struct fsuuid {
+  __u32 fsu_len;
+  __u32 fsu_flags;
+  __u8 fsu_uuid[];
+};
+struct move_extent {
+  __u32 reserved;
+  __u32 donor_fd;
+  __u64 orig_start;
+  __u64 donor_start;
+  __u64 len;
+  __u64 moved_len;
+};
+#define EXT4_GOING_FLAGS_DEFAULT 0x0
+#define EXT4_GOING_FLAGS_LOGFLUSH 0x1
+#define EXT4_GOING_FLAGS_NOLOGFLUSH 0x2
+struct ext4_new_group_input {
+  __u32 group;
+  __u64 block_bitmap;
+  __u64 inode_bitmap;
+  __u64 inode_table;
+  __u32 blocks_count;
+  __u16 reserved_blocks;
+  __u16 unused;
+};
+#define EXT4_FIEMAP_EXTENT_HOLE 0x08000000
+#endif
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index 05393d5..5ca840b 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -65,4 +65,5 @@
 #define AT_STATX_FORCE_SYNC 0x2000
 #define AT_STATX_DONT_SYNC 0x4000
 #define AT_RECURSIVE 0x8000
+#define AT_HANDLE_FID AT_REMOVEDIR
 #endif
diff --git a/libc/kernel/uapi/linux/firewire-cdev.h b/libc/kernel/uapi/linux/firewire-cdev.h
index a54191c..73a6a9b 100644
--- a/libc/kernel/uapi/linux/firewire-cdev.h
+++ b/libc/kernel/uapi/linux/firewire-cdev.h
@@ -31,6 +31,10 @@
 #define FW_CDEV_EVENT_PHY_PACKET_SENT 0x07
 #define FW_CDEV_EVENT_PHY_PACKET_RECEIVED 0x08
 #define FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL 0x09
+#define FW_CDEV_EVENT_REQUEST3 0x0a
+#define FW_CDEV_EVENT_RESPONSE2 0x0b
+#define FW_CDEV_EVENT_PHY_PACKET_SENT2 0x0c
+#define FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 0x0d
 struct fw_cdev_event_common {
   __u64 closure;
   __u32 type;
@@ -52,6 +56,16 @@
   __u32 length;
   __u32 data[];
 };
+struct fw_cdev_event_response2 {
+  __u64 closure;
+  __u32 type;
+  __u32 rcode;
+  __u32 length;
+  __u32 request_tstamp;
+  __u32 response_tstamp;
+  __u32 padding;
+  __u32 data[];
+};
 struct fw_cdev_event_request {
   __u64 closure;
   __u32 type;
@@ -74,6 +88,21 @@
   __u32 length;
   __u32 data[];
 };
+struct fw_cdev_event_request3 {
+  __u64 closure;
+  __u32 type;
+  __u32 tcode;
+  __u64 offset;
+  __u32 source_node_id;
+  __u32 destination_node_id;
+  __u32 card;
+  __u32 generation;
+  __u32 handle;
+  __u32 length;
+  __u32 tstamp;
+  __u32 padding;
+  __u32 data[];
+};
 struct fw_cdev_event_iso_interrupt {
   __u64 closure;
   __u32 type;
@@ -100,6 +129,14 @@
   __u32 length;
   __u32 data[];
 };
+struct fw_cdev_event_phy_packet2 {
+  __u64 closure;
+  __u32 type;
+  __u32 rcode;
+  __u32 length;
+  __u32 tstamp;
+  __u32 data[];
+};
 union fw_cdev_event {
   struct fw_cdev_event_common common;
   struct fw_cdev_event_bus_reset bus_reset;
@@ -110,6 +147,9 @@
   struct fw_cdev_event_iso_interrupt_mc iso_interrupt_mc;
   struct fw_cdev_event_iso_resource iso_resource;
   struct fw_cdev_event_phy_packet phy_packet;
+  struct fw_cdev_event_request3 request3;
+  struct fw_cdev_event_response2 response2;
+  struct fw_cdev_event_phy_packet2 phy_packet2;
 };
 #define FW_CDEV_IOC_GET_INFO _IOWR('#', 0x00, struct fw_cdev_get_info)
 #define FW_CDEV_IOC_SEND_REQUEST _IOW('#', 0x01, struct fw_cdev_send_request)
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index c3668e7..ce4424e 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -112,6 +112,7 @@
 #define FUSE_SECURITY_CTX (1ULL << 32)
 #define FUSE_HAS_INODE_DAX (1ULL << 33)
 #define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
+#define FUSE_HAS_EXPIRE_ONLY (1ULL << 35)
 #if FUSE_KERNEL_VERSION > 7 || FUSE_KERNEL_VERSION == 7 && FUSE_KERNEL_MINOR_VERSION >= 36
 #define FUSE_PASSTHROUGH (1ULL << 63)
 #else
diff --git a/libc/kernel/uapi/linux/gsmmux.h b/libc/kernel/uapi/linux/gsmmux.h
index 6ddf1b9..8ff29fd 100644
--- a/libc/kernel/uapi/linux/gsmmux.h
+++ b/libc/kernel/uapi/linux/gsmmux.h
@@ -49,8 +49,20 @@
 #define GSMIOC_GETFIRST _IOR('G', 4, __u32)
 struct gsm_config_ext {
   __u32 keep_alive;
-  __u32 reserved[7];
+  __u32 wait_config;
+  __u32 reserved[6];
 };
 #define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext)
 #define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext)
+struct gsm_dlci_config {
+  __u32 channel;
+  __u32 adaption;
+  __u32 mtu;
+  __u32 priority;
+  __u32 i;
+  __u32 k;
+  __u32 reserved[8];
+};
+#define GSMIOC_GETCONF_DLCI _IOWR('G', 7, struct gsm_dlci_config)
+#define GSMIOC_SETCONF_DLCI _IOW('G', 8, struct gsm_dlci_config)
 #endif
diff --git a/libc/kernel/uapi/linux/handshake.h b/libc/kernel/uapi/linux/handshake.h
new file mode 100644
index 0000000..e9923ae
--- /dev/null
+++ b/libc/kernel/uapi/linux/handshake.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_HANDSHAKE_H
+#define _UAPI_LINUX_HANDSHAKE_H
+#define HANDSHAKE_FAMILY_NAME "handshake"
+#define HANDSHAKE_FAMILY_VERSION 1
+enum handshake_handler_class {
+  HANDSHAKE_HANDLER_CLASS_NONE,
+  HANDSHAKE_HANDLER_CLASS_TLSHD,
+  HANDSHAKE_HANDLER_CLASS_MAX,
+};
+enum handshake_msg_type {
+  HANDSHAKE_MSG_TYPE_UNSPEC,
+  HANDSHAKE_MSG_TYPE_CLIENTHELLO,
+  HANDSHAKE_MSG_TYPE_SERVERHELLO,
+};
+enum handshake_auth {
+  HANDSHAKE_AUTH_UNSPEC,
+  HANDSHAKE_AUTH_UNAUTH,
+  HANDSHAKE_AUTH_PSK,
+  HANDSHAKE_AUTH_X509,
+};
+enum {
+  HANDSHAKE_A_X509_CERT = 1,
+  HANDSHAKE_A_X509_PRIVKEY,
+  __HANDSHAKE_A_X509_MAX,
+  HANDSHAKE_A_X509_MAX = (__HANDSHAKE_A_X509_MAX - 1)
+};
+enum {
+  HANDSHAKE_A_ACCEPT_SOCKFD = 1,
+  HANDSHAKE_A_ACCEPT_HANDLER_CLASS,
+  HANDSHAKE_A_ACCEPT_MESSAGE_TYPE,
+  HANDSHAKE_A_ACCEPT_TIMEOUT,
+  HANDSHAKE_A_ACCEPT_AUTH_MODE,
+  HANDSHAKE_A_ACCEPT_PEER_IDENTITY,
+  HANDSHAKE_A_ACCEPT_CERTIFICATE,
+  HANDSHAKE_A_ACCEPT_PEERNAME,
+  __HANDSHAKE_A_ACCEPT_MAX,
+  HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1)
+};
+enum {
+  HANDSHAKE_A_DONE_STATUS = 1,
+  HANDSHAKE_A_DONE_SOCKFD,
+  HANDSHAKE_A_DONE_REMOTE_AUTH,
+  __HANDSHAKE_A_DONE_MAX,
+  HANDSHAKE_A_DONE_MAX = (__HANDSHAKE_A_DONE_MAX - 1)
+};
+enum {
+  HANDSHAKE_CMD_READY = 1,
+  HANDSHAKE_CMD_ACCEPT,
+  HANDSHAKE_CMD_DONE,
+  __HANDSHAKE_CMD_MAX,
+  HANDSHAKE_CMD_MAX = (__HANDSHAKE_CMD_MAX - 1)
+};
+#define HANDSHAKE_MCGRP_NONE "none"
+#define HANDSHAKE_MCGRP_TLSHD "tlshd"
+#endif
diff --git a/libc/kernel/uapi/linux/hw_breakpoint.h b/libc/kernel/uapi/linux/hw_breakpoint.h
index 74acd53..416d746 100644
--- a/libc/kernel/uapi/linux/hw_breakpoint.h
+++ b/libc/kernel/uapi/linux/hw_breakpoint.h
@@ -36,9 +36,4 @@
   HW_BREAKPOINT_X = 4,
   HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
 };
-enum bp_type_idx {
-  TYPE_INST = 0,
-  TYPE_DATA = 1,
-  TYPE_MAX
-};
 #endif
diff --git a/libc/kernel/uapi/linux/idxd.h b/libc/kernel/uapi/linux/idxd.h
index 01c62f2..f8cfc11 100644
--- a/libc/kernel/uapi/linux/idxd.h
+++ b/libc/kernel/uapi/linux/idxd.h
@@ -39,6 +39,7 @@
   IDXD_SCMD_WQ_NO_PRIV = 0x800f0000,
   IDXD_SCMD_WQ_IRQ_ERR = 0x80100000,
   IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000,
+  IDXD_SCMD_DEV_EVL_ERR = 0x80120000,
 };
 #define IDXD_SCMD_SOFTERR_MASK 0x80000000
 #define IDXD_SCMD_SOFTERR_SHIFT 16
@@ -74,12 +75,14 @@
   DSA_OPCODE_CR_DELTA,
   DSA_OPCODE_AP_DELTA,
   DSA_OPCODE_DUALCAST,
+  DSA_OPCODE_TRANSL_FETCH,
   DSA_OPCODE_CRCGEN = 0x10,
   DSA_OPCODE_COPY_CRC,
   DSA_OPCODE_DIF_CHECK,
   DSA_OPCODE_DIF_INS,
   DSA_OPCODE_DIF_STRP,
   DSA_OPCODE_DIF_UPDT,
+  DSA_OPCODE_DIX_GEN = 0x17,
   DSA_OPCODE_CFLUSH = 0x20,
 };
 enum iax_opcode {
@@ -131,6 +134,8 @@
   DSA_COMP_HW_ERR1,
   DSA_COMP_HW_ERR_DRB,
   DSA_COMP_TRANSLATION_FAIL,
+  DSA_COMP_DRAIN_EVL = 0x26,
+  DSA_COMP_BATCH_EVL_ERR,
 };
 enum iax_completion_status {
   IAX_COMP_NONE = 0,
@@ -164,6 +169,7 @@
 };
 #define DSA_COMP_STATUS_MASK 0x7f
 #define DSA_COMP_STATUS_WRITE 0x80
+#define DSA_COMP_STATUS(status) ((status) & DSA_COMP_STATUS_MASK)
 struct dsa_hw_desc {
   uint32_t pasid : 20;
   uint32_t rsvd : 11;
@@ -176,6 +182,8 @@
     uint64_t rdback_addr;
     uint64_t pattern;
     uint64_t desc_list_addr;
+    uint64_t pattern_lower;
+    uint64_t transl_fetch_addr;
   };
   union {
     uint64_t dst_addr;
@@ -186,6 +194,7 @@
   union {
     uint32_t xfer_size;
     uint32_t desc_count;
+    uint32_t region_size;
   };
   uint16_t int_handle;
   uint16_t rsvd1;
@@ -234,6 +243,20 @@
       uint16_t dest_app_tag_mask;
       uint16_t dest_app_tag_seed;
     };
+    uint64_t pattern_upper;
+    struct {
+      uint64_t transl_fetch_res;
+      uint32_t region_stride;
+    };
+    struct {
+      uint8_t dix_gen_res;
+      uint8_t dest_dif_flags;
+      uint8_t dif_flags;
+      uint8_t dix_gen_res2[13];
+      uint32_t ref_tag_seed;
+      uint16_t app_tag_mask;
+      uint16_t app_tag_seed;
+    };
     uint8_t op_specific[24];
   };
 } __attribute__((packed));
@@ -267,8 +290,12 @@
     uint8_t result;
     uint8_t dif_status;
   };
-  uint16_t rsvd;
-  uint32_t bytes_completed;
+  uint8_t fault_info;
+  uint8_t rsvd;
+  union {
+    uint32_t bytes_completed;
+    uint32_t descs_completed;
+  };
   uint64_t fault_addr;
   union {
     struct {
@@ -296,6 +323,12 @@
       uint16_t dif_upd_dest_app_tag_mask;
       uint16_t dif_upd_dest_app_tag;
     };
+    struct {
+      uint64_t dix_gen_res;
+      uint32_t dix_ref_tag;
+      uint16_t dix_app_tag_mask;
+      uint16_t dix_app_tag;
+    };
     uint8_t op_specific[16];
   };
 } __attribute__((packed));
@@ -305,7 +338,8 @@
 struct iax_completion_record {
   volatile uint8_t status;
   uint8_t error_code;
-  uint16_t rsvd;
+  uint8_t fault_info;
+  uint8_t rsvd;
   uint32_t bytes_completed;
   uint64_t fault_addr;
   uint32_t invalid_flags;
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 48f6345..1f90580 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -437,6 +437,7 @@
   BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
   BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS,
   BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS,
+  BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS,
   __BRIDGE_VLANDB_ENTRY_MAX,
 };
 #define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
@@ -506,6 +507,11 @@
   MDBA_MDB_EATTR_GROUP_MODE,
   MDBA_MDB_EATTR_SOURCE,
   MDBA_MDB_EATTR_RTPROT,
+  MDBA_MDB_EATTR_DST,
+  MDBA_MDB_EATTR_DST_PORT,
+  MDBA_MDB_EATTR_VNI,
+  MDBA_MDB_EATTR_IFINDEX,
+  MDBA_MDB_EATTR_SRC_VNI,
   __MDBA_MDB_EATTR_MAX
 };
 #define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
@@ -581,6 +587,11 @@
   MDBE_ATTR_SRC_LIST,
   MDBE_ATTR_GROUP_MODE,
   MDBE_ATTR_RTPROT,
+  MDBE_ATTR_DST,
+  MDBE_ATTR_DST_PORT,
+  MDBE_ATTR_VNI,
+  MDBE_ATTR_IFINDEX,
+  MDBE_ATTR_SRC_VNI,
   __MDBE_ATTR_MAX,
 };
 #define MDBE_ATTR_MAX (__MDBE_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index fbb933b..e0b504e 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -311,6 +311,7 @@
   IFLA_BRPORT_MAB,
   IFLA_BRPORT_MCAST_N_GROUPS,
   IFLA_BRPORT_MCAST_MAX_GROUPS,
+  IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
   __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -364,6 +365,7 @@
   IFLA_MACVLAN_MACADDR_COUNT,
   IFLA_MACVLAN_BC_QUEUE_LEN,
   IFLA_MACVLAN_BC_QUEUE_LEN_USED,
+  IFLA_MACVLAN_BC_CUTOFF,
   __IFLA_MACVLAN_MAX,
 };
 #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
@@ -521,6 +523,7 @@
   IFLA_VXLAN_TTL_INHERIT,
   IFLA_VXLAN_DF,
   IFLA_VXLAN_VNIFILTER,
+  IFLA_VXLAN_LOCALBYPASS,
   __IFLA_VXLAN_MAX
 };
 #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index 719f596..cb0c804 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -32,7 +32,10 @@
   unsigned short sll_hatype;
   unsigned char sll_pkttype;
   unsigned char sll_halen;
-  unsigned char sll_addr[8];
+  union {
+    unsigned char sll_addr[8];
+    __DECLARE_FLEX_ARRAY(unsigned char, sll_addr_flex);
+  };
 };
 #define PACKET_HOST 0
 #define PACKET_BROADCAST 1
@@ -65,6 +68,7 @@
 #define PACKET_ROLLOVER_STATS 21
 #define PACKET_FANOUT_DATA 22
 #define PACKET_IGNORE_OUTGOING 23
+#define PACKET_VNET_HDR_SZ 24
 #define PACKET_FANOUT_HASH 0
 #define PACKET_FANOUT_LB 1
 #define PACKET_FANOUT_CPU 2
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 3947d5a..3e98b79 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -142,6 +142,7 @@
 #define IP_MULTICAST_ALL 49
 #define IP_UNICAST_IF 50
 #define IP_LOCAL_PORT_RANGE 51
+#define IP_PROTOCOL 52
 #define MCAST_EXCLUDE 0
 #define MCAST_INCLUDE 1
 #define IP_DEFAULT_MULTICAST_TTL 1
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index a2d4f5f..32c6c7b 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -118,6 +118,8 @@
 #define IORING_SETUP_CQE32 (1U << 11)
 #define IORING_SETUP_SINGLE_ISSUER (1U << 12)
 #define IORING_SETUP_DEFER_TASKRUN (1U << 13)
+#define IORING_SETUP_NO_MMAP (1U << 14)
+#define IORING_SETUP_REGISTERED_FD_ONLY (1U << 15)
 enum io_uring_op {
   IORING_OP_NOP,
   IORING_OP_READV,
@@ -171,6 +173,7 @@
   IORING_OP_LAST,
 };
 #define IORING_URING_CMD_FIXED (1U << 0)
+#define IORING_URING_CMD_POLLED (1U << 31)
 #define IORING_FSYNC_DATASYNC (1U << 0)
 #define IORING_TIMEOUT_ABS (1U << 0)
 #define IORING_TIMEOUT_UPDATE (1U << 1)
@@ -178,6 +181,7 @@
 #define IORING_TIMEOUT_REALTIME (1U << 3)
 #define IORING_LINK_TIMEOUT_UPDATE (1U << 4)
 #define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5)
+#define IORING_TIMEOUT_MULTISHOT (1U << 6)
 #define IORING_TIMEOUT_CLOCK_MASK (IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME)
 #define IORING_TIMEOUT_UPDATE_MASK (IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE)
 #define SPLICE_F_FD_IN_FIXED (1U << 31)
@@ -217,6 +221,9 @@
 #define IORING_OFF_SQ_RING 0ULL
 #define IORING_OFF_CQ_RING 0x8000000ULL
 #define IORING_OFF_SQES 0x10000000ULL
+#define IORING_OFF_PBUF_RING 0x80000000ULL
+#define IORING_OFF_PBUF_SHIFT 16
+#define IORING_OFF_MMAP_MASK 0xf8000000ULL
 struct io_sqring_offsets {
   __u32 head;
   __u32 tail;
@@ -226,7 +233,7 @@
   __u32 dropped;
   __u32 array;
   __u32 resv1;
-  __u64 resv2;
+  __u64 user_addr;
 };
 #define IORING_SQ_NEED_WAKEUP (1U << 0)
 #define IORING_SQ_CQ_OVERFLOW (1U << 1)
@@ -240,7 +247,7 @@
   __u32 cqes;
   __u32 flags;
   __u32 resv1;
-  __u64 resv2;
+  __u64 user_addr;
 };
 #define IORING_CQ_EVENTFD_DISABLED (1U << 0)
 #define IORING_ENTER_GETEVENTS (1U << 0)
@@ -334,17 +341,6 @@
   __u32 nr;
   __u32 resv2;
 };
-struct io_uring_notification_slot {
-  __u64 tag;
-  __u64 resv[3];
-};
-struct io_uring_notification_register {
-  __u32 nr_slots;
-  __u32 resv;
-  __u64 resv2;
-  __u64 data;
-  __u64 resv3;
-};
 #define IORING_REGISTER_FILES_SKIP (- 2)
 #define IO_URING_OP_SUPPORTED (1U << 0)
 struct io_uring_probe_op {
@@ -387,11 +383,14 @@
     __DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
   };
 };
+enum {
+  IOU_PBUF_RING_MMAP = 1,
+};
 struct io_uring_buf_reg {
   __u64 ring_addr;
   __u32 ring_entries;
   __u16 bgid;
-  __u16 pad;
+  __u16 flags;
   __u64 resv[3];
 };
 enum {
diff --git a/libc/kernel/uapi/linux/ioprio.h b/libc/kernel/uapi/linux/ioprio.h
index 7a90d87..c6dc42a 100644
--- a/libc/kernel/uapi/linux/ioprio.h
+++ b/libc/kernel/uapi/linux/ioprio.h
@@ -18,19 +18,25 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_IOPRIO_H
 #define _UAPI_LINUX_IOPRIO_H
+#include <linux/stddef.h>
+#include <linux/types.h>
 #define IOPRIO_CLASS_SHIFT 13
-#define IOPRIO_CLASS_MASK 0x07
+#define IOPRIO_NR_CLASSES 8
+#define IOPRIO_CLASS_MASK (IOPRIO_NR_CLASSES - 1)
 #define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
 #define IOPRIO_PRIO_CLASS(ioprio) (((ioprio) >> IOPRIO_CLASS_SHIFT) & IOPRIO_CLASS_MASK)
 #define IOPRIO_PRIO_DATA(ioprio) ((ioprio) & IOPRIO_PRIO_MASK)
-#define IOPRIO_PRIO_VALUE(class,data) ((((class) & IOPRIO_CLASS_MASK) << IOPRIO_CLASS_SHIFT) | ((data) & IOPRIO_PRIO_MASK))
 enum {
-  IOPRIO_CLASS_NONE,
-  IOPRIO_CLASS_RT,
-  IOPRIO_CLASS_BE,
-  IOPRIO_CLASS_IDLE,
+  IOPRIO_CLASS_NONE = 0,
+  IOPRIO_CLASS_RT = 1,
+  IOPRIO_CLASS_BE = 2,
+  IOPRIO_CLASS_IDLE = 3,
+  IOPRIO_CLASS_INVALID = 7,
 };
-#define IOPRIO_NR_LEVELS 8
+#define IOPRIO_LEVEL_NR_BITS 3
+#define IOPRIO_NR_LEVELS (1 << IOPRIO_LEVEL_NR_BITS)
+#define IOPRIO_LEVEL_MASK (IOPRIO_NR_LEVELS - 1)
+#define IOPRIO_PRIO_LEVEL(ioprio) ((ioprio) & IOPRIO_LEVEL_MASK)
 #define IOPRIO_BE_NR IOPRIO_NR_LEVELS
 enum {
   IOPRIO_WHO_PROCESS = 1,
@@ -39,4 +45,22 @@
 };
 #define IOPRIO_NORM 4
 #define IOPRIO_BE_NORM IOPRIO_NORM
+#define IOPRIO_HINT_SHIFT IOPRIO_LEVEL_NR_BITS
+#define IOPRIO_HINT_NR_BITS 10
+#define IOPRIO_NR_HINTS (1 << IOPRIO_HINT_NR_BITS)
+#define IOPRIO_HINT_MASK (IOPRIO_NR_HINTS - 1)
+#define IOPRIO_PRIO_HINT(ioprio) (((ioprio) >> IOPRIO_HINT_SHIFT) & IOPRIO_HINT_MASK)
+enum {
+  IOPRIO_HINT_NONE = 0,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_1 = 1,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_2 = 2,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_3 = 3,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_4 = 4,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_5 = 5,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_6 = 6,
+  IOPRIO_HINT_DEV_DURATION_LIMIT_7 = 7,
+};
+#define IOPRIO_BAD_VALUE(val,max) ((val) < 0 || (val) >= (max))
+#define IOPRIO_PRIO_VALUE(class,level) ioprio_value(class, level, IOPRIO_HINT_NONE)
+#define IOPRIO_PRIO_VALUE_HINT(class,level,hint) ioprio_value(class, level, hint)
 #endif
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index d62d269..d8fe3cd 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -62,7 +62,7 @@
 struct rt0_hdr {
   struct ipv6_rt_hdr rt_hdr;
   __u32 reserved;
-  struct in6_addr addr[0];
+  struct in6_addr addr[];
 #define rt0_type rt_hdr.type
 };
 struct rt2_hdr {
diff --git a/libc/kernel/uapi/linux/isst_if.h b/libc/kernel/uapi/linux/isst_if.h
index 322f70d..9d03b7a 100644
--- a/libc/kernel/uapi/linux/isst_if.h
+++ b/libc/kernel/uapi/linux/isst_if.h
@@ -67,10 +67,136 @@
   __u32 cmd_count;
   struct isst_if_msr_cmd msr_cmd[1];
 };
+struct isst_core_power {
+  __u8 get_set;
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 enable;
+  __u8 supported;
+  __u8 priority_type;
+};
+struct isst_clos_param {
+  __u8 get_set;
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 clos;
+  __u16 min_freq_mhz;
+  __u16 max_freq_mhz;
+  __u8 prop_prio;
+};
+struct isst_if_clos_assoc {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 logical_cpu;
+  __u16 clos;
+};
+struct isst_if_clos_assoc_cmds {
+  __u16 cmd_count;
+  __u16 get_set;
+  __u16 punit_cpu_map;
+  struct isst_if_clos_assoc assoc_info[1];
+};
+struct isst_tpmi_instance_count {
+  __u8 socket_id;
+  __u8 count;
+  __u16 valid_mask;
+};
+struct isst_perf_level_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 max_level;
+  __u8 feature_rev;
+  __u8 level_mask;
+  __u8 current_level;
+  __u8 feature_state;
+  __u8 locked;
+  __u8 enabled;
+  __u8 sst_tf_support;
+  __u8 sst_bf_support;
+};
+struct isst_perf_level_control {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 level;
+};
+struct isst_perf_feature_control {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 feature;
+};
+#define TRL_MAX_BUCKETS 8
+#define TRL_MAX_LEVELS 6
+struct isst_perf_level_data_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 level;
+  __u16 tdp_ratio;
+  __u16 base_freq_mhz;
+  __u16 base_freq_avx2_mhz;
+  __u16 base_freq_avx512_mhz;
+  __u16 base_freq_amx_mhz;
+  __u16 thermal_design_power_w;
+  __u16 tjunction_max_c;
+  __u16 max_memory_freq_mhz;
+  __u16 cooling_type;
+  __u16 p0_freq_mhz;
+  __u16 p1_freq_mhz;
+  __u16 pn_freq_mhz;
+  __u16 pm_freq_mhz;
+  __u16 p0_fabric_freq_mhz;
+  __u16 p1_fabric_freq_mhz;
+  __u16 pn_fabric_freq_mhz;
+  __u16 pm_fabric_freq_mhz;
+  __u16 max_buckets;
+  __u16 max_trl_levels;
+  __u16 bucket_core_counts[TRL_MAX_BUCKETS];
+  __u16 trl_freq_mhz[TRL_MAX_LEVELS][TRL_MAX_BUCKETS];
+};
+struct isst_perf_level_cpu_mask {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 level;
+  __u8 punit_cpu_map;
+  __u64 mask;
+  __u16 cpu_buffer_size;
+  __s8 cpu_buffer[1];
+};
+struct isst_base_freq_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 level;
+  __u16 high_base_freq_mhz;
+  __u16 low_base_freq_mhz;
+  __u16 tjunction_max_c;
+  __u16 thermal_design_power_w;
+};
+struct isst_turbo_freq_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 level;
+  __u16 max_clip_freqs;
+  __u16 max_buckets;
+  __u16 max_trl_levels;
+  __u16 lp_clip_freq_mhz[TRL_MAX_LEVELS];
+  __u16 bucket_core_counts[TRL_MAX_BUCKETS];
+  __u16 trl_freq_mhz[TRL_MAX_LEVELS][TRL_MAX_BUCKETS];
+};
 #define ISST_IF_MAGIC 0xFE
 #define ISST_IF_GET_PLATFORM_INFO _IOR(ISST_IF_MAGIC, 0, struct isst_if_platform_info *)
 #define ISST_IF_GET_PHY_ID _IOWR(ISST_IF_MAGIC, 1, struct isst_if_cpu_map *)
 #define ISST_IF_IO_CMD _IOW(ISST_IF_MAGIC, 2, struct isst_if_io_regs *)
 #define ISST_IF_MBOX_COMMAND _IOWR(ISST_IF_MAGIC, 3, struct isst_if_mbox_cmds *)
 #define ISST_IF_MSR_COMMAND _IOWR(ISST_IF_MAGIC, 4, struct isst_if_msr_cmds *)
+#define ISST_IF_COUNT_TPMI_INSTANCES _IOR(ISST_IF_MAGIC, 5, struct isst_tpmi_instance_count *)
+#define ISST_IF_CORE_POWER_STATE _IOWR(ISST_IF_MAGIC, 6, struct isst_core_power *)
+#define ISST_IF_CLOS_PARAM _IOWR(ISST_IF_MAGIC, 7, struct isst_clos_param *)
+#define ISST_IF_CLOS_ASSOC _IOWR(ISST_IF_MAGIC, 8, struct isst_if_clos_assoc_cmds *)
+#define ISST_IF_PERF_LEVELS _IOWR(ISST_IF_MAGIC, 9, struct isst_perf_level_info *)
+#define ISST_IF_PERF_SET_LEVEL _IOW(ISST_IF_MAGIC, 10, struct isst_perf_level_control *)
+#define ISST_IF_PERF_SET_FEATURE _IOW(ISST_IF_MAGIC, 11, struct isst_perf_feature_control *)
+#define ISST_IF_GET_PERF_LEVEL_INFO _IOR(ISST_IF_MAGIC, 12, struct isst_perf_level_data_info *)
+#define ISST_IF_GET_PERF_LEVEL_CPU_MASK _IOR(ISST_IF_MAGIC, 13, struct isst_perf_level_cpu_mask *)
+#define ISST_IF_GET_BASE_FREQ_INFO _IOR(ISST_IF_MAGIC, 14, struct isst_base_freq_info *)
+#define ISST_IF_GET_BASE_FREQ_CPU_MASK _IOR(ISST_IF_MAGIC, 15, struct isst_perf_level_cpu_mask *)
+#define ISST_IF_GET_TURBO_FREQ_INFO _IOR(ISST_IF_MAGIC, 16, struct isst_turbo_freq_info *)
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index d21e0fc..1094182 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -21,7 +21,7 @@
 #include <drm/drm.h>
 #include <linux/ioctl.h>
 #define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 11
+#define KFD_IOCTL_MINOR_VERSION 14
 struct kfd_ioctl_get_version_args {
   __u32 major_version;
   __u32 minor_version;
@@ -77,6 +77,31 @@
   __u32 gpu_id;
   __u32 pad;
 };
+struct kfd_dbg_device_info_entry {
+  __u64 exception_status;
+  __u64 lds_base;
+  __u64 lds_limit;
+  __u64 scratch_base;
+  __u64 scratch_limit;
+  __u64 gpuvm_base;
+  __u64 gpuvm_limit;
+  __u32 gpu_id;
+  __u32 location_id;
+  __u32 vendor_id;
+  __u32 device_id;
+  __u32 revision_id;
+  __u32 subsystem_vendor_id;
+  __u32 subsystem_device_id;
+  __u32 fw_version;
+  __u32 gfx_target_version;
+  __u32 simd_count;
+  __u32 max_waves_per_simd;
+  __u32 array_count;
+  __u32 simd_arrays_per_engine;
+  __u32 num_xcc;
+  __u32 capability;
+  __u32 debug_prop;
+};
 #define KFD_IOC_CACHE_POLICY_COHERENT 0
 #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
 struct kfd_ioctl_set_memory_policy_args {
@@ -198,10 +223,14 @@
   __u32 memory_lost;
   __u32 gpu_id;
 };
+struct kfd_hsa_signal_event_data {
+  __u64 last_event_age;
+};
 struct kfd_event_data {
   union {
     struct kfd_hsa_memory_exception_data memory_exception_data;
     struct kfd_hsa_hw_exception_data hw_exception_data;
+    struct kfd_hsa_signal_event_data signal_event_data;
   };
   __u64 kfd_event_data_ext;
   __u32 event_id;
@@ -294,6 +323,11 @@
   __u32 gpu_id;
   __u32 dmabuf_fd;
 };
+struct kfd_ioctl_export_dmabuf_args {
+  __u64 handle;
+  __u32 flags;
+  __u32 dmabuf_fd;
+};
 enum kfd_smi_event {
   KFD_SMI_EVENT_NONE = 0,
   KFD_SMI_EVENT_VMFAULT = 1,
@@ -411,6 +445,230 @@
 struct kfd_ioctl_set_xnack_mode_args {
   __s32 xnack_enabled;
 };
+enum kfd_dbg_trap_override_mode {
+  KFD_DBG_TRAP_OVERRIDE_OR = 0,
+  KFD_DBG_TRAP_OVERRIDE_REPLACE = 1
+};
+enum kfd_dbg_trap_mask {
+  KFD_DBG_TRAP_MASK_FP_INVALID = 1,
+  KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL = 2,
+  KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO = 4,
+  KFD_DBG_TRAP_MASK_FP_OVERFLOW = 8,
+  KFD_DBG_TRAP_MASK_FP_UNDERFLOW = 16,
+  KFD_DBG_TRAP_MASK_FP_INEXACT = 32,
+  KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO = 64,
+  KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH = 128,
+  KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION = 256,
+  KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START = (1 << 30),
+  KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END = (1 << 31)
+};
+enum kfd_dbg_trap_wave_launch_mode {
+  KFD_DBG_TRAP_WAVE_LAUNCH_MODE_NORMAL = 0,
+  KFD_DBG_TRAP_WAVE_LAUNCH_MODE_HALT = 1,
+  KFD_DBG_TRAP_WAVE_LAUNCH_MODE_DEBUG = 3
+};
+enum kfd_dbg_trap_address_watch_mode {
+  KFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ = 0,
+  KFD_DBG_TRAP_ADDRESS_WATCH_MODE_NONREAD = 1,
+  KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ATOMIC = 2,
+  KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ALL = 3
+};
+enum kfd_dbg_trap_flags {
+  KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP = 1,
+};
+enum kfd_dbg_trap_exception_code {
+  EC_NONE = 0,
+  EC_QUEUE_WAVE_ABORT = 1,
+  EC_QUEUE_WAVE_TRAP = 2,
+  EC_QUEUE_WAVE_MATH_ERROR = 3,
+  EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION = 4,
+  EC_QUEUE_WAVE_MEMORY_VIOLATION = 5,
+  EC_QUEUE_WAVE_APERTURE_VIOLATION = 6,
+  EC_QUEUE_PACKET_DISPATCH_DIM_INVALID = 16,
+  EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID = 17,
+  EC_QUEUE_PACKET_DISPATCH_CODE_INVALID = 18,
+  EC_QUEUE_PACKET_RESERVED = 19,
+  EC_QUEUE_PACKET_UNSUPPORTED = 20,
+  EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID = 21,
+  EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID = 22,
+  EC_QUEUE_PACKET_VENDOR_UNSUPPORTED = 23,
+  EC_QUEUE_PREEMPTION_ERROR = 30,
+  EC_QUEUE_NEW = 31,
+  EC_DEVICE_QUEUE_DELETE = 32,
+  EC_DEVICE_MEMORY_VIOLATION = 33,
+  EC_DEVICE_RAS_ERROR = 34,
+  EC_DEVICE_FATAL_HALT = 35,
+  EC_DEVICE_NEW = 36,
+  EC_PROCESS_RUNTIME = 48,
+  EC_PROCESS_DEVICE_REMOVE = 49,
+  EC_MAX
+};
+#define KFD_EC_MASK(ecode) (1ULL << (ecode - 1))
+#define KFD_EC_MASK_QUEUE (KFD_EC_MASK(EC_QUEUE_WAVE_ABORT) | KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | KFD_EC_MASK(EC_QUEUE_WAVE_MATH_ERROR) | KFD_EC_MASK(EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION) | KFD_EC_MASK(EC_QUEUE_WAVE_MEMORY_VIOLATION) | KFD_EC_MASK(EC_QUEUE_WAVE_APERTURE_VIOLATION) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_RESERVED) | KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED) | KFD_EC_MASK(EC_QUEUE_PREEMPTION_ERROR) | KFD_EC_MASK(EC_QUEUE_NEW))
+#define KFD_EC_MASK_DEVICE (KFD_EC_MASK(EC_DEVICE_QUEUE_DELETE) | KFD_EC_MASK(EC_DEVICE_RAS_ERROR) | KFD_EC_MASK(EC_DEVICE_FATAL_HALT) | KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION) | KFD_EC_MASK(EC_DEVICE_NEW))
+#define KFD_EC_MASK_PROCESS (KFD_EC_MASK(EC_PROCESS_RUNTIME) | KFD_EC_MASK(EC_PROCESS_DEVICE_REMOVE))
+#define KFD_DBG_EC_TYPE_IS_QUEUE(ecode) (! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_QUEUE))
+#define KFD_DBG_EC_TYPE_IS_DEVICE(ecode) (! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_DEVICE))
+#define KFD_DBG_EC_TYPE_IS_PROCESS(ecode) (! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_PROCESS))
+enum kfd_dbg_runtime_state {
+  DEBUG_RUNTIME_STATE_DISABLED = 0,
+  DEBUG_RUNTIME_STATE_ENABLED = 1,
+  DEBUG_RUNTIME_STATE_ENABLED_BUSY = 2,
+  DEBUG_RUNTIME_STATE_ENABLED_ERROR = 3
+};
+struct kfd_runtime_info {
+  __u64 r_debug;
+  __u32 runtime_state;
+  __u32 ttmp_setup;
+};
+#define KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK 1
+#define KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK 2
+struct kfd_ioctl_runtime_enable_args {
+  __u64 r_debug;
+  __u32 mode_mask;
+  __u32 capabilities_mask;
+};
+struct kfd_queue_snapshot_entry {
+  __u64 exception_status;
+  __u64 ring_base_address;
+  __u64 write_pointer_address;
+  __u64 read_pointer_address;
+  __u64 ctx_save_restore_address;
+  __u32 queue_id;
+  __u32 gpu_id;
+  __u32 ring_size;
+  __u32 queue_type;
+  __u32 ctx_save_restore_area_size;
+  __u32 reserved;
+};
+#define KFD_DBG_QUEUE_ERROR_BIT 30
+#define KFD_DBG_QUEUE_INVALID_BIT 31
+#define KFD_DBG_QUEUE_ERROR_MASK (1 << KFD_DBG_QUEUE_ERROR_BIT)
+#define KFD_DBG_QUEUE_INVALID_MASK (1 << KFD_DBG_QUEUE_INVALID_BIT)
+struct kfd_context_save_area_header {
+  struct {
+    __u32 control_stack_offset;
+    __u32 control_stack_size;
+    __u32 wave_state_offset;
+    __u32 wave_state_size;
+  } wave_state;
+  __u32 debug_offset;
+  __u32 debug_size;
+  __u64 err_payload_addr;
+  __u32 err_event_id;
+  __u32 reserved1;
+};
+enum kfd_dbg_trap_operations {
+  KFD_IOC_DBG_TRAP_ENABLE = 0,
+  KFD_IOC_DBG_TRAP_DISABLE = 1,
+  KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT = 2,
+  KFD_IOC_DBG_TRAP_SET_EXCEPTIONS_ENABLED = 3,
+  KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE = 4,
+  KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE = 5,
+  KFD_IOC_DBG_TRAP_SUSPEND_QUEUES = 6,
+  KFD_IOC_DBG_TRAP_RESUME_QUEUES = 7,
+  KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH = 8,
+  KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH = 9,
+  KFD_IOC_DBG_TRAP_SET_FLAGS = 10,
+  KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT = 11,
+  KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO = 12,
+  KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT = 13,
+  KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT = 14
+};
+struct kfd_ioctl_dbg_trap_enable_args {
+  __u64 exception_mask;
+  __u64 rinfo_ptr;
+  __u32 rinfo_size;
+  __u32 dbg_fd;
+};
+struct kfd_ioctl_dbg_trap_send_runtime_event_args {
+  __u64 exception_mask;
+  __u32 gpu_id;
+  __u32 queue_id;
+};
+struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args {
+  __u64 exception_mask;
+};
+struct kfd_ioctl_dbg_trap_set_wave_launch_override_args {
+  __u32 override_mode;
+  __u32 enable_mask;
+  __u32 support_request_mask;
+  __u32 pad;
+};
+struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args {
+  __u32 launch_mode;
+  __u32 pad;
+};
+struct kfd_ioctl_dbg_trap_suspend_queues_args {
+  __u64 exception_mask;
+  __u64 queue_array_ptr;
+  __u32 num_queues;
+  __u32 grace_period;
+};
+struct kfd_ioctl_dbg_trap_resume_queues_args {
+  __u64 queue_array_ptr;
+  __u32 num_queues;
+  __u32 pad;
+};
+struct kfd_ioctl_dbg_trap_set_node_address_watch_args {
+  __u64 address;
+  __u32 mode;
+  __u32 mask;
+  __u32 gpu_id;
+  __u32 id;
+};
+struct kfd_ioctl_dbg_trap_clear_node_address_watch_args {
+  __u32 gpu_id;
+  __u32 id;
+};
+struct kfd_ioctl_dbg_trap_set_flags_args {
+  __u32 flags;
+  __u32 pad;
+};
+struct kfd_ioctl_dbg_trap_query_debug_event_args {
+  __u64 exception_mask;
+  __u32 gpu_id;
+  __u32 queue_id;
+};
+struct kfd_ioctl_dbg_trap_query_exception_info_args {
+  __u64 info_ptr;
+  __u32 info_size;
+  __u32 source_id;
+  __u32 exception_code;
+  __u32 clear_exception;
+};
+struct kfd_ioctl_dbg_trap_queue_snapshot_args {
+  __u64 exception_mask;
+  __u64 snapshot_buf_ptr;
+  __u32 num_queues;
+  __u32 entry_size;
+};
+struct kfd_ioctl_dbg_trap_device_snapshot_args {
+  __u64 exception_mask;
+  __u64 snapshot_buf_ptr;
+  __u32 num_devices;
+  __u32 entry_size;
+};
+struct kfd_ioctl_dbg_trap_args {
+  __u32 pid;
+  __u32 op;
+  union {
+    struct kfd_ioctl_dbg_trap_enable_args enable;
+    struct kfd_ioctl_dbg_trap_send_runtime_event_args send_runtime_event;
+    struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args set_exceptions_enabled;
+    struct kfd_ioctl_dbg_trap_set_wave_launch_override_args launch_override;
+    struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args launch_mode;
+    struct kfd_ioctl_dbg_trap_suspend_queues_args suspend_queues;
+    struct kfd_ioctl_dbg_trap_resume_queues_args resume_queues;
+    struct kfd_ioctl_dbg_trap_set_node_address_watch_args set_node_address_watch;
+    struct kfd_ioctl_dbg_trap_clear_node_address_watch_args clear_node_address_watch;
+    struct kfd_ioctl_dbg_trap_set_flags_args set_flags;
+    struct kfd_ioctl_dbg_trap_query_debug_event_args query_debug_event;
+    struct kfd_ioctl_dbg_trap_query_exception_info_args query_exception_info;
+    struct kfd_ioctl_dbg_trap_queue_snapshot_args queue_snapshot;
+    struct kfd_ioctl_dbg_trap_device_snapshot_args device_snapshot;
+  };
+};
 #define AMDKFD_IOCTL_BASE 'K'
 #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
 #define AMDKFD_IOR(nr,type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
@@ -451,6 +709,9 @@
 #define AMDKFD_IOC_SET_XNACK_MODE AMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args)
 #define AMDKFD_IOC_CRIU_OP AMDKFD_IOWR(0x22, struct kfd_ioctl_criu_args)
 #define AMDKFD_IOC_AVAILABLE_MEMORY AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args)
+#define AMDKFD_IOC_EXPORT_DMABUF AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args)
+#define AMDKFD_IOC_RUNTIME_ENABLE AMDKFD_IOWR(0x25, struct kfd_ioctl_runtime_enable_args)
+#define AMDKFD_IOC_DBG_TRAP AMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args)
 #define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x24
+#define AMDKFD_COMMAND_END 0x27
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_sysfs.h b/libc/kernel/uapi/linux/kfd_sysfs.h
index 9604b03..333ad9d 100644
--- a/libc/kernel/uapi/linux/kfd_sysfs.h
+++ b/libc/kernel/uapi/linux/kfd_sysfs.h
@@ -34,6 +34,10 @@
 #define HSA_CAP_DOORBELL_TYPE_1_0 0x1
 #define HSA_CAP_DOORBELL_TYPE_2_0 0x2
 #define HSA_CAP_AQL_QUEUE_DOUBLE_MAP 0x00004000
+#define HSA_CAP_TRAP_DEBUG_SUPPORT 0x00008000
+#define HSA_CAP_TRAP_DEBUG_WAVE_LAUNCH_TRAP_OVERRIDE_SUPPORTED 0x00010000
+#define HSA_CAP_TRAP_DEBUG_WAVE_LAUNCH_MODE_SUPPORTED 0x00020000
+#define HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED 0x00040000
 #define HSA_CAP_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000
 #define HSA_CAP_MEM_EDCSUPPORTED 0x00100000
 #define HSA_CAP_RASEVENTNOTIFY 0x00200000
@@ -42,7 +46,15 @@
 #define HSA_CAP_SRAM_EDCSUPPORTED 0x04000000
 #define HSA_CAP_SVMAPI_SUPPORTED 0x08000000
 #define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000
+#define HSA_CAP_TRAP_DEBUG_FIRMWARE_SUPPORTED 0x20000000
 #define HSA_CAP_RESERVED 0xe00f8000
+#define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_MASK 0x0000000f
+#define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_SHIFT 0
+#define HSA_DBG_WATCH_ADDR_MASK_HI_BIT_MASK 0x000003f0
+#define HSA_DBG_WATCH_ADDR_MASK_HI_BIT_SHIFT 4
+#define HSA_DBG_DISPATCH_INFO_ALWAYS_VALID 0x00000400
+#define HSA_DBG_WATCHPOINTS_EXCLUSIVE 0x00000800
+#define HSA_DBG_RESERVED 0xfffffffffffff000ull
 #define HSA_MEM_HEAP_TYPE_SYSTEM 0
 #define HSA_MEM_HEAP_TYPE_FB_PUBLIC 1
 #define HSA_MEM_HEAP_TYPE_FB_PRIVATE 2
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 342c5c9..ebed0e8 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -265,8 +265,10 @@
       __u64 nr;
       __u64 args[6];
       __u64 ret;
-      __u32 longmode;
-      __u32 pad;
+      union {
+        __u32 longmode;
+        __u64 flags;
+      };
     } hypercall;
     struct {
       __u64 rip;
@@ -932,6 +934,9 @@
 #define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224
 #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
 #define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
+#define KVM_CAP_COUNTER_OFFSET 227
+#define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228
+#define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -1128,6 +1133,8 @@
 #define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE
   KVM_DEV_TYPE_ARM_PV_TIME,
 #define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME
+  KVM_DEV_TYPE_RISCV_AIA,
+#define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA
   KVM_DEV_TYPE_MAX,
 };
 struct kvm_vfio_spapr_tce {
@@ -1198,6 +1205,7 @@
 #define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_filter)
 #define KVM_PPC_SVM_OFF _IO(KVMIO, 0xb3)
 #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags)
+#define KVM_ARM_SET_COUNTER_OFFSET _IOW(KVMIO, 0xb5, struct kvm_arm_counter_offset)
 #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
 #define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr)
 #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr)
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index 725eb1a..2305f64 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -202,6 +202,28 @@
 #define MDIO_PMA_EXTABLE_10BT 0x0100
 #define MDIO_PMA_EXTABLE_BT1 0x0800
 #define MDIO_PMA_EXTABLE_NBT 0x4000
+#define MDIO_AN_C73_0_S_MASK GENMASK(4, 0)
+#define MDIO_AN_C73_0_E_MASK GENMASK(9, 5)
+#define MDIO_AN_C73_0_PAUSE BIT(10)
+#define MDIO_AN_C73_0_ASM_DIR BIT(11)
+#define MDIO_AN_C73_0_C2 BIT(12)
+#define MDIO_AN_C73_0_RF BIT(13)
+#define MDIO_AN_C73_0_ACK BIT(14)
+#define MDIO_AN_C73_0_NP BIT(15)
+#define MDIO_AN_C73_1_T_MASK GENMASK(4, 0)
+#define MDIO_AN_C73_1_1000BASE_KX BIT(5)
+#define MDIO_AN_C73_1_10GBASE_KX4 BIT(6)
+#define MDIO_AN_C73_1_10GBASE_KR BIT(7)
+#define MDIO_AN_C73_1_40GBASE_KR4 BIT(8)
+#define MDIO_AN_C73_1_40GBASE_CR4 BIT(9)
+#define MDIO_AN_C73_1_100GBASE_CR10 BIT(10)
+#define MDIO_AN_C73_1_100GBASE_KP4 BIT(11)
+#define MDIO_AN_C73_1_100GBASE_KR4 BIT(12)
+#define MDIO_AN_C73_1_100GBASE_CR4 BIT(13)
+#define MDIO_AN_C73_1_25GBASE_R_S BIT(14)
+#define MDIO_AN_C73_1_25GBASE_R BIT(15)
+#define MDIO_AN_C73_2_2500BASE_KX BIT(0)
+#define MDIO_AN_C73_2_5GBASE_KR BIT(1)
 #define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
 #define MDIO_PHYXS_LNSTAT_SYNC1 0x0002
 #define MDIO_PHYXS_LNSTAT_SYNC2 0x0004
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index fe97e90..6027dc4 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -66,8 +66,8 @@
 #define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4)
 #define MEDIA_ENT_F_DV_DECODER (MEDIA_ENT_F_BASE + 0x6001)
 #define MEDIA_ENT_F_DV_ENCODER (MEDIA_ENT_F_BASE + 0x6002)
-#define MEDIA_ENT_FL_DEFAULT (1 << 0)
-#define MEDIA_ENT_FL_CONNECTOR (1 << 1)
+#define MEDIA_ENT_FL_DEFAULT (1U << 0)
+#define MEDIA_ENT_FL_CONNECTOR (1U << 1)
 #define MEDIA_ENT_ID_FLAG_NEXT (1U << 31)
 struct media_entity_desc {
   __u32 id;
@@ -101,22 +101,22 @@
     __u8 raw[184];
   };
 };
-#define MEDIA_PAD_FL_SINK (1 << 0)
-#define MEDIA_PAD_FL_SOURCE (1 << 1)
-#define MEDIA_PAD_FL_MUST_CONNECT (1 << 2)
+#define MEDIA_PAD_FL_SINK (1U << 0)
+#define MEDIA_PAD_FL_SOURCE (1U << 1)
+#define MEDIA_PAD_FL_MUST_CONNECT (1U << 2)
 struct media_pad_desc {
   __u32 entity;
   __u16 index;
   __u32 flags;
   __u32 reserved[2];
 };
-#define MEDIA_LNK_FL_ENABLED (1 << 0)
-#define MEDIA_LNK_FL_IMMUTABLE (1 << 1)
-#define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_ENABLED (1U << 0)
+#define MEDIA_LNK_FL_IMMUTABLE (1U << 1)
+#define MEDIA_LNK_FL_DYNAMIC (1U << 2)
 #define MEDIA_LNK_FL_LINK_TYPE (0xf << 28)
-#define MEDIA_LNK_FL_DATA_LINK (0 << 28)
-#define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
-#define MEDIA_LNK_FL_ANCILLARY_LINK (2 << 28)
+#define MEDIA_LNK_FL_DATA_LINK (0U << 28)
+#define MEDIA_LNK_FL_INTERFACE_LINK (1U << 28)
+#define MEDIA_LNK_FL_ANCILLARY_LINK (2U << 28)
 struct media_link_desc {
   struct media_pad_desc source;
   struct media_pad_desc sink;
@@ -146,7 +146,7 @@
 #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE)
 #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1)
 #define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2)
-#define MEDIA_V2_ENTITY_HAS_FLAGS(media_version) ((media_version) >= ((4 << 16) | (19 << 8) | 0))
+#define MEDIA_V2_ENTITY_HAS_FLAGS(media_version) ((media_version) >= ((4U << 16) | (19U << 8) | 0U))
 struct media_v2_entity {
   __u32 id;
   char name[64];
@@ -168,7 +168,7 @@
     __u32 raw[16];
   };
 } __attribute__((packed));
-#define MEDIA_V2_PAD_HAS_INDEX(media_version) ((media_version) >= ((4 << 16) | (19 << 8) | 0))
+#define MEDIA_V2_PAD_HAS_INDEX(media_version) ((media_version) >= ((4U << 16) | (19U << 8) | 0U))
 struct media_v2_pad {
   __u32 id;
   __u32 entity_id;
@@ -229,5 +229,5 @@
 #define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5)
 #define MEDIA_INTF_T_ALSA_SEQUENCER (MEDIA_INTF_T_ALSA_BASE + 6)
 #define MEDIA_INTF_T_ALSA_TIMER (MEDIA_INTF_T_ALSA_BASE + 7)
-#define MEDIA_API_VERSION ((0 << 16) | (1 << 8) | 0)
+#define MEDIA_API_VERSION ((0U << 16) | (1U << 8) | 0U)
 #endif
diff --git a/libc/kernel/uapi/linux/mei.h b/libc/kernel/uapi/linux/mei.h
index ed37abd..3d4ae66 100644
--- a/libc/kernel/uapi/linux/mei.h
+++ b/libc/kernel/uapi/linux/mei.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef _LINUX_MEI_H
 #define _LINUX_MEI_H
-#include <linux/uuid.h>
+#include <linux/mei_uuid.h>
 #define IOCTL_MEI_CONNECT_CLIENT _IOWR('H', 0x01, struct mei_connect_client_data)
 struct mei_client {
   __u32 max_msg_length;
diff --git a/libc/kernel/uapi/linux/mei_uuid.h b/libc/kernel/uapi/linux/mei_uuid.h
new file mode 100644
index 0000000..17f6e55
--- /dev/null
+++ b/libc/kernel/uapi/linux/mei_uuid.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_MEI_UUID_H_
+#define _UAPI_LINUX_MEI_UUID_H_
+#include <linux/types.h>
+typedef struct {
+  __u8 b[16];
+} uuid_le;
+#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((uuid_le) \
+{ { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+#define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+#endif
diff --git a/libc/kernel/uapi/linux/mman.h b/libc/kernel/uapi/linux/mman.h
index 9fdccf6..a58fc49 100644
--- a/libc/kernel/uapi/linux/mman.h
+++ b/libc/kernel/uapi/linux/mman.h
@@ -20,6 +20,7 @@
 #define _UAPI_LINUX_MMAN_H
 #include <asm/mman.h>
 #include <asm-generic/hugetlb_encode.h>
+#include <linux/types.h>
 #define MREMAP_MAYMOVE 1
 #define MREMAP_FIXED 2
 #define MREMAP_DONTUNMAP 4
@@ -44,4 +45,15 @@
 #define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
 #define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
 #define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
+struct cachestat_range {
+  __u64 off;
+  __u64 len;
+};
+struct cachestat {
+  __u64 nr_cache;
+  __u64 nr_dirty;
+  __u64 nr_writeback;
+  __u64 nr_evicted;
+  __u64 nr_recently_evicted;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/mount.h b/libc/kernel/uapi/linux/mount.h
index 2099b48..28f233a 100644
--- a/libc/kernel/uapi/linux/mount.h
+++ b/libc/kernel/uapi/linux/mount.h
@@ -63,7 +63,8 @@
 #define MOVE_MOUNT_T_AUTOMOUNTS 0x00000020
 #define MOVE_MOUNT_T_EMPTY_PATH 0x00000040
 #define MOVE_MOUNT_SET_GROUP 0x00000100
-#define MOVE_MOUNT__MASK 0x00000177
+#define MOVE_MOUNT_BENEATH 0x00000200
+#define MOVE_MOUNT__MASK 0x00000377
 #define FSOPEN_CLOEXEC 0x00000001
 #define FSPICK_CLOEXEC 0x00000001
 #define FSPICK_SYMLINK_NOFOLLOW 0x00000002
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index 9f7215c..d84ab50 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -114,6 +114,11 @@
   __u8 mptcpi_local_addr_used;
   __u8 mptcpi_local_addr_max;
   __u8 mptcpi_csum_enabled;
+  __u32 mptcpi_retransmits;
+  __u64 mptcpi_bytes_retrans;
+  __u64 mptcpi_bytes_sent;
+  __u64 mptcpi_bytes_received;
+  __u64 mptcpi_bytes_acked;
 };
 enum mptcp_event_type {
   MPTCP_EVENT_UNSPEC = 0,
@@ -179,7 +184,23 @@
     struct __kernel_sockaddr_storage ss_remote;
   };
 };
+struct mptcp_subflow_info {
+  __u32 id;
+  struct mptcp_subflow_addrs addrs;
+};
+struct mptcp_full_info {
+  __u32 size_tcpinfo_kernel;
+  __u32 size_tcpinfo_user;
+  __u32 size_sfinfo_kernel;
+  __u32 size_sfinfo_user;
+  __u32 num_subflows;
+  __u32 size_arrays_user;
+  __aligned_u64 subflow_info;
+  __aligned_u64 tcp_info;
+  struct mptcp_info mptcp_info;
+};
 #define MPTCP_INFO 1
 #define MPTCP_TCPINFO 2
 #define MPTCP_SUBFLOW_ADDRS 3
+#define MPTCP_FULL_INFO 4
 #endif
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index 3b74393..fee4b74 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -51,13 +51,19 @@
 struct nbd_request {
   __be32 magic;
   __be32 type;
-  char handle[8];
+  union {
+    __be64 cookie;
+    char handle[8];
+  };
   __be64 from;
   __be32 len;
 } __attribute__((packed));
 struct nbd_reply {
   __be32 magic;
   __be32 error;
-  char handle[8];
+  union {
+    __be64 cookie;
+    char handle[8];
+  };
 };
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 33bfb7f..ef938f0 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -94,6 +94,7 @@
   NFT_MSG_DESTROYSETELEM,
   NFT_MSG_DESTROYOBJ,
   NFT_MSG_DESTROYFLOWTABLE,
+  NFT_MSG_GETSETELEM_RESET,
   NFT_MSG_MAX,
 };
 enum nft_list_attributes {
@@ -448,6 +449,7 @@
   NFT_EXTHDR_OP_TCPOPT,
   NFT_EXTHDR_OP_IPV4,
   NFT_EXTHDR_OP_SCTP,
+  NFT_EXTHDR_OP_DCCP,
   __NFT_EXTHDR_OP_MAX
 };
 #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1)
@@ -500,6 +502,7 @@
   NFT_META_TIME_HOUR,
   NFT_META_SDIF,
   NFT_META_SDIFNAME,
+  NFT_META_BRI_BROUTE,
   __NFT_META_IIFTYPE,
 };
 enum nft_rt_keys {
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
index ce1692c..702917d 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
@@ -50,5 +50,12 @@
 #define NFNLA_CHAIN_MAX (__NFNLA_CHAIN_MAX - 1)
 enum nfnl_hook_chaintype {
   NFNL_HOOK_TYPE_NFTABLES = 0x1,
+  NFNL_HOOK_TYPE_BPF,
 };
+enum nfnl_hook_bpf_attributes {
+  NFNLA_HOOK_BPF_UNSPEC,
+  NFNLA_HOOK_BPF_ID,
+  __NFNLA_HOOK_BPF_MAX,
+};
+#define NFNLA_HOOK_BPF_MAX (__NFNLA_HOOK_BPF_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
index d100dec..c2d62ba 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
@@ -71,6 +71,7 @@
   NFQA_VLAN,
   NFQA_L2HDR,
   NFQA_PRIORITY,
+  NFQA_CGROUP_CLASSID,
   __NFQA_MAX
 };
 #define NFQA_MAX (__NFQA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/nfsd/export.h b/libc/kernel/uapi/linux/nfsd/export.h
index 4716fb1..63ccedc 100644
--- a/libc/kernel/uapi/linux/nfsd/export.h
+++ b/libc/kernel/uapi/linux/nfsd/export.h
@@ -41,4 +41,9 @@
 #define NFSEXP_PNFS 0x20000
 #define NFSEXP_ALLFLAGS 0x3FEFF
 #define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH | NFSEXP_ALLSQUASH | NFSEXP_INSECURE_PORT)
+#define NFSEXP_XPRTSEC_NONE 0x0001
+#define NFSEXP_XPRTSEC_TLS 0x0002
+#define NFSEXP_XPRTSEC_MTLS 0x0004
+#define NFSEXP_XPRTSEC_NUM (3)
+#define NFSEXP_XPRTSEC_ALL (NFSEXP_XPRTSEC_NONE | NFSEXP_XPRTSEC_TLS | NFSEXP_XPRTSEC_MTLS)
 #endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index d73922a..90d7b9e 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -190,6 +190,8 @@
   NL80211_CMD_ADD_LINK_STA,
   NL80211_CMD_MODIFY_LINK_STA,
   NL80211_CMD_REMOVE_LINK_STA,
+  NL80211_CMD_SET_HW_TIMESTAMP,
+  NL80211_CMD_LINKS_REMOVED,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -529,6 +531,10 @@
   NL80211_ATTR_RX_HW_TIMESTAMP,
   NL80211_ATTR_TD_BITMAP,
   NL80211_ATTR_PUNCT_BITMAP,
+  NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS,
+  NL80211_ATTR_HW_TIMESTAMP_ENABLED,
+  NL80211_ATTR_EMA_RNR_ELEMS,
+  NL80211_ATTR_MLO_LINK_DISABLED,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -683,6 +689,13 @@
   NL80211_RATE_INFO_EHT_NSS,
   NL80211_RATE_INFO_EHT_GI,
   NL80211_RATE_INFO_EHT_RU_ALLOC,
+  NL80211_RATE_INFO_S1G_MCS,
+  NL80211_RATE_INFO_S1G_NSS,
+  NL80211_RATE_INFO_1_MHZ_WIDTH,
+  NL80211_RATE_INFO_2_MHZ_WIDTH,
+  NL80211_RATE_INFO_4_MHZ_WIDTH,
+  NL80211_RATE_INFO_8_MHZ_WIDTH,
+  NL80211_RATE_INFO_16_MHZ_WIDTH,
   __NL80211_RATE_INFO_AFTER_LAST,
   NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1
 };
@@ -822,6 +835,8 @@
   NL80211_BAND_ATTR_IFTYPE_DATA,
   NL80211_BAND_ATTR_EDMG_CHANNELS,
   NL80211_BAND_ATTR_EDMG_BW_CONFIG,
+  NL80211_BAND_ATTR_S1G_MCS_NSS_SET,
+  NL80211_BAND_ATTR_S1G_CAPA,
   __NL80211_BAND_ATTR_AFTER_LAST,
   NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
 };
@@ -933,6 +948,7 @@
   NL80211_RRF_NO_160MHZ = 1 << 16,
   NL80211_RRF_NO_HE = 1 << 17,
   NL80211_RRF_NO_320MHZ = 1 << 18,
+  NL80211_RRF_NO_EHT = 1 << 19,
 };
 #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
 #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
@@ -1537,6 +1553,7 @@
   NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
   NL80211_EXT_FEATURE_PUNCT,
   NL80211_EXT_FEATURE_SECURE_NAN,
+  NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 0226e93..1e2a412 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -396,6 +396,7 @@
 };
 enum ovs_hash_alg {
   OVS_HASH_ALG_L4,
+  OVS_HASH_ALG_SYM_L4,
 };
 struct ovs_action_hash {
   __u32 hash_alg;
diff --git a/libc/kernel/uapi/linux/parport.h b/libc/kernel/uapi/linux/parport.h
index 8152224..611775f 100644
--- a/libc/kernel/uapi/linux/parport.h
+++ b/libc/kernel/uapi/linux/parport.h
@@ -75,4 +75,7 @@
 #define IEEE1284_DATA 0
 #define PARPORT_EPP_FAST (1 << 0)
 #define PARPORT_W91284PIC (1 << 1)
+#define PARPORT_EPP_FAST_32 PARPORT_EPP_FAST
+#define PARPORT_EPP_FAST_16 (1 << 2)
+#define PARPORT_EPP_FAST_8 (1 << 3)
 #endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index 44b0613..888fb5c 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -636,6 +636,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_PL_32GT 0x2A
 #define PCI_EXT_CAP_ID_DOE 0x2E
 #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE
 #define PCI_EXT_CAP_DSN_SIZEOF 12
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index 876cb73..0afec0d 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -463,6 +463,8 @@
   TCA_FLOWER_KEY_PPPOE_SID,
   TCA_FLOWER_KEY_PPP_PROTO,
   TCA_FLOWER_KEY_L2TPV3_SID,
+  TCA_FLOWER_L2_MISS,
+  TCA_FLOWER_KEY_CFM,
   __TCA_FLOWER_MAX,
 };
 #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
@@ -534,6 +536,13 @@
   TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
   TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
 };
+enum {
+  TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
+  TCA_FLOWER_KEY_CFM_MD_LEVEL,
+  TCA_FLOWER_KEY_CFM_OPCODE,
+  __TCA_FLOWER_KEY_CFM_OPT_MAX,
+};
+#define TCA_FLOWER_KEY_CFM_OPT_MAX (__TCA_FLOWER_KEY_CFM_OPT_MAX - 1)
 #define TCA_FLOWER_MASK_FLAGS_RANGE (1 << 0)
 struct tc_matchall_pcnt {
   __u64 rhit;
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index c31b8bb..6a4b6e1 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -532,6 +532,10 @@
   __TC_MQPRIO_SHAPER_MAX
 };
 #define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1)
+enum {
+  TC_FP_EXPRESS = 1,
+  TC_FP_PREEMPTIBLE = 2,
+};
 struct tc_mqprio_qopt {
   __u8 num_tc;
   __u8 prio_tc_map[TC_QOPT_BITMASK + 1];
@@ -544,11 +548,19 @@
 #define TC_MQPRIO_F_MIN_RATE 0x4
 #define TC_MQPRIO_F_MAX_RATE 0x8
 enum {
+  TCA_MQPRIO_TC_ENTRY_UNSPEC,
+  TCA_MQPRIO_TC_ENTRY_INDEX,
+  TCA_MQPRIO_TC_ENTRY_FP,
+  __TCA_MQPRIO_TC_ENTRY_CNT,
+  TCA_MQPRIO_TC_ENTRY_MAX = (__TCA_MQPRIO_TC_ENTRY_CNT - 1)
+};
+enum {
   TCA_MQPRIO_UNSPEC,
   TCA_MQPRIO_MODE,
   TCA_MQPRIO_SHAPER,
   TCA_MQPRIO_MIN_RATE64,
   TCA_MQPRIO_MAX_RATE64,
+  TCA_MQPRIO_TC_ENTRY,
   __TCA_MQPRIO_MAX,
 };
 #define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1)
@@ -927,10 +939,18 @@
   TCA_TAPRIO_TC_ENTRY_UNSPEC,
   TCA_TAPRIO_TC_ENTRY_INDEX,
   TCA_TAPRIO_TC_ENTRY_MAX_SDU,
+  TCA_TAPRIO_TC_ENTRY_FP,
   __TCA_TAPRIO_TC_ENTRY_CNT,
   TCA_TAPRIO_TC_ENTRY_MAX = (__TCA_TAPRIO_TC_ENTRY_CNT - 1)
 };
 enum {
+  TCA_TAPRIO_OFFLOAD_STATS_PAD = 1,
+  TCA_TAPRIO_OFFLOAD_STATS_WINDOW_DROPS,
+  TCA_TAPRIO_OFFLOAD_STATS_TX_OVERRUNS,
+  __TCA_TAPRIO_OFFLOAD_STATS_CNT,
+  TCA_TAPRIO_OFFLOAD_STATS_MAX = (__TCA_TAPRIO_OFFLOAD_STATS_CNT - 1)
+};
+enum {
   TCA_TAPRIO_ATTR_UNSPEC,
   TCA_TAPRIO_ATTR_PRIOMAP,
   TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST,
diff --git a/libc/kernel/uapi/linux/pktcdvd.h b/libc/kernel/uapi/linux/pktcdvd.h
index eed22f8..c2414d1 100644
--- a/libc/kernel/uapi/linux/pktcdvd.h
+++ b/libc/kernel/uapi/linux/pktcdvd.h
@@ -23,7 +23,6 @@
 #define MAX_WRITERS 8
 #define PKT_RB_POOL_SIZE 512
 #define PACKET_WAIT_TIME (HZ * 5 / 1000)
-#define USE_WCACHING 0
 #define PACKET_CDR 1
 #define PACKET_CDRW 2
 #define PACKET_DVDR 3
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 6ad1c04..0e86d95 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -189,4 +189,16 @@
 #define PR_GET_MDWE 66
 #define PR_SET_VMA 0x53564d41
 #define PR_SET_VMA_ANON_NAME 0
+#define PR_GET_AUXV 0x41555856
+#define PR_SET_MEMORY_MERGE 67
+#define PR_GET_MEMORY_MERGE 68
+#define PR_RISCV_V_SET_CONTROL 69
+#define PR_RISCV_V_GET_CONTROL 70
+#define PR_RISCV_V_VSTATE_CTRL_DEFAULT 0
+#define PR_RISCV_V_VSTATE_CTRL_OFF 1
+#define PR_RISCV_V_VSTATE_CTRL_ON 2
+#define PR_RISCV_V_VSTATE_CTRL_INHERIT (1 << 4)
+#define PR_RISCV_V_VSTATE_CTRL_CUR_MASK 0x3
+#define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 0xc
+#define PR_RISCV_V_VSTATE_CTRL_MASK 0x1f
 #endif
diff --git a/libc/kernel/uapi/linux/psp-sev.h b/libc/kernel/uapi/linux/psp-sev.h
index 8c9ec80..5aefc1c 100644
--- a/libc/kernel/uapi/linux/psp-sev.h
+++ b/libc/kernel/uapi/linux/psp-sev.h
@@ -32,6 +32,7 @@
   SEV_MAX,
 };
 typedef enum {
+  SEV_RET_NO_FW_CALL = - 1,
   SEV_RET_SUCCESS = 0,
   SEV_RET_INVALID_PLATFORM_STATE,
   SEV_RET_INVALID_GUEST_STATE,
diff --git a/libc/kernel/uapi/linux/ptp_clock.h b/libc/kernel/uapi/linux/ptp_clock.h
index ca6f3c3..fe26e6e 100644
--- a/libc/kernel/uapi/linux/ptp_clock.h
+++ b/libc/kernel/uapi/linux/ptp_clock.h
@@ -46,7 +46,8 @@
   int n_pins;
   int cross_timestamping;
   int adjust_phase;
-  int rsv[12];
+  int max_phase_adj;
+  int rsv[11];
 };
 struct ptp_extts_request {
   unsigned int index;
diff --git a/libc/kernel/uapi/linux/ptrace.h b/libc/kernel/uapi/linux/ptrace.h
index 4bfa59a..56a350b 100644
--- a/libc/kernel/uapi/linux/ptrace.h
+++ b/libc/kernel/uapi/linux/ptrace.h
@@ -90,6 +90,14 @@
   __u32 flags;
   __u32 pad;
 };
+#define PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG 0x4210
+#define PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG 0x4211
+struct ptrace_sud_config {
+  __u64 mode;
+  __u64 selector;
+  __u64 offset;
+  __u64 len;
+};
 #define PTRACE_EVENTMSG_SYSCALL_ENTRY 1
 #define PTRACE_EVENTMSG_SYSCALL_EXIT 2
 #define PTRACE_PEEKSIGINFO_SHARED (1 << 0)
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 4bf2412..b1a571c 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -709,7 +709,9 @@
   SCTP_SS_DEFAULT = SCTP_SS_FCFS,
   SCTP_SS_PRIO,
   SCTP_SS_RR,
-  SCTP_SS_MAX = SCTP_SS_RR
+  SCTP_SS_FC,
+  SCTP_SS_WFQ,
+  SCTP_SS_MAX = SCTP_SS_WFQ
 };
 struct sctp_probeinterval {
   sctp_assoc_t spi_assoc_id;
diff --git a/libc/kernel/uapi/linux/sed-opal.h b/libc/kernel/uapi/linux/sed-opal.h
index 4685bb3..fa1d7ed 100644
--- a/libc/kernel/uapi/linux/sed-opal.h
+++ b/libc/kernel/uapi/linux/sed-opal.h
@@ -74,6 +74,15 @@
   __u32 WLE;
   struct opal_session_info session;
 };
+struct opal_lr_status {
+  struct opal_session_info session;
+  __u64 range_start;
+  __u64 range_length;
+  __u32 RLE;
+  __u32 WLE;
+  __u32 l_state;
+  __u8 align[4];
+};
 struct opal_lock_unlock {
   struct opal_session_info session;
   __u32 l_state;
@@ -127,6 +136,13 @@
   __u32 flags;
   __u32 reserved;
 };
+struct opal_geometry {
+  __u8 align;
+  __u32 logical_block_size;
+  __u64 alignment_granularity;
+  __u64 lowest_aligned_lba;
+  __u8 __align[3];
+};
 #define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock)
 #define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock)
 #define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key)
@@ -144,4 +160,6 @@
 #define IOC_OPAL_WRITE_SHADOW_MBR _IOW('p', 234, struct opal_shadow_mbr)
 #define IOC_OPAL_GENERIC_TABLE_RW _IOW('p', 235, struct opal_read_write_table)
 #define IOC_OPAL_GET_STATUS _IOR('p', 236, struct opal_status)
+#define IOC_OPAL_GET_LR_STATUS _IOW('p', 237, struct opal_lr_status)
+#define IOC_OPAL_GET_GEOMETRY _IOR('p', 238, struct opal_geometry)
 #endif
diff --git a/libc/kernel/uapi/linux/sev-guest.h b/libc/kernel/uapi/linux/sev-guest.h
index 796479a..3e8c0bf 100644
--- a/libc/kernel/uapi/linux/sev-guest.h
+++ b/libc/kernel/uapi/linux/sev-guest.h
@@ -42,7 +42,13 @@
   __u8 msg_version;
   __u64 req_data;
   __u64 resp_data;
-  __u64 fw_err;
+  union {
+    __u64 exitinfo2;
+    struct {
+      __u32 fw_error;
+      __u32 vmm_error;
+    };
+  };
 };
 struct snp_ext_report_req {
   struct snp_report_req data;
@@ -53,4 +59,9 @@
 #define SNP_GET_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x0, struct snp_guest_request_ioctl)
 #define SNP_GET_DERIVED_KEY _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x1, struct snp_guest_request_ioctl)
 #define SNP_GET_EXT_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x2, struct snp_guest_request_ioctl)
+#define SNP_GUEST_FW_ERR_MASK GENMASK_ULL(31, 0)
+#define SNP_GUEST_VMM_ERR_SHIFT 32
+#define SNP_GUEST_VMM_ERR(x) (((u64) x) << SNP_GUEST_VMM_ERR_SHIFT)
+#define SNP_GUEST_VMM_ERR_INVALID_LEN 1
+#define SNP_GUEST_VMM_ERR_BUSY 2
 #endif
diff --git a/libc/kernel/uapi/linux/spi/spi.h b/libc/kernel/uapi/linux/spi/spi.h
index 693e752..a5af3f4 100644
--- a/libc/kernel/uapi/linux/spi/spi.h
+++ b/libc/kernel/uapi/linux/spi/spi.h
@@ -41,5 +41,6 @@
 #define SPI_RX_OCTAL _BITUL(14)
 #define SPI_3WIRE_HIZ _BITUL(15)
 #define SPI_RX_CPHA_FLIP _BITUL(16)
-#define SPI_MODE_USER_MASK (_BITUL(17) - 1)
+#define SPI_MOSI_IDLE_LOW _BITUL(17)
+#define SPI_MODE_USER_MASK (_BITUL(18) - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index 83e155e..84af2d2 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -61,7 +61,7 @@
       __u64 cdb_off;
       __u64 __pad1;
       __u64 __pad2;
-      struct iovec iov[0];
+      __DECLARE_FLEX_ARRAY(struct iovec, iov);
     } req;
     struct {
       __u8 scsi_status;
diff --git a/libc/kernel/uapi/linux/taskstats.h b/libc/kernel/uapi/linux/taskstats.h
index c1cda52..4f1637e 100644
--- a/libc/kernel/uapi/linux/taskstats.h
+++ b/libc/kernel/uapi/linux/taskstats.h
@@ -19,7 +19,7 @@
 #ifndef _LINUX_TASKSTATS_H
 #define _LINUX_TASKSTATS_H
 #include <linux/types.h>
-#define TASKSTATS_VERSION 13
+#define TASKSTATS_VERSION 14
 #define TS_COMM_LEN 32
 struct taskstats {
   __u16 version;
@@ -77,6 +77,8 @@
   __u64 ac_exe_inode;
   __u64 wpcopy_count;
   __u64 wpcopy_delay_total;
+  __u64 irq_count;
+  __u64 irq_delay_total;
 };
 enum {
   TASKSTATS_CMD_UNSPEC = 0,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
index e137ae8..7eb61e8 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
@@ -40,6 +40,7 @@
   TCA_TUNNEL_KEY_ENC_OPTS,
   TCA_TUNNEL_KEY_ENC_TOS,
   TCA_TUNNEL_KEY_ENC_TTL,
+  TCA_TUNNEL_KEY_NO_FRAG,
   __TCA_TUNNEL_KEY_MAX,
 };
 #define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tps6594_pfsm.h b/libc/kernel/uapi/linux/tps6594_pfsm.h
new file mode 100644
index 0000000..ca3222b
--- /dev/null
+++ b/libc/kernel/uapi/linux/tps6594_pfsm.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __TPS6594_PFSM_H
+#define __TPS6594_PFSM_H
+#include <linux/const.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+struct pmic_state_opt {
+  __u8 gpio_retention;
+  __u8 ddr_retention;
+  __u8 mcu_only_startup_dest;
+};
+#define PMIC_BASE 'P'
+#define PMIC_GOTO_STANDBY _IO(PMIC_BASE, 0)
+#define PMIC_GOTO_LP_STANDBY _IO(PMIC_BASE, 1)
+#define PMIC_UPDATE_PGM _IO(PMIC_BASE, 2)
+#define PMIC_SET_ACTIVE_STATE _IO(PMIC_BASE, 3)
+#define PMIC_SET_MCU_ONLY_STATE _IOW(PMIC_BASE, 4, struct pmic_state_opt)
+#define PMIC_SET_RETENTION_STATE _IOW(PMIC_BASE, 5, struct pmic_state_opt)
+#endif
diff --git a/libc/kernel/uapi/linux/types.h b/libc/kernel/uapi/linux/types.h
index f41d676..cbc079d 100644
--- a/libc/kernel/uapi/linux/types.h
+++ b/libc/kernel/uapi/linux/types.h
@@ -21,6 +21,10 @@
 #include <asm/types.h>
 #ifndef __ASSEMBLY__
 #include <linux/posix_types.h>
+#ifdef __SIZEOF_INT128__
+typedef __signed__ __int128 __s128 __attribute__((aligned(16)));
+typedef unsigned __int128 __u128 __attribute__((aligned(16)));
+#endif
 #define __bitwise
 #define __bitwise__ __bitwise
 typedef __u16 __bitwise __le16;
diff --git a/libc/kernel/uapi/linux/ublk_cmd.h b/libc/kernel/uapi/linux/ublk_cmd.h
index 6e0a9f8..975015f 100644
--- a/libc/kernel/uapi/linux/ublk_cmd.h
+++ b/libc/kernel/uapi/linux/ublk_cmd.h
@@ -30,21 +30,51 @@
 #define UBLK_CMD_START_USER_RECOVERY 0x10
 #define UBLK_CMD_END_USER_RECOVERY 0x11
 #define UBLK_CMD_GET_DEV_INFO2 0x12
+#define UBLK_U_CMD_GET_QUEUE_AFFINITY _IOR('u', UBLK_CMD_GET_QUEUE_AFFINITY, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_DEV_INFO _IOR('u', UBLK_CMD_GET_DEV_INFO, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_ADD_DEV _IOWR('u', UBLK_CMD_ADD_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_DEL_DEV _IOWR('u', UBLK_CMD_DEL_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_START_DEV _IOWR('u', UBLK_CMD_START_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_STOP_DEV _IOWR('u', UBLK_CMD_STOP_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_SET_PARAMS _IOWR('u', UBLK_CMD_SET_PARAMS, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_PARAMS _IOR('u', UBLK_CMD_GET_PARAMS, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_START_USER_RECOVERY _IOWR('u', UBLK_CMD_START_USER_RECOVERY, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_END_USER_RECOVERY _IOWR('u', UBLK_CMD_END_USER_RECOVERY, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_DEV_INFO2 _IOR('u', UBLK_CMD_GET_DEV_INFO2, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_FEATURES _IOR('u', 0x13, struct ublksrv_ctrl_cmd)
+#define UBLK_FEATURES_LEN 8
 #define UBLK_IO_FETCH_REQ 0x20
 #define UBLK_IO_COMMIT_AND_FETCH_REQ 0x21
 #define UBLK_IO_NEED_GET_DATA 0x22
+#define UBLK_U_IO_FETCH_REQ _IOWR('u', UBLK_IO_FETCH_REQ, struct ublksrv_io_cmd)
+#define UBLK_U_IO_COMMIT_AND_FETCH_REQ _IOWR('u', UBLK_IO_COMMIT_AND_FETCH_REQ, struct ublksrv_io_cmd)
+#define UBLK_U_IO_NEED_GET_DATA _IOWR('u', UBLK_IO_NEED_GET_DATA, struct ublksrv_io_cmd)
 #define UBLK_IO_RES_OK 0
 #define UBLK_IO_RES_NEED_GET_DATA 1
 #define UBLK_IO_RES_ABORT (- ENODEV)
 #define UBLKSRV_CMD_BUF_OFFSET 0
 #define UBLKSRV_IO_BUF_OFFSET 0x80000000
 #define UBLK_MAX_QUEUE_DEPTH 4096
+#define UBLK_IO_BUF_OFF 0
+#define UBLK_IO_BUF_BITS 25
+#define UBLK_IO_BUF_BITS_MASK ((1ULL << UBLK_IO_BUF_BITS) - 1)
+#define UBLK_TAG_OFF UBLK_IO_BUF_BITS
+#define UBLK_TAG_BITS 16
+#define UBLK_TAG_BITS_MASK ((1ULL << UBLK_TAG_BITS) - 1)
+#define UBLK_QID_OFF (UBLK_TAG_OFF + UBLK_TAG_BITS)
+#define UBLK_QID_BITS 12
+#define UBLK_QID_BITS_MASK ((1ULL << UBLK_QID_BITS) - 1)
+#define UBLK_MAX_NR_QUEUES (1U << UBLK_QID_BITS)
+#define UBLKSRV_IO_BUF_TOTAL_BITS (UBLK_QID_OFF + UBLK_QID_BITS)
+#define UBLKSRV_IO_BUF_TOTAL_SIZE (1ULL << UBLKSRV_IO_BUF_TOTAL_BITS)
 #define UBLK_F_SUPPORT_ZERO_COPY (1ULL << 0)
 #define UBLK_F_URING_CMD_COMP_IN_TASK (1ULL << 1)
 #define UBLK_F_NEED_GET_DATA (1UL << 2)
 #define UBLK_F_USER_RECOVERY (1UL << 3)
 #define UBLK_F_USER_RECOVERY_REISSUE (1UL << 4)
 #define UBLK_F_UNPRIVILEGED_DEV (1UL << 5)
+#define UBLK_F_CMD_IOCTL_ENCODE (1UL << 6)
+#define UBLK_F_USER_COPY (1UL << 7)
 #define UBLK_S_DEV_DEAD 0
 #define UBLK_S_DEV_LIVE 1
 #define UBLK_S_DEV_QUIESCED 2
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 9ddc640..dd66991 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -203,7 +203,10 @@
 struct usb_string_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
-  __le16 wData[1];
+  union {
+    __le16 legacy_padding;
+    __DECLARE_FLEX_ARRAY(__le16, wData);
+  };
 } __attribute__((packed));
 struct usb_interface_descriptor {
   __u8 bLength;
@@ -441,7 +444,10 @@
 #define USB_SSP_MIN_RX_LANE_COUNT (0xf << 8)
 #define USB_SSP_MIN_TX_LANE_COUNT (0xf << 12)
   __le16 wReserved;
-  __le32 bmSublinkSpeedAttr[1];
+  union {
+    __le32 legacy_padding;
+    __DECLARE_FLEX_ARRAY(__le32, bmSublinkSpeedAttr);
+  };
 #define USB_SSP_SUBLINK_SPEED_SSID (0xf)
 #define USB_SSP_SUBLINK_SPEED_LSE (0x3 << 4)
 #define USB_SSP_SUBLINK_SPEED_LSE_BPS 0
diff --git a/libc/kernel/uapi/linux/user_events.h b/libc/kernel/uapi/linux/user_events.h
new file mode 100644
index 0000000..f26519e
--- /dev/null
+++ b/libc/kernel/uapi/linux/user_events.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USER_EVENTS_H
+#define _UAPI_LINUX_USER_EVENTS_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define USER_EVENTS_SYSTEM "user_events"
+#define USER_EVENTS_PREFIX "u:"
+#define DYN_LOC(offset,size) ((size) << 16 | (offset))
+struct user_reg {
+  __u32 size;
+  __u8 enable_bit;
+  __u8 enable_size;
+  __u16 flags;
+  __u64 enable_addr;
+  __u64 name_args;
+  __u32 write_index;
+} __attribute__((__packed__));
+struct user_unreg {
+  __u32 size;
+  __u8 disable_bit;
+  __u8 __reserved;
+  __u16 __reserved2;
+  __u64 disable_addr;
+} __attribute__((__packed__));
+#define DIAG_IOC_MAGIC '*'
+#define DIAG_IOCSREG _IOWR(DIAG_IOC_MAGIC, 0, struct user_reg *)
+#define DIAG_IOCSDEL _IOW(DIAG_IOC_MAGIC, 1, char *)
+#define DIAG_IOCSUNREG _IOW(DIAG_IOC_MAGIC, 2, struct user_unreg *)
+#endif
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index 09e0d80..816198f 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -23,7 +23,7 @@
 #define USERFAULTFD_IOC_NEW _IO(USERFAULTFD_IOC, 0x00)
 #define UFFD_API ((__u64) 0xAA)
 #define UFFD_API_REGISTER_MODES (UFFDIO_REGISTER_MODE_MISSING | UFFDIO_REGISTER_MODE_WP | UFFDIO_REGISTER_MODE_MINOR)
-#define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID | UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM | UFFD_FEATURE_EXACT_ADDRESS | UFFD_FEATURE_WP_HUGETLBFS_SHMEM)
+#define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID | UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM | UFFD_FEATURE_EXACT_ADDRESS | UFFD_FEATURE_WP_HUGETLBFS_SHMEM | UFFD_FEATURE_WP_UNPOPULATED)
 #define UFFD_API_IOCTLS ((__u64) 1 << _UFFDIO_REGISTER | (__u64) 1 << _UFFDIO_UNREGISTER | (__u64) 1 << _UFFDIO_API)
 #define UFFD_API_RANGE_IOCTLS ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_ZEROPAGE | (__u64) 1 << _UFFDIO_WRITEPROTECT | (__u64) 1 << _UFFDIO_CONTINUE)
 #define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_CONTINUE | (__u64) 1 << _UFFDIO_WRITEPROTECT)
@@ -99,6 +99,7 @@
 #define UFFD_FEATURE_MINOR_SHMEM (1 << 10)
 #define UFFD_FEATURE_EXACT_ADDRESS (1 << 11)
 #define UFFD_FEATURE_WP_HUGETLBFS_SHMEM (1 << 12)
+#define UFFD_FEATURE_WP_UNPOPULATED (1 << 13)
   __u64 features;
   __u64 ioctls;
 };
@@ -138,6 +139,7 @@
 struct uffdio_continue {
   struct uffdio_range range;
 #define UFFDIO_CONTINUE_MODE_DONTWAKE ((__u64) 1 << 0)
+#define UFFDIO_CONTINUE_MODE_WP ((__u64) 1 << 1)
   __u64 mode;
   __s64 mapped;
 };
diff --git a/libc/kernel/uapi/linux/uuid.h b/libc/kernel/uapi/linux/uuid.h
index 1505137..73529c9 100644
--- a/libc/kernel/uapi/linux/uuid.h
+++ b/libc/kernel/uapi/linux/uuid.h
@@ -16,14 +16,4 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _UAPI_LINUX_UUID_H_
-#define _UAPI_LINUX_UUID_H_
-#include <linux/types.h>
-typedef struct {
-  __u8 b[16];
-} uuid_le;
-#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((uuid_le) \
-{ { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
-#define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-#endif
+#include <linux/mei_uuid.h>
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index a6e70c0..d77be94 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -691,6 +691,39 @@
 #define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP (V4L2_CID_CODEC_BASE + 652)
 #define V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY (V4L2_CID_CODEC_BASE + 653)
 #define V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE (V4L2_CID_CODEC_BASE + 654)
+#define V4L2_CID_MPEG_VIDEO_AV1_PROFILE (V4L2_CID_CODEC_BASE + 655)
+enum v4l2_mpeg_video_av1_profile {
+  V4L2_MPEG_VIDEO_AV1_PROFILE_MAIN = 0,
+  V4L2_MPEG_VIDEO_AV1_PROFILE_HIGH = 1,
+  V4L2_MPEG_VIDEO_AV1_PROFILE_PROFESSIONAL = 2,
+};
+#define V4L2_CID_MPEG_VIDEO_AV1_LEVEL (V4L2_CID_CODEC_BASE + 656)
+enum v4l2_mpeg_video_av1_level {
+  V4L2_MPEG_VIDEO_AV1_LEVEL_2_0 = 0,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_2_1 = 1,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_2_2 = 2,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_2_3 = 3,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_3_0 = 4,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_3_1 = 5,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_3_2 = 6,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_3_3 = 7,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_4_0 = 8,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_4_1 = 9,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_4_2 = 10,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_4_3 = 11,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_5_0 = 12,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_5_1 = 13,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_5_2 = 14,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_5_3 = 15,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_6_0 = 16,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_6_1 = 17,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_6_2 = 18,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_6_3 = 19,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_7_0 = 20,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_7_1 = 21,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_7_2 = 22,
+  V4L2_MPEG_VIDEO_AV1_LEVEL_7_3 = 23
+};
 #define V4L2_CID_CODEC_CX2341X_BASE (V4L2_CTRL_CLASS_CODEC | 0x1000)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_CODEC_CX2341X_BASE + 0)
 enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
@@ -1520,7 +1553,8 @@
   __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
   __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
   __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
-  __u8 reserved[4];
+  __u8 num_delta_pocs_of_ref_rps_idx;
+  __u8 reserved[3];
   struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
   __u64 flags;
 };
@@ -1684,6 +1718,271 @@
   __u8 partition[16][3];
   struct v4l2_vp9_mv_probs mv;
 };
+#define V4L2_AV1_TOTAL_REFS_PER_FRAME 8
+#define V4L2_AV1_CDEF_MAX 8
+#define V4L2_AV1_NUM_PLANES_MAX 3
+#define V4L2_AV1_MAX_SEGMENTS 8
+#define V4L2_AV1_MAX_OPERATING_POINTS (1 << 5)
+#define V4L2_AV1_REFS_PER_FRAME 7
+#define V4L2_AV1_MAX_NUM_Y_POINTS (1 << 4)
+#define V4L2_AV1_MAX_NUM_CB_POINTS (1 << 4)
+#define V4L2_AV1_MAX_NUM_CR_POINTS (1 << 4)
+#define V4L2_AV1_AR_COEFFS_SIZE 25
+#define V4L2_AV1_MAX_NUM_PLANES 3
+#define V4L2_AV1_MAX_TILE_COLS 64
+#define V4L2_AV1_MAX_TILE_ROWS 64
+#define V4L2_AV1_MAX_TILE_COUNT 512
+#define V4L2_AV1_SEQUENCE_FLAG_STILL_PICTURE 0x00000001
+#define V4L2_AV1_SEQUENCE_FLAG_USE_128X128_SUPERBLOCK 0x00000002
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_FILTER_INTRA 0x00000004
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_INTRA_EDGE_FILTER 0x00000008
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_INTERINTRA_COMPOUND 0x00000010
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_MASKED_COMPOUND 0x00000020
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_WARPED_MOTION 0x00000040
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_DUAL_FILTER 0x00000080
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_ORDER_HINT 0x00000100
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_JNT_COMP 0x00000200
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_REF_FRAME_MVS 0x00000400
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_SUPERRES 0x00000800
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_CDEF 0x00001000
+#define V4L2_AV1_SEQUENCE_FLAG_ENABLE_RESTORATION 0x00002000
+#define V4L2_AV1_SEQUENCE_FLAG_MONO_CHROME 0x00004000
+#define V4L2_AV1_SEQUENCE_FLAG_COLOR_RANGE 0x00008000
+#define V4L2_AV1_SEQUENCE_FLAG_SUBSAMPLING_X 0x00010000
+#define V4L2_AV1_SEQUENCE_FLAG_SUBSAMPLING_Y 0x00020000
+#define V4L2_AV1_SEQUENCE_FLAG_FILM_GRAIN_PARAMS_PRESENT 0x00040000
+#define V4L2_AV1_SEQUENCE_FLAG_SEPARATE_UV_DELTA_Q 0x00080000
+#define V4L2_CID_STATELESS_AV1_SEQUENCE (V4L2_CID_CODEC_STATELESS_BASE + 500)
+struct v4l2_ctrl_av1_sequence {
+  __u32 flags;
+  __u8 seq_profile;
+  __u8 order_hint_bits;
+  __u8 bit_depth;
+  __u8 reserved;
+  __u16 max_frame_width_minus_1;
+  __u16 max_frame_height_minus_1;
+};
+#define V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY (V4L2_CID_CODEC_STATELESS_BASE + 501)
+struct v4l2_ctrl_av1_tile_group_entry {
+  __u32 tile_offset;
+  __u32 tile_size;
+  __u32 tile_row;
+  __u32 tile_col;
+};
+enum v4l2_av1_warp_model {
+  V4L2_AV1_WARP_MODEL_IDENTITY = 0,
+  V4L2_AV1_WARP_MODEL_TRANSLATION = 1,
+  V4L2_AV1_WARP_MODEL_ROTZOOM = 2,
+  V4L2_AV1_WARP_MODEL_AFFINE = 3,
+};
+enum v4l2_av1_reference_frame {
+  V4L2_AV1_REF_INTRA_FRAME = 0,
+  V4L2_AV1_REF_LAST_FRAME = 1,
+  V4L2_AV1_REF_LAST2_FRAME = 2,
+  V4L2_AV1_REF_LAST3_FRAME = 3,
+  V4L2_AV1_REF_GOLDEN_FRAME = 4,
+  V4L2_AV1_REF_BWDREF_FRAME = 5,
+  V4L2_AV1_REF_ALTREF2_FRAME = 6,
+  V4L2_AV1_REF_ALTREF_FRAME = 7,
+};
+#define V4L2_AV1_GLOBAL_MOTION_IS_INVALID(ref) (1 << (ref))
+#define V4L2_AV1_GLOBAL_MOTION_FLAG_IS_GLOBAL 0x1
+#define V4L2_AV1_GLOBAL_MOTION_FLAG_IS_ROT_ZOOM 0x2
+#define V4L2_AV1_GLOBAL_MOTION_FLAG_IS_TRANSLATION 0x4
+struct v4l2_av1_global_motion {
+  __u8 flags[V4L2_AV1_TOTAL_REFS_PER_FRAME];
+  enum v4l2_av1_warp_model type[V4L2_AV1_TOTAL_REFS_PER_FRAME];
+  __s32 params[V4L2_AV1_TOTAL_REFS_PER_FRAME][6];
+  __u8 invalid;
+  __u8 reserved[3];
+};
+enum v4l2_av1_frame_restoration_type {
+  V4L2_AV1_FRAME_RESTORE_NONE = 0,
+  V4L2_AV1_FRAME_RESTORE_WIENER = 1,
+  V4L2_AV1_FRAME_RESTORE_SGRPROJ = 2,
+  V4L2_AV1_FRAME_RESTORE_SWITCHABLE = 3,
+};
+#define V4L2_AV1_LOOP_RESTORATION_FLAG_USES_LR 0x1
+#define V4L2_AV1_LOOP_RESTORATION_FLAG_USES_CHROMA_LR 0x2
+struct v4l2_av1_loop_restoration {
+  __u8 flags;
+  __u8 lr_unit_shift;
+  __u8 lr_uv_shift;
+  __u8 reserved;
+  enum v4l2_av1_frame_restoration_type frame_restoration_type[V4L2_AV1_NUM_PLANES_MAX];
+  __u32 loop_restoration_size[V4L2_AV1_MAX_NUM_PLANES];
+};
+struct v4l2_av1_cdef {
+  __u8 damping_minus_3;
+  __u8 bits;
+  __u8 y_pri_strength[V4L2_AV1_CDEF_MAX];
+  __u8 y_sec_strength[V4L2_AV1_CDEF_MAX];
+  __u8 uv_pri_strength[V4L2_AV1_CDEF_MAX];
+  __u8 uv_sec_strength[V4L2_AV1_CDEF_MAX];
+};
+#define V4L2_AV1_SEGMENTATION_FLAG_ENABLED 0x1
+#define V4L2_AV1_SEGMENTATION_FLAG_UPDATE_MAP 0x2
+#define V4L2_AV1_SEGMENTATION_FLAG_TEMPORAL_UPDATE 0x4
+#define V4L2_AV1_SEGMENTATION_FLAG_UPDATE_DATA 0x8
+#define V4L2_AV1_SEGMENTATION_FLAG_SEG_ID_PRE_SKIP 0x10
+enum v4l2_av1_segment_feature {
+  V4L2_AV1_SEG_LVL_ALT_Q = 0,
+  V4L2_AV1_SEG_LVL_ALT_LF_Y_V = 1,
+  V4L2_AV1_SEG_LVL_REF_FRAME = 5,
+  V4L2_AV1_SEG_LVL_REF_SKIP = 6,
+  V4L2_AV1_SEG_LVL_REF_GLOBALMV = 7,
+  V4L2_AV1_SEG_LVL_MAX = 8
+};
+#define V4L2_AV1_SEGMENT_FEATURE_ENABLED(id) (1 << (id))
+struct v4l2_av1_segmentation {
+  __u8 flags;
+  __u8 last_active_seg_id;
+  __u8 feature_enabled[V4L2_AV1_MAX_SEGMENTS];
+  __s16 feature_data[V4L2_AV1_MAX_SEGMENTS][V4L2_AV1_SEG_LVL_MAX];
+};
+#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_ENABLED 0x1
+#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_UPDATE 0x2
+#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_PRESENT 0x4
+#define V4L2_AV1_LOOP_FILTER_FLAG_DELTA_LF_MULTI 0x8
+struct v4l2_av1_loop_filter {
+  __u8 flags;
+  __u8 level[4];
+  __u8 sharpness;
+  __s8 ref_deltas[V4L2_AV1_TOTAL_REFS_PER_FRAME];
+  __s8 mode_deltas[2];
+  __u8 delta_lf_res;
+};
+#define V4L2_AV1_QUANTIZATION_FLAG_DIFF_UV_DELTA 0x1
+#define V4L2_AV1_QUANTIZATION_FLAG_USING_QMATRIX 0x2
+#define V4L2_AV1_QUANTIZATION_FLAG_DELTA_Q_PRESENT 0x4
+struct v4l2_av1_quantization {
+  __u8 flags;
+  __u8 base_q_idx;
+  __s8 delta_q_y_dc;
+  __s8 delta_q_u_dc;
+  __s8 delta_q_u_ac;
+  __s8 delta_q_v_dc;
+  __s8 delta_q_v_ac;
+  __u8 qm_y;
+  __u8 qm_u;
+  __u8 qm_v;
+  __u8 delta_q_res;
+};
+#define V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING 0x1
+struct v4l2_av1_tile_info {
+  __u8 flags;
+  __u8 context_update_tile_id;
+  __u8 tile_cols;
+  __u8 tile_rows;
+  __u32 mi_col_starts[V4L2_AV1_MAX_TILE_COLS + 1];
+  __u32 mi_row_starts[V4L2_AV1_MAX_TILE_ROWS + 1];
+  __u32 width_in_sbs_minus_1[V4L2_AV1_MAX_TILE_COLS];
+  __u32 height_in_sbs_minus_1[V4L2_AV1_MAX_TILE_ROWS];
+  __u8 tile_size_bytes;
+  __u8 reserved[3];
+};
+enum v4l2_av1_frame_type {
+  V4L2_AV1_KEY_FRAME = 0,
+  V4L2_AV1_INTER_FRAME = 1,
+  V4L2_AV1_INTRA_ONLY_FRAME = 2,
+  V4L2_AV1_SWITCH_FRAME = 3
+};
+enum v4l2_av1_interpolation_filter {
+  V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP = 0,
+  V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH = 1,
+  V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP = 2,
+  V4L2_AV1_INTERPOLATION_FILTER_BILINEAR = 3,
+  V4L2_AV1_INTERPOLATION_FILTER_SWITCHABLE = 4,
+};
+enum v4l2_av1_tx_mode {
+  V4L2_AV1_TX_MODE_ONLY_4X4 = 0,
+  V4L2_AV1_TX_MODE_LARGEST = 1,
+  V4L2_AV1_TX_MODE_SELECT = 2
+};
+#define V4L2_AV1_FRAME_FLAG_SHOW_FRAME 0x00000001
+#define V4L2_AV1_FRAME_FLAG_SHOWABLE_FRAME 0x00000002
+#define V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE 0x00000004
+#define V4L2_AV1_FRAME_FLAG_DISABLE_CDF_UPDATE 0x00000008
+#define V4L2_AV1_FRAME_FLAG_ALLOW_SCREEN_CONTENT_TOOLS 0x00000010
+#define V4L2_AV1_FRAME_FLAG_FORCE_INTEGER_MV 0x00000020
+#define V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC 0x00000040
+#define V4L2_AV1_FRAME_FLAG_USE_SUPERRES 0x00000080
+#define V4L2_AV1_FRAME_FLAG_ALLOW_HIGH_PRECISION_MV 0x00000100
+#define V4L2_AV1_FRAME_FLAG_IS_MOTION_MODE_SWITCHABLE 0x00000200
+#define V4L2_AV1_FRAME_FLAG_USE_REF_FRAME_MVS 0x00000400
+#define V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF 0x00000800
+#define V4L2_AV1_FRAME_FLAG_ALLOW_WARPED_MOTION 0x00001000
+#define V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT 0x00002000
+#define V4L2_AV1_FRAME_FLAG_REDUCED_TX_SET 0x00004000
+#define V4L2_AV1_FRAME_FLAG_SKIP_MODE_ALLOWED 0x00008000
+#define V4L2_AV1_FRAME_FLAG_SKIP_MODE_PRESENT 0x00010000
+#define V4L2_AV1_FRAME_FLAG_FRAME_SIZE_OVERRIDE 0x00020000
+#define V4L2_AV1_FRAME_FLAG_BUFFER_REMOVAL_TIME_PRESENT 0x00040000
+#define V4L2_AV1_FRAME_FLAG_FRAME_REFS_SHORT_SIGNALING 0x00080000
+#define V4L2_CID_STATELESS_AV1_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 502)
+struct v4l2_ctrl_av1_frame {
+  struct v4l2_av1_tile_info tile_info;
+  struct v4l2_av1_quantization quantization;
+  __u8 superres_denom;
+  struct v4l2_av1_segmentation segmentation;
+  struct v4l2_av1_loop_filter loop_filter;
+  struct v4l2_av1_cdef cdef;
+  __u8 skip_mode_frame[2];
+  __u8 primary_ref_frame;
+  struct v4l2_av1_loop_restoration loop_restoration;
+  struct v4l2_av1_global_motion global_motion;
+  __u32 flags;
+  enum v4l2_av1_frame_type frame_type;
+  __u32 order_hint;
+  __u32 upscaled_width;
+  enum v4l2_av1_interpolation_filter interpolation_filter;
+  enum v4l2_av1_tx_mode tx_mode;
+  __u32 frame_width_minus_1;
+  __u32 frame_height_minus_1;
+  __u16 render_width_minus_1;
+  __u16 render_height_minus_1;
+  __u32 current_frame_id;
+  __u32 buffer_removal_time[V4L2_AV1_MAX_OPERATING_POINTS];
+  __u8 reserved[4];
+  __u32 order_hints[V4L2_AV1_TOTAL_REFS_PER_FRAME];
+  __u64 reference_frame_ts[V4L2_AV1_TOTAL_REFS_PER_FRAME];
+  __s8 ref_frame_idx[V4L2_AV1_REFS_PER_FRAME];
+  __u8 refresh_frame_flags;
+};
+#define V4L2_AV1_FILM_GRAIN_FLAG_APPLY_GRAIN 0x1
+#define V4L2_AV1_FILM_GRAIN_FLAG_UPDATE_GRAIN 0x2
+#define V4L2_AV1_FILM_GRAIN_FLAG_CHROMA_SCALING_FROM_LUMA 0x4
+#define V4L2_AV1_FILM_GRAIN_FLAG_OVERLAP 0x8
+#define V4L2_AV1_FILM_GRAIN_FLAG_CLIP_TO_RESTRICTED_RANGE 0x10
+#define V4L2_CID_STATELESS_AV1_FILM_GRAIN (V4L2_CID_CODEC_STATELESS_BASE + 505)
+struct v4l2_ctrl_av1_film_grain {
+  __u8 flags;
+  __u8 cr_mult;
+  __u16 grain_seed;
+  __u8 film_grain_params_ref_idx;
+  __u8 num_y_points;
+  __u8 point_y_value[V4L2_AV1_MAX_NUM_Y_POINTS];
+  __u8 point_y_scaling[V4L2_AV1_MAX_NUM_Y_POINTS];
+  __u8 num_cb_points;
+  __u8 point_cb_value[V4L2_AV1_MAX_NUM_CB_POINTS];
+  __u8 point_cb_scaling[V4L2_AV1_MAX_NUM_CB_POINTS];
+  __u8 num_cr_points;
+  __u8 point_cr_value[V4L2_AV1_MAX_NUM_CR_POINTS];
+  __u8 point_cr_scaling[V4L2_AV1_MAX_NUM_CR_POINTS];
+  __u8 grain_scaling_minus_8;
+  __u8 ar_coeff_lag;
+  __u8 ar_coeffs_y_plus_128[V4L2_AV1_AR_COEFFS_SIZE];
+  __u8 ar_coeffs_cb_plus_128[V4L2_AV1_AR_COEFFS_SIZE];
+  __u8 ar_coeffs_cr_plus_128[V4L2_AV1_AR_COEFFS_SIZE];
+  __u8 ar_coeff_shift_minus_6;
+  __u8 grain_scale_shift;
+  __u8 cb_mult;
+  __u8 cb_luma_mult;
+  __u8 cr_luma_mult;
+  __u16 cb_offset;
+  __u16 cr_offset;
+  __u8 reserved[4];
+};
 #define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC
 #define V4L2_CID_MPEG_CLASS V4L2_CID_CODEC_CLASS
 #define V4L2_CID_MPEG_BASE V4L2_CID_CODEC_BASE
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 8b2c1bd..55d7192 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -115,6 +115,10 @@
   __u64 routes;
   __u32 reserved[6];
 };
+#define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1U << 0)
+struct v4l2_subdev_client_capability {
+  __u64 capabilities;
+};
 #define v4l2_subdev_edid v4l2_edid
 #define VIDIOC_SUBDEV_QUERYCAP _IOR('V', 0, struct v4l2_subdev_capability)
 #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
@@ -130,6 +134,8 @@
 #define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection)
 #define VIDIOC_SUBDEV_G_ROUTING _IOWR('V', 38, struct v4l2_subdev_routing)
 #define VIDIOC_SUBDEV_S_ROUTING _IOWR('V', 39, struct v4l2_subdev_routing)
+#define VIDIOC_SUBDEV_G_CLIENT_CAP _IOR('V', 101, struct v4l2_subdev_client_capability)
+#define VIDIOC_SUBDEV_S_CLIENT_CAP _IOWR('V', 102, struct v4l2_subdev_client_capability)
 #define VIDIOC_SUBDEV_G_STD _IOR('V', 23, v4l2_std_id)
 #define VIDIOC_SUBDEV_S_STD _IOW('V', 24, v4l2_std_id)
 #define VIDIOC_SUBDEV_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 9d48e3d..52d0113 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 393984
+#define LINUX_VERSION_CODE 394496
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
 #define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 3
+#define LINUX_VERSION_PATCHLEVEL 5
 #define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index 3c1821c..b404238 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -62,6 +62,7 @@
 #define VFIO_DEVICE_FLAGS_AP (1 << 5)
 #define VFIO_DEVICE_FLAGS_FSL_MC (1 << 6)
 #define VFIO_DEVICE_FLAGS_CAPS (1 << 7)
+#define VFIO_DEVICE_FLAGS_CDX (1 << 8)
   __u32 num_regions;
   __u32 num_irqs;
   __u32 cap_offset;
@@ -76,6 +77,15 @@
 #define VFIO_DEVICE_INFO_CAP_ZPCI_GROUP 2
 #define VFIO_DEVICE_INFO_CAP_ZPCI_UTIL 3
 #define VFIO_DEVICE_INFO_CAP_ZPCI_PFIP 4
+#define VFIO_DEVICE_INFO_CAP_PCI_ATOMIC_COMP 5
+struct vfio_device_info_cap_pci_atomic_comp {
+  struct vfio_info_cap_header header;
+  __u32 flags;
+#define VFIO_PCI_ATOMIC_COMP32 (1 << 0)
+#define VFIO_PCI_ATOMIC_COMP64 (1 << 1)
+#define VFIO_PCI_ATOMIC_COMP128 (1 << 2)
+  __u32 reserved;
+};
 struct vfio_region_info {
   __u32 argsz;
   __u32 flags;
@@ -217,6 +227,10 @@
   VFIO_CCW_REQ_IRQ_INDEX,
   VFIO_CCW_NUM_IRQS
 };
+enum {
+  VFIO_AP_REQ_IRQ_INDEX,
+  VFIO_AP_NUM_IRQS
+};
 struct vfio_pci_dependent_device {
   __u32 group_id;
   __u16 segment;
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index 5138f0c..7e0a55a 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -30,6 +30,8 @@
 #define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, struct vhost_memory)
 #define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64)
 #define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int)
+#define VHOST_NEW_WORKER _IOR(VHOST_VIRTIO, 0x8, struct vhost_worker_state)
+#define VHOST_FREE_WORKER _IOW(VHOST_VIRTIO, 0x9, struct vhost_worker_state)
 #define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state)
 #define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr)
 #define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
@@ -38,6 +40,8 @@
 #define VHOST_VRING_BIG_ENDIAN 1
 #define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state)
 #define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state)
+#define VHOST_ATTACH_VRING_WORKER _IOW(VHOST_VIRTIO, 0x15, struct vhost_vring_worker)
+#define VHOST_GET_VRING_WORKER _IOWR(VHOST_VIRTIO, 0x16, struct vhost_vring_worker)
 #define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file)
 #define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)
 #define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
diff --git a/libc/kernel/uapi/linux/vhost_types.h b/libc/kernel/uapi/linux/vhost_types.h
index 1669c28..1cd6965 100644
--- a/libc/kernel/uapi/linux/vhost_types.h
+++ b/libc/kernel/uapi/linux/vhost_types.h
@@ -39,6 +39,13 @@
   __u64 avail_user_addr;
   __u64 log_guest_addr;
 };
+struct vhost_worker_state {
+  unsigned int worker_id;
+};
+struct vhost_vring_worker {
+  unsigned int index;
+  unsigned int worker_id;
+};
 struct vhost_iotlb_msg {
   __u64 iova;
   __u64 size;
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 95c2d94..2cd1beb 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -247,11 +247,14 @@
 #define V4L2_PIX_FMT_RGBX1010102 v4l2_fourcc('R', 'X', '3', '0')
 #define V4L2_PIX_FMT_RGBA1010102 v4l2_fourcc('R', 'A', '3', '0')
 #define V4L2_PIX_FMT_ARGB2101010 v4l2_fourcc('A', 'R', '3', '0')
+#define V4L2_PIX_FMT_BGR48_12 v4l2_fourcc('B', '3', '1', '2')
+#define V4L2_PIX_FMT_ABGR64_12 v4l2_fourcc('B', '4', '1', '2')
 #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y')
 #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
 #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ')
 #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ')
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ')
+#define V4L2_PIX_FMT_Y012 v4l2_fourcc('Y', '0', '1', '2')
 #define V4L2_PIX_FMT_Y14 v4l2_fourcc('Y', '1', '4', ' ')
 #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')
 #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ')
@@ -278,6 +281,7 @@
 #define V4L2_PIX_FMT_YUVA32 v4l2_fourcc('Y', 'U', 'V', 'A')
 #define V4L2_PIX_FMT_YUVX32 v4l2_fourcc('Y', 'U', 'V', 'X')
 #define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0')
+#define V4L2_PIX_FMT_YUV48_12 v4l2_fourcc('Y', '3', '1', '2')
 #define V4L2_PIX_FMT_Y210 v4l2_fourcc('Y', '2', '1', '0')
 #define V4L2_PIX_FMT_Y212 v4l2_fourcc('Y', '2', '1', '2')
 #define V4L2_PIX_FMT_Y216 v4l2_fourcc('Y', '2', '1', '6')
@@ -288,10 +292,12 @@
 #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4')
 #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2')
 #define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0')
+#define V4L2_PIX_FMT_P012 v4l2_fourcc('P', '0', '1', '2')
 #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2')
 #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1')
 #define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6')
 #define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1')
+#define V4L2_PIX_FMT_P012M v4l2_fourcc('P', 'M', '1', '2')
 #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9')
 #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9')
 #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P')
@@ -307,6 +313,7 @@
 #define V4L2_PIX_FMT_NV12_4L4 v4l2_fourcc('V', 'T', '1', '2')
 #define V4L2_PIX_FMT_NV12_16L16 v4l2_fourcc('H', 'M', '1', '2')
 #define V4L2_PIX_FMT_NV12_32L32 v4l2_fourcc('S', 'T', '1', '2')
+#define V4L2_PIX_FMT_NV15_4L4 v4l2_fourcc('V', 'T', '1', '5')
 #define V4L2_PIX_FMT_P010_4L4 v4l2_fourcc('T', '0', '1', '0')
 #define V4L2_PIX_FMT_NV12_8L128 v4l2_fourcc('A', 'T', '1', '2')
 #define V4L2_PIX_FMT_NV12_10BE_8L128 v4l2_fourcc_be('A', 'X', '1', '2')
@@ -380,6 +387,10 @@
 #define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H')
 #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4')
 #define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5')
+#define V4L2_PIX_FMT_AV1_FRAME v4l2_fourcc('A', 'V', '1', 'F')
+#define V4L2_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0')
+#define V4L2_PIX_FMT_RV30 v4l2_fourcc('R', 'V', '3', '0')
+#define V4L2_PIX_FMT_RV40 v4l2_fourcc('R', 'V', '4', '0')
 #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A')
 #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A')
 #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0')
@@ -905,8 +916,8 @@
     __u8  * p_u8;
     __u16  * p_u16;
     __u32  * p_u32;
-    __u32  * p_s32;
-    __u32  * p_s64;
+    __s32  * p_s32;
+    __s64  * p_s64;
     struct v4l2_area  * p_area;
     struct v4l2_ctrl_h264_sps  * p_h264_sps;
     struct v4l2_ctrl_h264_pps * p_h264_pps;
@@ -926,6 +937,10 @@
     struct v4l2_ctrl_hevc_slice_params  * p_hevc_slice_params;
     struct v4l2_ctrl_hevc_scaling_matrix  * p_hevc_scaling_matrix;
     struct v4l2_ctrl_hevc_decode_params  * p_hevc_decode_params;
+    struct v4l2_ctrl_av1_sequence  * p_av1_sequence;
+    struct v4l2_ctrl_av1_tile_group_entry  * p_av1_tile_group_entry;
+    struct v4l2_ctrl_av1_frame  * p_av1_frame;
+    struct v4l2_ctrl_av1_film_grain  * p_av1_film_grain;
     void  * ptr;
   };
 } __attribute__((packed));
@@ -983,6 +998,10 @@
   V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS = 0x0272,
   V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX = 0x0273,
   V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS = 0x0274,
+  V4L2_CTRL_TYPE_AV1_SEQUENCE = 0x280,
+  V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY = 0x281,
+  V4L2_CTRL_TYPE_AV1_FRAME = 0x282,
+  V4L2_CTRL_TYPE_AV1_FILM_GRAIN = 0x283,
 };
 struct v4l2_queryctrl {
   __u32 id;
diff --git a/libc/kernel/uapi/linux/virtio_config.h b/libc/kernel/uapi/linux/virtio_config.h
index bdd2e73..152d854 100644
--- a/libc/kernel/uapi/linux/virtio_config.h
+++ b/libc/kernel/uapi/linux/virtio_config.h
@@ -38,5 +38,6 @@
 #define VIRTIO_F_IN_ORDER 35
 #define VIRTIO_F_ORDER_PLATFORM 36
 #define VIRTIO_F_SR_IOV 37
+#define VIRTIO_F_NOTIFICATION_DATA 38
 #define VIRTIO_F_RING_RESET 40
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_net.h b/libc/kernel/uapi/linux/virtio_net.h
index da7285e..d2554a0 100644
--- a/libc/kernel/uapi/linux/virtio_net.h
+++ b/libc/kernel/uapi/linux/virtio_net.h
@@ -50,6 +50,7 @@
 #define VIRTIO_NET_F_GUEST_USO6 55
 #define VIRTIO_NET_F_HOST_USO 56
 #define VIRTIO_NET_F_HASH_REPORT 57
+#define VIRTIO_NET_F_GUEST_HDRLEN 59
 #define VIRTIO_NET_F_RSS 60
 #define VIRTIO_NET_F_RSC_EXT 61
 #define VIRTIO_NET_F_STANDBY 62
diff --git a/libc/kernel/uapi/linux/wireless.h b/libc/kernel/uapi/linux/wireless.h
index eb57fff..e6b0330 100644
--- a/libc/kernel/uapi/linux/wireless.h
+++ b/libc/kernel/uapi/linux/wireless.h
@@ -314,7 +314,7 @@
   struct sockaddr addr;
   __u16 alg;
   __u16 key_len;
-  __u8 key[0];
+  __u8 key[];
 };
 struct iw_mlme {
   __u16 cmd;
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 62ba685..68cb06a 100644
--- a/libc/kernel/uapi/rdma/bnxt_re-abi.h
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -19,6 +19,7 @@
 #ifndef __BNXT_RE_UVERBS_ABI_H__
 #define __BNXT_RE_UVERBS_ABI_H__
 #include <linux/types.h>
+#include <rdma/ib_user_ioctl_cmds.h>
 #define BNXT_RE_ABI_VERSION 1
 #define BNXT_RE_CHIP_ID0_CHIP_NUM_SFT 0x00
 #define BNXT_RE_CHIP_ID0_CHIP_REV_SFT 0x10
@@ -26,6 +27,7 @@
 enum {
   BNXT_RE_UCNTX_CMASK_HAVE_CCTX = 0x1ULL,
   BNXT_RE_UCNTX_CMASK_HAVE_MODE = 0x02ULL,
+  BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED = 0x04ULL,
 };
 enum bnxt_re_wqe_mode {
   BNXT_QPLIB_WQE_MODE_STATIC = 0x00,
@@ -60,6 +62,9 @@
   __u32 phase;
   __u32 rsvd;
 };
+struct bnxt_re_resize_cq_req {
+  __aligned_u64 cq_va;
+};
 struct bnxt_re_qp_req {
   __aligned_u64 qpsva;
   __aligned_u64 qprva;
@@ -82,4 +87,24 @@
   BNXT_RE_AVID_SIZE = 0x04,
   BNXT_RE_END_RESV_OFFT = 0xFF0
 };
+enum bnxt_re_objects {
+  BNXT_RE_OBJECT_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum bnxt_re_alloc_page_type {
+  BNXT_RE_ALLOC_WC_PAGE = 0,
+};
+enum bnxt_re_var_alloc_page_attrs {
+  BNXT_RE_ALLOC_PAGE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  BNXT_RE_ALLOC_PAGE_TYPE,
+  BNXT_RE_ALLOC_PAGE_DPI,
+  BNXT_RE_ALLOC_PAGE_MMAP_OFFSET,
+  BNXT_RE_ALLOC_PAGE_MMAP_LENGTH,
+};
+enum bnxt_re_alloc_page_attrs {
+  BNXT_RE_DESTROY_PAGE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum bnxt_re_alloc_page_methods {
+  BNXT_RE_METHOD_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT),
+  BNXT_RE_METHOD_DESTROY_PAGE,
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/efa-abi.h b/libc/kernel/uapi/rdma/efa-abi.h
index bfb3f18..aab5902 100644
--- a/libc/kernel/uapi/rdma/efa-abi.h
+++ b/libc/kernel/uapi/rdma/efa-abi.h
@@ -104,6 +104,8 @@
   EFA_QUERY_DEVICE_CAPS_RNR_RETRY = 1 << 1,
   EFA_QUERY_DEVICE_CAPS_CQ_NOTIFICATIONS = 1 << 2,
   EFA_QUERY_DEVICE_CAPS_CQ_WITH_SGID = 1 << 3,
+  EFA_QUERY_DEVICE_CAPS_DATA_POLLING_128 = 1 << 4,
+  EFA_QUERY_DEVICE_CAPS_RDMA_WRITE = 1 << 5,
 };
 struct efa_ibv_ex_query_device_resp {
   __u32 comp_mask;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
index 036243e..b820c07 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
@@ -51,6 +51,18 @@
   __be32 value;
   __be32 reserved[2];
 };
+struct utp_upiu_query_v4_0 {
+  __u8 opcode;
+  __u8 idn;
+  __u8 index;
+  __u8 selector;
+  __u8 osf3;
+  __u8 osf4;
+  __be16 osf5;
+  __be32 osf6;
+  __be32 osf7;
+  __be32 reserved;
+};
 struct utp_upiu_cmd {
   __be32 exp_data_transfer_len;
   __u8 cdb[UFS_CDB_SIZE];
diff --git a/libc/kernel/uapi/sound/asequencer.h b/libc/kernel/uapi/sound/asequencer.h
index 01a5058..e90e812 100644
--- a/libc/kernel/uapi/sound/asequencer.h
+++ b/libc/kernel/uapi/sound/asequencer.h
@@ -19,7 +19,7 @@
 #ifndef _UAPI__SOUND_ASEQUENCER_H
 #define _UAPI__SOUND_ASEQUENCER_H
 #include <sound/asound.h>
-#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 2)
+#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 3)
 #define SNDRV_SEQ_EVENT_SYSTEM 0
 #define SNDRV_SEQ_EVENT_RESULT 1
 #define SNDRV_SEQ_EVENT_NOTE 5
@@ -106,6 +106,7 @@
 #define SNDRV_SEQ_PRIORITY_NORMAL (0 << 4)
 #define SNDRV_SEQ_PRIORITY_HIGH (1 << 4)
 #define SNDRV_SEQ_PRIORITY_MASK (1 << 4)
+#define SNDRV_SEQ_EVENT_UMP (1 << 5)
 struct snd_seq_ev_note {
   unsigned char channel;
   unsigned char note;
@@ -163,6 +164,19 @@
   unsigned short value;
   struct snd_seq_event * event;
 } __attribute__((packed));
+union snd_seq_event_data {
+  struct snd_seq_ev_note note;
+  struct snd_seq_ev_ctrl control;
+  struct snd_seq_ev_raw8 raw8;
+  struct snd_seq_ev_raw32 raw32;
+  struct snd_seq_ev_ext ext;
+  struct snd_seq_ev_queue_control queue;
+  union snd_seq_timestamp time;
+  struct snd_seq_addr addr;
+  struct snd_seq_connect connect;
+  struct snd_seq_result result;
+  struct snd_seq_ev_quote quote;
+};
 struct snd_seq_event {
   snd_seq_event_type_t type;
   unsigned char flags;
@@ -171,19 +185,20 @@
   union snd_seq_timestamp time;
   struct snd_seq_addr source;
   struct snd_seq_addr dest;
+  union snd_seq_event_data data;
+};
+struct snd_seq_ump_event {
+  snd_seq_event_type_t type;
+  unsigned char flags;
+  char tag;
+  unsigned char queue;
+  union snd_seq_timestamp time;
+  struct snd_seq_addr source;
+  struct snd_seq_addr dest;
   union {
-    struct snd_seq_ev_note note;
-    struct snd_seq_ev_ctrl control;
-    struct snd_seq_ev_raw8 raw8;
-    struct snd_seq_ev_raw32 raw32;
-    struct snd_seq_ev_ext ext;
-    struct snd_seq_ev_queue_control queue;
-    union snd_seq_timestamp time;
-    struct snd_seq_addr addr;
-    struct snd_seq_connect connect;
-    struct snd_seq_result result;
-    struct snd_seq_ev_quote quote;
-  } data;
+    union snd_seq_event_data data;
+    unsigned int ump[4];
+  };
 };
 struct snd_seq_event_bounce {
   int err;
@@ -215,6 +230,7 @@
 #define SNDRV_SEQ_FILTER_BROADCAST (1U << 0)
 #define SNDRV_SEQ_FILTER_MULTICAST (1U << 1)
 #define SNDRV_SEQ_FILTER_BOUNCE (1U << 2)
+#define SNDRV_SEQ_FILTER_NO_CONVERT (1U << 30)
 #define SNDRV_SEQ_FILTER_USE_EVENT (1U << 31)
 struct snd_seq_client_info {
   int client;
@@ -227,8 +243,13 @@
   int event_lost;
   int card;
   int pid;
-  char reserved[56];
+  unsigned int midi_version;
+  unsigned int group_filter;
+  char reserved[48];
 };
+#define SNDRV_SEQ_CLIENT_LEGACY_MIDI 0
+#define SNDRV_SEQ_CLIENT_UMP_MIDI_1_0 1
+#define SNDRV_SEQ_CLIENT_UMP_MIDI_2_0 2
 struct snd_seq_client_pool {
   int client;
   int output_pool;
@@ -268,6 +289,8 @@
 #define SNDRV_SEQ_PORT_CAP_SUBS_READ (1 << 5)
 #define SNDRV_SEQ_PORT_CAP_SUBS_WRITE (1 << 6)
 #define SNDRV_SEQ_PORT_CAP_NO_EXPORT (1 << 7)
+#define SNDRV_SEQ_PORT_CAP_INACTIVE (1 << 8)
+#define SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT (1 << 9)
 #define SNDRV_SEQ_PORT_TYPE_SPECIFIC (1 << 0)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC (1 << 1)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_GM (1 << 2)
@@ -275,6 +298,7 @@
 #define SNDRV_SEQ_PORT_TYPE_MIDI_XG (1 << 4)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1 << 5)
 #define SNDRV_SEQ_PORT_TYPE_MIDI_GM2 (1 << 6)
+#define SNDRV_SEQ_PORT_TYPE_MIDI_UMP (1 << 7)
 #define SNDRV_SEQ_PORT_TYPE_SYNTH (1 << 10)
 #define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1 << 11)
 #define SNDRV_SEQ_PORT_TYPE_SAMPLE (1 << 12)
@@ -286,6 +310,10 @@
 #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_DIR_UNKNOWN 0
+#define SNDRV_SEQ_PORT_DIR_INPUT 1
+#define SNDRV_SEQ_PORT_DIR_OUTPUT 2
+#define SNDRV_SEQ_PORT_DIR_BIDIRECTION 3
 struct snd_seq_port_info {
   struct snd_seq_addr addr;
   char name[64];
@@ -299,7 +327,9 @@
   void * kernel;
   unsigned int flags;
   unsigned char time_queue;
-  char reserved[59];
+  unsigned char direction;
+  unsigned char ump_group;
+  char reserved[57];
 };
 #define SNDRV_SEQ_QUEUE_FLG_SYNC (1 << 0)
 struct snd_seq_queue_info {
@@ -371,12 +401,22 @@
   unsigned int flags;
   char reserved[64];
 };
+#define SNDRV_SEQ_CLIENT_UMP_INFO_ENDPOINT 0
+#define SNDRV_SEQ_CLIENT_UMP_INFO_BLOCK 1
+struct snd_seq_client_ump_info {
+  int client;
+  int type;
+  unsigned char info[512];
+} __attribute__((__packed__));
 #define SNDRV_SEQ_IOCTL_PVERSION _IOR('S', 0x00, int)
 #define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR('S', 0x01, int)
 #define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct snd_seq_system_info)
 #define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct snd_seq_running_info)
+#define SNDRV_SEQ_IOCTL_USER_PVERSION _IOW('S', 0x04, int)
 #define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct snd_seq_client_info)
 #define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW('S', 0x11, struct snd_seq_client_info)
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO _IOWR('S', 0x12, struct snd_seq_client_ump_info)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO _IOWR('S', 0x13, struct snd_seq_client_ump_info)
 #define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct snd_seq_port_info)
 #define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW('S', 0x21, struct snd_seq_port_info)
 #define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct snd_seq_port_info)
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index 1940e5d..b156267 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -149,9 +149,9 @@
   __le32 type;
   __le32 num_elems;
   union {
-    struct snd_soc_tplg_vendor_uuid_elem uuid[0];
-    struct snd_soc_tplg_vendor_value_elem value[0];
-    struct snd_soc_tplg_vendor_string_elem string[0];
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_uuid_elem, uuid);
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_value_elem, value);
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_string_elem, string);
   };
 } __attribute__((packed));
 struct snd_soc_tplg_private {
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 9c1a3ae..ee75e7d 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -219,6 +219,7 @@
 #define SNDRV_PCM_INFO_DOUBLE 0x00000004
 #define SNDRV_PCM_INFO_BATCH 0x00000010
 #define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020
+#define SNDRV_PCM_INFO_PERFECT_DRAIN 0x00000040
 #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100
 #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200
 #define SNDRV_PCM_INFO_COMPLEX 0x00000400
@@ -310,6 +311,7 @@
 #define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1 << 0)
 #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1 << 1)
 #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1 << 2)
+#define SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE (1 << 3)
 struct snd_interval {
   unsigned int min, max;
   unsigned int openmin : 1, openmax : 1, integer : 1, empty : 1;
@@ -565,7 +567,7 @@
 #define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern)
 #define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
 #define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
-#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
+#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 4)
 enum {
   SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
   SNDRV_RAWMIDI_STREAM_INPUT,
@@ -574,6 +576,7 @@
 #define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001
 #define SNDRV_RAWMIDI_INFO_INPUT 0x00000002
 #define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004
+#define SNDRV_RAWMIDI_INFO_UMP 0x00000008
 struct snd_rawmidi_info {
   unsigned int device;
   unsigned int subdevice;
@@ -622,6 +625,56 @@
   size_t xruns;
   unsigned char reserved[16];
 };
+#define SNDRV_UMP_EP_INFO_STATIC_BLOCKS 0x01
+#define SNDRV_UMP_EP_INFO_PROTO_MIDI_MASK 0x0300
+#define SNDRV_UMP_EP_INFO_PROTO_MIDI1 0x0100
+#define SNDRV_UMP_EP_INFO_PROTO_MIDI2 0x0200
+#define SNDRV_UMP_EP_INFO_PROTO_JRTS_MASK 0x0003
+#define SNDRV_UMP_EP_INFO_PROTO_JRTS_TX 0x0001
+#define SNDRV_UMP_EP_INFO_PROTO_JRTS_RX 0x0002
+struct snd_ump_endpoint_info {
+  int card;
+  int device;
+  unsigned int flags;
+  unsigned int protocol_caps;
+  unsigned int protocol;
+  unsigned int num_blocks;
+  unsigned short version;
+  unsigned short family_id;
+  unsigned short model_id;
+  unsigned int manufacturer_id;
+  unsigned char sw_revision[4];
+  unsigned short padding;
+  unsigned char name[128];
+  unsigned char product_id[128];
+  unsigned char reserved[32];
+} __attribute__((__packed__));
+#define SNDRV_UMP_DIR_INPUT 0x01
+#define SNDRV_UMP_DIR_OUTPUT 0x02
+#define SNDRV_UMP_DIR_BIDIRECTION 0x03
+#define SNDRV_UMP_BLOCK_IS_MIDI1 (1U << 0)
+#define SNDRV_UMP_BLOCK_IS_LOWSPEED (1U << 1)
+#define SNDRV_UMP_BLOCK_UI_HINT_UNKNOWN 0x00
+#define SNDRV_UMP_BLOCK_UI_HINT_RECEIVER 0x01
+#define SNDRV_UMP_BLOCK_UI_HINT_SENDER 0x02
+#define SNDRV_UMP_BLOCK_UI_HINT_BOTH 0x03
+#define SNDRV_UMP_MAX_GROUPS 16
+#define SNDRV_UMP_MAX_BLOCKS 32
+struct snd_ump_block_info {
+  int card;
+  int device;
+  unsigned char block_id;
+  unsigned char direction;
+  unsigned char active;
+  unsigned char first_group;
+  unsigned char num_groups;
+  unsigned char midi_ci_version;
+  unsigned char sysex8_streams;
+  unsigned char ui_hint;
+  unsigned int flags;
+  unsigned char name[128];
+  unsigned char reserved[32];
+} __attribute__((__packed__));
 #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
 #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info)
 #define SNDRV_RAWMIDI_IOCTL_USER_PVERSION _IOW('W', 0x02, int)
@@ -629,6 +682,8 @@
 #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
 #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
 #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)
 enum {
   SNDRV_TIMER_CLASS_NONE = - 1,
@@ -763,7 +818,7 @@
   unsigned int val;
   __time_pad pad2;
 };
-#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
+#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 9)
 struct snd_ctl_card_info {
   int card;
   int pad;
@@ -909,6 +964,9 @@
 #define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
 #define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info)
 #define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
+#define SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE _IOWR('U', 0x43, int)
+#define SNDRV_CTL_IOCTL_UMP_ENDPOINT_INFO _IOWR('U', 0x44, struct snd_ump_endpoint_info)
+#define SNDRV_CTL_IOCTL_UMP_BLOCK_INFO _IOWR('U', 0x45, struct snd_ump_block_info)
 #define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
 #define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
 enum sndrv_ctl_event_type {
diff --git a/libc/kernel/uapi/sound/emu10k1.h b/libc/kernel/uapi/sound/emu10k1.h
index 483309e..dbf0eeb 100644
--- a/libc/kernel/uapi/sound/emu10k1.h
+++ b/libc/kernel/uapi/sound/emu10k1.h
@@ -21,8 +21,6 @@
 #ifdef __linux__
 #include <linux/types.h>
 #endif
-#define EMU10K1_CARD_CREATIVE 0x00000000
-#define EMU10K1_CARD_EMUAPS 0x00000001
 #define EMU10K1_FX8010_PCM_COUNT 8
 #define __EMU10K1_DECLARE_BITMAP(name,bits) unsigned long name[(bits) / (sizeof(unsigned long) * 8)]
 #define iMAC0 0x00
@@ -41,10 +39,29 @@
 #define iEXP 0x0d
 #define iINTERP 0x0e
 #define iSKIP 0x0f
+#define LOWORD_OPX_MASK 0x000ffc00
+#define LOWORD_OPY_MASK 0x000003ff
+#define HIWORD_OPCODE_MASK 0x00f00000
+#define HIWORD_RESULT_MASK 0x000ffc00
+#define HIWORD_OPA_MASK 0x000003ff
+#define A_LOWORD_OPX_MASK 0x007ff000
+#define A_LOWORD_OPY_MASK 0x000007ff
+#define A_HIWORD_OPCODE_MASK 0x0f000000
+#define A_HIWORD_RESULT_MASK 0x007ff000
+#define A_HIWORD_OPA_MASK 0x000007ff
 #define FXBUS(x) (0x00 + (x))
 #define EXTIN(x) (0x10 + (x))
 #define EXTOUT(x) (0x20 + (x))
 #define FXBUS2(x) (0x30 + (x))
+#define A_FXBUS(x) (0x00 + (x))
+#define A_EXTIN(x) (0x40 + (x))
+#define A_P16VIN(x) (0x50 + (x))
+#define A_EXTOUT(x) (0x60 + (x))
+#define A_FXBUS2(x) (0x80 + (x))
+#define A_EMU32OUTH(x) (0xa0 + (x))
+#define A_EMU32OUTL(x) (0xb0 + (x))
+#define A3_EMU32IN(x) (0x160 + (x))
+#define A3_EMU32OUT(x) (0x1E0 + (x))
 #define C_00000000 0x40
 #define C_00000001 0x41
 #define C_00000002 0x42
@@ -73,33 +90,71 @@
 #define GPR_NOISE1 0x59
 #define GPR_IRQ 0x5a
 #define GPR_DBAC 0x5b
+#define A_C_00000000 0xc0
+#define A_C_00000001 0xc1
+#define A_C_00000002 0xc2
+#define A_C_00000003 0xc3
+#define A_C_00000004 0xc4
+#define A_C_00000008 0xc5
+#define A_C_00000010 0xc6
+#define A_C_00000020 0xc7
+#define A_C_00000100 0xc8
+#define A_C_00010000 0xc9
+#define A_C_00000800 0xca
+#define A_C_10000000 0xcb
+#define A_C_20000000 0xcc
+#define A_C_40000000 0xcd
+#define A_C_80000000 0xce
+#define A_C_7fffffff 0xcf
+#define A_C_ffffffff 0xd0
+#define A_C_fffffffe 0xd1
+#define A_C_c0000000 0xd2
+#define A_C_4f1bbcdc 0xd3
+#define A_C_5a7ef9db 0xd4
+#define A_C_00100000 0xd5
+#define A_GPR_ACCU 0xd6
+#define A_GPR_COND 0xd7
+#define A_GPR_NOISE0 0xd8
+#define A_GPR_NOISE1 0xd9
+#define A_GPR_IRQ 0xda
+#define A_GPR_DBAC 0xdb
+#define A_GPR_DBACE 0xde
+#define FXGPREGBASE 0x100
+#define A_FXGPREGBASE 0x400
+#define A_TANKMEMCTLREGBASE 0x100
+#define A_TANKMEMCTLREG_MASK 0x1f
+#define TANKMEMDATAREGBASE 0x200
+#define TANKMEMDATAREG_MASK 0x000fffff
+#define TANKMEMADDRREGBASE 0x300
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff
+#define TANKMEMADDRREG_CLEAR 0x00800000
+#define TANKMEMADDRREG_ALIGN 0x00400000
+#define TANKMEMADDRREG_WRITE 0x00200000
+#define TANKMEMADDRREG_READ 0x00100000
 #define GPR(x) (FXGPREGBASE + (x))
 #define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x))
 #define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x))
 #define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x))
 #define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x))
+#define A_GPR(x) (A_FXGPREGBASE + (x))
 #define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x))
 #define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x))
 #define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x))
 #define A_ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0xc0 + (x))
 #define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x))
 #define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x))
-#define A_FXBUS(x) (0x00 + (x))
-#define A_EXTIN(x) (0x40 + (x))
-#define A_P16VIN(x) (0x50 + (x))
-#define A_EXTOUT(x) (0x60 + (x))
-#define A_FXBUS2(x) (0x80 + (x))
-#define A_EMU32OUTH(x) (0xa0 + (x))
-#define A_EMU32OUTL(x) (0xb0 + (x))
-#define A3_EMU32IN(x) (0x160 + (x))
-#define A3_EMU32OUT(x) (0x1E0 + (x))
-#define A_GPR(x) (A_FXGPREGBASE + (x))
 #define CC_REG_NORMALIZED C_00000001
 #define CC_REG_BORROW C_00000002
 #define CC_REG_MINUS C_00000004
 #define CC_REG_ZERO C_00000008
 #define CC_REG_SATURATE C_00000010
 #define CC_REG_NONZERO C_00000100
+#define A_CC_REG_NORMALIZED A_C_00000001
+#define A_CC_REG_BORROW A_C_00000002
+#define A_CC_REG_MINUS A_C_00000004
+#define A_CC_REG_ZERO A_C_00000008
+#define A_CC_REG_SATURATE A_C_00000010
+#define A_CC_REG_NONZERO A_C_00000100
 #define FXBUS_PCM_LEFT 0x00
 #define FXBUS_PCM_RIGHT 0x01
 #define FXBUS_PCM_LEFT_REAR 0x02
@@ -180,35 +235,6 @@
 #define A_EXTOUT_ADC_CAP_L 0x16
 #define A_EXTOUT_ADC_CAP_R 0x17
 #define A_EXTOUT_MIC_CAP 0x18
-#define A_C_00000000 0xc0
-#define A_C_00000001 0xc1
-#define A_C_00000002 0xc2
-#define A_C_00000003 0xc3
-#define A_C_00000004 0xc4
-#define A_C_00000008 0xc5
-#define A_C_00000010 0xc6
-#define A_C_00000020 0xc7
-#define A_C_00000100 0xc8
-#define A_C_00010000 0xc9
-#define A_C_00000800 0xca
-#define A_C_10000000 0xcb
-#define A_C_20000000 0xcc
-#define A_C_40000000 0xcd
-#define A_C_80000000 0xce
-#define A_C_7fffffff 0xcf
-#define A_C_ffffffff 0xd0
-#define A_C_fffffffe 0xd1
-#define A_C_c0000000 0xd2
-#define A_C_4f1bbcdc 0xd3
-#define A_C_5a7ef9db 0xd4
-#define A_C_00100000 0xd5
-#define A_GPR_ACCU 0xd6
-#define A_GPR_COND 0xd7
-#define A_GPR_NOISE0 0xd8
-#define A_GPR_NOISE1 0xd9
-#define A_GPR_IRQ 0xda
-#define A_GPR_DBAC 0xdb
-#define A_GPR_DBACE 0xde
 #define EMU10K1_DBG_ZC 0x80000000
 #define EMU10K1_DBG_SATURATION_OCCURED 0x02000000
 #define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000
@@ -216,11 +242,13 @@
 #define EMU10K1_DBG_STEP 0x00004000
 #define EMU10K1_DBG_CONDITION_CODE 0x00003e00
 #define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff
-#define TANKMEMADDRREG_ADDR_MASK 0x000fffff
-#define TANKMEMADDRREG_CLEAR 0x00800000
-#define TANKMEMADDRREG_ALIGN 0x00400000
-#define TANKMEMADDRREG_WRITE 0x00200000
-#define TANKMEMADDRREG_READ 0x00100000
+#define A_DBG_ZC 0x40000000
+#define A_DBG_SATURATION_OCCURED 0x20000000
+#define A_DBG_SATURATION_ADDR 0x0ffc0000
+#define A_DBG_SINGLE_STEP 0x00020000
+#define A_DBG_STEP 0x00010000
+#define A_DBG_CONDITION_CODE 0x0000f800
+#define A_DBG_STEP_ADDR 0x000003ff
 struct snd_emu10k1_fx8010_info {
   unsigned int internal_tram_size;
   unsigned int external_tram_size;
@@ -234,6 +262,8 @@
 #define EMU10K1_GPR_TRANSLATION_BASS 2
 #define EMU10K1_GPR_TRANSLATION_TREBLE 3
 #define EMU10K1_GPR_TRANSLATION_ONOFF 4
+#define EMU10K1_GPR_TRANSLATION_NEGATE 5
+#define EMU10K1_GPR_TRANSLATION_NEG_TABLE100 6
 enum emu10k1_ctl_elem_iface {
   EMU10K1_CTL_ELEM_IFACE_MIXER = 2,
   EMU10K1_CTL_ELEM_IFACE_PCM = 3,
@@ -251,9 +281,9 @@
   unsigned int vcount;
   unsigned int count;
   unsigned short gpr[32];
-  unsigned int value[32];
-  unsigned int min;
-  unsigned int max;
+  int value[32];
+  int min;
+  int max;
   unsigned int translation;
   const unsigned int * tlv;
 };
diff --git a/libc/kernel/uapi/sound/skl-tplg-interface.h b/libc/kernel/uapi/sound/skl-tplg-interface.h
index 6dd9655..ff3d42a 100644
--- a/libc/kernel/uapi/sound/skl-tplg-interface.h
+++ b/libc/kernel/uapi/sound/skl-tplg-interface.h
@@ -47,7 +47,8 @@
   SKL_CH_CFG_DUAL_MONO = 9,
   SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
   SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
-  SKL_CH_CFG_4_CHANNEL = 12,
+  SKL_CH_CFG_7_1 = 12,
+  SKL_CH_CFG_4_CHANNEL = SKL_CH_CFG_7_1,
   SKL_CH_CFG_INVALID
 };
 enum skl_module_type {
diff --git a/libc/kernel/uapi/sound/sof/abi.h b/libc/kernel/uapi/sound/sof/abi.h
index dc4e525..a4844d6 100644
--- a/libc/kernel/uapi/sound/sof/abi.h
+++ b/libc/kernel/uapi/sound/sof/abi.h
@@ -35,4 +35,5 @@
 #define SOF_ABI_VERSION_INCOMPATIBLE(sof_ver,client_ver) (SOF_ABI_VERSION_MAJOR((sof_ver)) != SOF_ABI_VERSION_MAJOR((client_ver)))
 #define SOF_ABI_VERSION SOF_ABI_VER(SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH)
 #define SOF_ABI_MAGIC 0x00464F53
+#define SOF_IPC4_ABI_MAGIC 0x34464F53
 #endif
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index 3726546..48ef360 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -39,6 +39,7 @@
 #define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
 #define SOF_TKN_SCHED_LP_MODE 207
 #define SOF_TKN_SCHED_MEM_USAGE 208
+#define SOF_TKN_SCHED_USE_CHAIN_DMA 209
 #define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
 #define SOF_TKN_VOLUME_RAMP_STEP_MS 251
 #define SOF_TKN_GAIN_RAMP_TYPE 260
@@ -59,10 +60,12 @@
 #define SOF_TKN_COMP_CPC 406
 #define SOF_TKN_COMP_IS_PAGES 409
 #define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410
-#define SOF_TKN_COMP_NUM_SINK_PINS 411
-#define SOF_TKN_COMP_NUM_SOURCE_PINS 412
-#define SOF_TKN_COMP_SINK_PIN_BINDING_WNAME 413
-#define SOF_TKN_COMP_SRC_PIN_BINDING_WNAME 414
+#define SOF_TKN_COMP_NUM_INPUT_PINS 411
+#define SOF_TKN_COMP_NUM_OUTPUT_PINS 412
+#define SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME 413
+#define SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME 414
+#define SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS 415
+#define SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS 416
 #define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500
 #define SOF_TKN_INTEL_SSP_MCLK_ID 501
 #define SOF_TKN_INTEL_SSP_SAMPLE_BITS 502
@@ -107,26 +110,29 @@
 #define SOF_TKN_AMD_ACPDMIC_CH 1801
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901
-#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT_DEPTH 1902
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908
+#define SOF_TKN_CAVS_AUDIO_FORMAT_INPUT_PIN_INDEX 1909
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931
-#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT_DEPTH 1932
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE 1936
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG 1937
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_SAMPLE_TYPE 1938
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUTPUT_PIN_INDEX 1939
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IBS 1970
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OBS 1971
 #define SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE 1972
 #define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980
+#define SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS 1981
 #define SOF_TKN_AMD_ACPI2S_RATE 1700
 #define SOF_TKN_AMD_ACPI2S_CH 1701
 #define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
diff --git a/libc/kernel/uapi/xen/evtchn.h b/libc/kernel/uapi/xen/evtchn.h
index aa4aaaf..1b27bdb 100644
--- a/libc/kernel/uapi/xen/evtchn.h
+++ b/libc/kernel/uapi/xen/evtchn.h
@@ -43,4 +43,8 @@
 struct ioctl_evtchn_restrict_domid {
   domid_t domid;
 };
+#define IOCTL_EVTCHN_BIND_STATIC _IOC(_IOC_NONE, 'E', 7, sizeof(struct ioctl_evtchn_bind))
+struct ioctl_evtchn_bind {
+  unsigned int port;
+};
 #endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c69e609..e6ea3c2 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -955,7 +955,7 @@
     sigaction;
     sigaddset; # introduced=21
     sigaltstack;
-    sigblock;
+    sigblock; # arm x86 arm64 x86_64
     sigdelset; # introduced=21
     sigemptyset; # introduced=21
     sigfillset; # introduced=21
@@ -968,7 +968,7 @@
     sigprocmask;
     sigqueue; # introduced=23
     sigsetjmp; # introduced-arm=9 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
-    sigsetmask;
+    sigsetmask; # arm x86 arm64 x86_64
     sigsuspend;
     sigtimedwait; # introduced=23
     sigwait;
@@ -1586,9 +1586,15 @@
 
 LIBC_V { # introduced=VanillaIceCream
   global:
+    epoll_pwait2;
+    epoll_pwait2_64;
     localtime_rz;
     mbsrtowcs_l;
     mktime_z;
+    __riscv_flush_icache; # riscv64
+    __riscv_hwprobe; # riscv64
+    tcgetwinsize;
+    tcsetwinsize;
     timespec_getres;
     tzalloc;
     tzfree;
diff --git a/libc/platform/bionic/page.h b/libc/platform/bionic/page.h
index 5f4bb6f..65faba4 100644
--- a/libc/platform/bionic/page.h
+++ b/libc/platform/bionic/page.h
@@ -24,16 +24,19 @@
 #include <sys/user.h>
 
 inline size_t page_size() {
-  /*
-   * PAGE_SIZE defines the maximum supported page size. Since 4096 is the
-   * minimum supported page size we can just let it be constant folded if it's
-   * also the maximum.
-   */
-#if PAGE_SIZE == 4096
+#if defined(PAGE_SIZE)
   return PAGE_SIZE;
 #else
-  static size_t size = getauxval(AT_PAGESZ);
-  return size;
+  static const size_t page_size = getauxval(AT_PAGESZ);
+  return page_size;
+#endif
+}
+
+constexpr size_t max_page_size() {
+#if defined(PAGE_SIZE)
+  return PAGE_SIZE;
+#else
+  return 65536;
 #endif
 }
 
diff --git a/libc/private/CFIShadow.h b/libc/private/CFIShadow.h
index ec87e3c..cbdf0f7 100644
--- a/libc/private/CFIShadow.h
+++ b/libc/private/CFIShadow.h
@@ -68,8 +68,7 @@
 #endif
 
   // Shadow is 2 -> 2**kShadowGranularity.
-  static constexpr uintptr_t kShadowSize =
-      align_up((kMaxTargetAddr >> (kShadowGranularity - 1)), PAGE_SIZE);
+  static constexpr uintptr_t kShadowSize = kMaxTargetAddr >> (kShadowGranularity - 1);
 
   // Returns offset inside the shadow region for an address.
   static constexpr uintptr_t MemToShadowOffset(uintptr_t x) {
diff --git a/libc/private/SigSetConverter.h b/libc/private/SigSetConverter.h
index 7d0b215..9e9df73 100644
--- a/libc/private/SigSetConverter.h
+++ b/libc/private/SigSetConverter.h
@@ -28,8 +28,45 @@
 
 #pragma once
 
-union SigSetConverter {
-  int bsd;
-  sigset_t sigset;
-  sigset64_t sigset64;
+// Android's 32-bit ABI shipped with a sigset_t too small to include any
+// of the realtime signals, so we have both sigset_t and sigset64_t. Many
+// new system calls only accept a sigset64_t, so this helps paper over
+// the difference at zero cost to LP64 in most cases after the optimizer
+// removes the unnecessary temporary `ptr`.
+struct SigSetConverter {
+ public:
+  SigSetConverter(const sigset_t* s) : SigSetConverter(const_cast<sigset_t*>(s)) {}
+
+  SigSetConverter(sigset_t* s) {
+#if defined(__LP64__)
+    // sigset_t == sigset64_t on LP64.
+    ptr = s;
+#else
+    sigset64 = {};
+    if (s != nullptr) {
+      original_ptr = s;
+      sigset = *s;
+      ptr = &sigset64;
+    } else {
+      ptr = nullptr;
+    }
+#endif
+  }
+
+  void copy_out() {
+#if defined(__LP64__)
+    // We used the original pointer directly, so no copy needed.
+#else
+    *original_ptr = sigset;
+#endif
+  }
+
+  sigset64_t* ptr;
+
+ private:
+  [[maybe_unused]] sigset_t* original_ptr;
+  union {
+    sigset_t sigset;
+    sigset64_t sigset64;
+  };
 };
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
index 746f72a..2faaf77 100644
--- a/libc/private/WriteProtected.h
+++ b/libc/private/WriteProtected.h
@@ -25,15 +25,16 @@
 #include <async_safe/log.h>
 
 #include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
 
 template <typename T>
 union WriteProtectedContents {
   T value;
-  char padding[PAGE_SIZE];
+  char padding[max_page_size()];
 
   WriteProtectedContents() = default;
   BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
-} __attribute__((aligned(PAGE_SIZE)));
+} __attribute__((aligned(max_page_size())));
 
 // Write protected wrapper class that aligns its contents to a page boundary,
 // and sets the memory protection to be non-writable, except when being modified
@@ -41,8 +42,8 @@
 template <typename T>
 class WriteProtected {
  public:
-  static_assert(sizeof(T) < PAGE_SIZE,
-                "WriteProtected only supports contents up to PAGE_SIZE");
+  static_assert(sizeof(T) < max_page_size(),
+                "WriteProtected only supports contents up to max_page_size()");
   static_assert(__is_pod(T), "WriteProtected only supports POD contents");
 
   WriteProtected() = default;
@@ -80,7 +81,7 @@
     // ourselves.
     addr = untag_address(addr);
 #endif
-    if (mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot) == -1) {
+    if (mprotect(reinterpret_cast<void*>(addr), max_page_size(), prot) == -1) {
       async_safe_fatal("WriteProtected mprotect %x failed: %s", prot, strerror(errno));
     }
   }
diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h
index 78e5046..f9d85b2 100644
--- a/libc/private/bionic_asm.h
+++ b/libc/private/bionic_asm.h
@@ -90,3 +90,5 @@
 
 #define NOTE_GNU_PROPERTY() \
     __bionic_asm_custom_note_gnu_section()
+
+#define L(__label) .L##__label
diff --git a/libc/private/bionic_asm_offsets.h b/libc/private/bionic_asm_offsets.h
index c2f2b56..e72adda 100644
--- a/libc/private/bionic_asm_offsets.h
+++ b/libc/private/bionic_asm_offsets.h
@@ -28,6 +28,6 @@
 
 #pragma once
 
-#ifdef __aarch64__
-#define OFFSETOF_libc_globals_memtag_stack 80
+#if defined(__aarch64__)
+#define OFFSETOF_libc_globals_memtag_stack 64
 #endif
diff --git a/libc/private/bionic_inline_raise.h b/libc/private/bionic_inline_raise.h
index 8565c80..82a564d 100644
--- a/libc/private/bionic_inline_raise.h
+++ b/libc/private/bionic_inline_raise.h
@@ -60,6 +60,13 @@
   register long x3 __asm__("x3") = reinterpret_cast<long>(&info);
   register long x8 __asm__("x8") = __NR_rt_tgsigqueueinfo;
   __asm__("svc #0" : "=r"(x0) : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory");
+#elif defined(__riscv)
+  register long a0 __asm__("a0") = pid;
+  register long a1 __asm__("a1") = tid;
+  register long a2 __asm__("a2") = sig;
+  register long a3 __asm__("a3") = reinterpret_cast<long>(&info);
+  register long a7 __asm__("a7") = __NR_rt_tgsigqueueinfo;
+  __asm__("ecall" : "=r"(a0) : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a7) : "memory");
 #elif defined(__x86_64__)
   register long rax __asm__("rax") = __NR_rt_tgsigqueueinfo;
   register long rdi __asm__("rdi") = pid;
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 243b220..0e5f861 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -34,15 +34,9 @@
 
 __BEGIN_DECLS
 
-/*
- * These return values are specified by POSIX for multibyte conversion
- * functions.
- */
-#define __MB_ERR_ILLEGAL_SEQUENCE static_cast<size_t>(-1)
-#define __MB_ERR_INCOMPLETE_SEQUENCE static_cast<size_t>(-2)
-
-#define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
-                         rv == __MB_ERR_INCOMPLETE_SEQUENCE)
+#define __MB_IS_ERR(rv)                              \
+  (rv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE || \
+   rv == BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE)
 
 static inline __wur bool mbstate_is_initial(const mbstate_t* ps) {
   return *(reinterpret_cast<const uint32_t*>(ps->__seq)) == 0;
@@ -63,14 +57,18 @@
   return ps->__seq[n];
 }
 
-static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
-  errno = _errno;
+static inline void mbstate_reset(mbstate_t* ps) {
   *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
-  return __MB_ERR_ILLEGAL_SEQUENCE;
 }
 
-static inline __wur size_t mbstate_reset_and_return(int _return, mbstate_t* ps) {
-  *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
+static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
+  errno = _errno;
+  mbstate_reset(ps);
+  return BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE;
+}
+
+static inline __wur size_t mbstate_reset_and_return(size_t _return, mbstate_t* ps) {
+  mbstate_reset(ps);
   return _return;
 }
 
diff --git a/libc/private/bionic_vdso.h b/libc/private/bionic_vdso.h
index da19b29..406b064 100644
--- a/libc/private/bionic_vdso.h
+++ b/libc/private/bionic_vdso.h
@@ -26,26 +26,23 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _PRIVATE_BIONIC_VDSO_H
-#define _PRIVATE_BIONIC_VDSO_H
-
-#include <time.h>
+#pragma once
 
 #if defined(__aarch64__)
 #define VDSO_CLOCK_GETTIME_SYMBOL "__kernel_clock_gettime"
-#define VDSO_CLOCK_GETRES_SYMBOL  "__kernel_clock_getres"
-#define VDSO_GETTIMEOFDAY_SYMBOL  "__kernel_gettimeofday"
-#define VDSO_TIME_SYMBOL          "__kernel_time"
+#define VDSO_CLOCK_GETRES_SYMBOL "__kernel_clock_getres"
+#define VDSO_GETTIMEOFDAY_SYMBOL "__kernel_gettimeofday"
 #else
 #define VDSO_CLOCK_GETTIME_SYMBOL "__vdso_clock_gettime"
-#define VDSO_CLOCK_GETRES_SYMBOL  "__vdso_clock_getres"
-#define VDSO_GETTIMEOFDAY_SYMBOL  "__vdso_gettimeofday"
-#define VDSO_TIME_SYMBOL          "__vdso_time"
+#define VDSO_CLOCK_GETRES_SYMBOL "__vdso_clock_getres"
+#define VDSO_GETTIMEOFDAY_SYMBOL "__vdso_gettimeofday"
 #endif
-
-extern "C" int __clock_gettime(int, timespec*);
-extern "C" int __clock_getres(int, timespec*);
-extern "C" int __gettimeofday(timeval*, struct timezone*);
+#if defined(__riscv)
+#define VDSO_RISCV_HWPROBE_SYMBOL "__vdso_riscv_hwprobe"
+#endif
+#if defined(__i386__) || defined(__x86_64__)
+#define VDSO_TIME_SYMBOL "__vdso_time"
+#endif
 
 struct vdso_entry {
   const char* name;
@@ -56,8 +53,11 @@
   VDSO_CLOCK_GETTIME = 0,
   VDSO_CLOCK_GETRES,
   VDSO_GETTIMEOFDAY,
+#if defined(VDSO_TIME_SYMBOL)
   VDSO_TIME,
+#endif
+#if defined(VDSO_RISCV_HWPROBE_SYMBOL)
+  VDSO_RISCV_HWPROBE,
+#endif
   VDSO_END
 };
-
-#endif  // _PRIVATE_BIONIC_VDSO_H
diff --git a/libc/private/thread_private.h b/libc/private/thread_private.h
index 1f9eeb6..1a13690 100644
--- a/libc/private/thread_private.h
+++ b/libc/private/thread_private.h
@@ -29,7 +29,6 @@
 
 #define _ARC4_LOCK() _thread_arc4_lock()
 #define _ARC4_UNLOCK() _thread_arc4_unlock()
-#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
 
 extern volatile sig_atomic_t _rs_forked;
 
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index 3133f1f..3607995 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -327,12 +327,12 @@
             fp->_r--;
             memset(&mbs, 0, sizeof(mbs));
             nconv = mbrtowc(wcp, buf, bytes, &mbs);
-            if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
+            if (nconv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
               fp->_flags |= __SERR;
               goto input_failure;
             }
             if (nconv == 0 && !(flags & SUPPRESS)) *wcp = L'\0';
-            if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+            if (nconv != BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
               nread += bytes;
               width--;
               if (!(flags & SUPPRESS)) wcp++;
@@ -417,11 +417,11 @@
             wchar_t wc = L'\0';
             memset(&mbs, 0, sizeof(mbs));
             nconv = mbrtowc(&wc, buf, bytes, &mbs);
-            if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
+            if (nconv == BIONIC_MULTIBYTE_RESULT_ILLEGAL_SEQUENCE) {
               fp->_flags |= __SERR;
               goto input_failure;
             }
-            if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+            if (nconv != BIONIC_MULTIBYTE_RESULT_INCOMPLETE_SEQUENCE) {
               if ((c == CT_CCL && wctob(wc) != EOF && !ccltab[wctob(wc)]) || (c == CT_STRING && iswspace(wc))) {
                 while (bytes != 0) {
                   bytes--;
diff --git a/libc/system_properties/context_node.cpp b/libc/system_properties/context_node.cpp
index d392c0a..572bf97 100644
--- a/libc/system_properties/context_node.cpp
+++ b/libc/system_properties/context_node.cpp
@@ -49,17 +49,11 @@
     return true;
   }
 
-  char filename[PROP_FILENAME_MAX];
-  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", filename_, context_);
-  if (len < 0 || len >= PROP_FILENAME_MAX) {
-    lock_.unlock();
-    return false;
-  }
-
+  PropertiesFilename filename(filename_, context_);
   if (access_rw) {
-    pa_ = prop_area::map_prop_area_rw(filename, context_, fsetxattr_failed);
+    pa_ = prop_area::map_prop_area_rw(filename.c_str(), context_, fsetxattr_failed);
   } else {
-    pa_ = prop_area::map_prop_area(filename);
+    pa_ = prop_area::map_prop_area(filename.c_str());
   }
   lock_.unlock();
   return pa_;
@@ -84,13 +78,8 @@
 }
 
 bool ContextNode::CheckAccess() {
-  char filename[PROP_FILENAME_MAX];
-  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", filename_, context_);
-  if (len < 0 || len >= PROP_FILENAME_MAX) {
-    return false;
-  }
-
-  return access(filename, R_OK) == 0;
+  PropertiesFilename filename(filename_, context_);
+  return access(filename.c_str(), R_OK) == 0;
 }
 
 void ContextNode::Unmap() {
diff --git a/libc/system_properties/contexts_serialized.cpp b/libc/system_properties/contexts_serialized.cpp
index 6ccd46c..f05aaa0 100644
--- a/libc/system_properties/contexts_serialized.cpp
+++ b/libc/system_properties/contexts_serialized.cpp
@@ -66,18 +66,12 @@
 }
 
 bool ContextsSerialized::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed) {
-  char filename[PROP_FILENAME_MAX];
-  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial", filename_);
-  if (len < 0 || len >= PROP_FILENAME_MAX) {
-    serial_prop_area_ = nullptr;
-    return false;
-  }
-
+  PropertiesFilename filename(filename_, "properties_serial");
   if (access_rw) {
-    serial_prop_area_ =
-        prop_area::map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
+    serial_prop_area_ = prop_area::map_prop_area_rw(
+        filename.c_str(), "u:object_r:properties_serial:s0", fsetxattr_failed);
   } else {
-    serial_prop_area_ = prop_area::map_prop_area(filename);
+    serial_prop_area_ = prop_area::map_prop_area(filename.c_str());
   }
   return serial_prop_area_;
 }
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
index 7ba835a..3579f55 100644
--- a/libc/system_properties/contexts_split.cpp
+++ b/libc/system_properties/contexts_split.cpp
@@ -192,18 +192,12 @@
 }
 
 bool ContextsSplit::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed) {
-  char filename[PROP_FILENAME_MAX];
-  int len = async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial", filename_);
-  if (len < 0 || len >= PROP_FILENAME_MAX) {
-    serial_prop_area_ = nullptr;
-    return false;
-  }
-
+  PropertiesFilename filename(filename_, "properties_serial");
   if (access_rw) {
-    serial_prop_area_ =
-        prop_area::map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
+    serial_prop_area_ = prop_area::map_prop_area_rw(
+        filename.c_str(), "u:object_r:properties_serial:s0", fsetxattr_failed);
   } else {
-    serial_prop_area_ = prop_area::map_prop_area(filename);
+    serial_prop_area_ = prop_area::map_prop_area(filename.c_str());
   }
   return serial_prop_area_;
 }
diff --git a/libc/system_properties/include/system_properties/prop_area.h b/libc/system_properties/include/system_properties/prop_area.h
index e32a8d7..187ff75 100644
--- a/libc/system_properties/include/system_properties/prop_area.h
+++ b/libc/system_properties/include/system_properties/prop_area.h
@@ -53,14 +53,14 @@
 //                  +-----+   +-----+     +-----+            +===========+
 
 // Represents a node in the trie.
-struct prop_bt {
+struct prop_trie_node {
   uint32_t namelen;
 
   // The property trie is updated only by the init process (single threaded) which provides
   // property service. And it can be read by multiple threads at the same time.
   // As the property trie is not protected by locks, we use atomic_uint_least32_t types for the
   // left, right, children "pointers" in the trie node. To make sure readers who see the
-  // change of "pointers" can also notice the change of prop_bt structure contents pointed by
+  // change of "pointers" can also notice the change of prop_trie_node structure contents pointed by
   // the "pointers", we always use release-consume ordering pair when accessing these "pointers".
 
   // prop "points" to prop_info structure if there is a propery associated with the trie node.
@@ -79,14 +79,14 @@
 
   char name[0];
 
-  prop_bt(const char* name, const uint32_t name_length) {
+  prop_trie_node(const char* name, const uint32_t name_length) {
     this->namelen = name_length;
     memcpy(this->name, name, name_length);
     this->name[name_length] = '\0';
   }
 
  private:
-  BIONIC_DISALLOW_COPY_AND_ASSIGN(prop_bt);
+  BIONIC_DISALLOW_COPY_AND_ASSIGN(prop_trie_node);
 };
 
 class prop_area {
@@ -105,7 +105,7 @@
     atomic_init(&serial_, 0u);
     memset(reserved_, 0, sizeof(reserved_));
     // Allocate enough space for the root node.
-    bytes_used_ = sizeof(prop_bt);
+    bytes_used_ = sizeof(prop_trie_node);
     // To make property reads wait-free, we reserve a
     // PROP_VALUE_MAX-sized block of memory, the "dirty backup area",
     // just after the root node. When we're about to modify a
@@ -136,30 +136,29 @@
   uint32_t version() const {
     return version_;
   }
-  char* dirty_backup_area() {
-    return data_ + sizeof (prop_bt);
-  }
+  char* dirty_backup_area() { return data_ + sizeof(prop_trie_node); }
 
  private:
   static prop_area* map_fd_ro(const int fd);
 
   void* allocate_obj(const size_t size, uint_least32_t* const off);
-  prop_bt* new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off);
+  prop_trie_node* new_prop_trie_node(const char* name, uint32_t namelen, uint_least32_t* const off);
   prop_info* new_prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen,
                            uint_least32_t* const off);
   void* to_prop_obj(uint_least32_t off);
-  prop_bt* to_prop_bt(atomic_uint_least32_t* off_p);
+  prop_trie_node* to_prop_trie_node(atomic_uint_least32_t* off_p);
   prop_info* to_prop_info(atomic_uint_least32_t* off_p);
 
-  prop_bt* root_node();
+  prop_trie_node* root_node();
 
-  prop_bt* find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen, bool alloc_if_needed);
+  prop_trie_node* find_prop_trie_node(prop_trie_node* const trie, const char* name,
+                                      uint32_t namelen, bool alloc_if_needed);
 
-  const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
+  const prop_info* find_property(prop_trie_node* const trie, const char* name, uint32_t namelen,
                                  const char* value, uint32_t valuelen, bool alloc_if_needed);
 
-  bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
-                        void* cookie);
+  bool foreach_property(prop_trie_node* const trie,
+                        void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
 
   // The original design doesn't include pa_size or pa_data_size in the prop_area struct itself.
   // Since we'll need to be backwards compatible with that design, we don't gain much by adding it
diff --git a/libc/system_properties/include/system_properties/system_properties.h b/libc/system_properties/include/system_properties/system_properties.h
index 0666e28..4d84b39 100644
--- a/libc/system_properties/include/system_properties/system_properties.h
+++ b/libc/system_properties/include/system_properties/system_properties.h
@@ -37,7 +37,25 @@
 #include "contexts_serialized.h"
 #include "contexts_split.h"
 
-constexpr int PROP_FILENAME_MAX = 1024;
+class PropertiesFilename {
+ public:
+  PropertiesFilename() = default;
+  PropertiesFilename(const char* dir, const char* file) {
+    if (snprintf(filename_, sizeof(filename_), "%s/%s", dir, file) >=
+        static_cast<int>(sizeof(filename_))) {
+      abort();
+    }
+  }
+  void operator=(const char* value) {
+    if (strlen(value) >= sizeof(filename_)) abort();
+    strcpy(filename_, value);
+  }
+  const char* c_str() { return filename_; }
+
+ private:
+  // Typically something like "/dev/__properties__/properties_serial".
+  char filename_[128];
+};
 
 class SystemProperties {
  public:
@@ -86,5 +104,5 @@
   Contexts* contexts_;
 
   bool initialized_;
-  char property_filename_[PROP_FILENAME_MAX];
+  PropertiesFilename properties_filename_;
 };
diff --git a/libc/system_properties/prop_area.cpp b/libc/system_properties/prop_area.cpp
index 42bee9f..4668eed 100644
--- a/libc/system_properties/prop_area.cpp
+++ b/libc/system_properties/prop_area.cpp
@@ -154,16 +154,15 @@
   return data_ + *off;
 }
 
-prop_bt* prop_area::new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off) {
+prop_trie_node* prop_area::new_prop_trie_node(const char* name, uint32_t namelen,
+                                              uint_least32_t* const off) {
   uint_least32_t new_offset;
-  void* const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
-  if (p != nullptr) {
-    prop_bt* bt = new (p) prop_bt(name, namelen);
-    *off = new_offset;
-    return bt;
-  }
+  void* const p = allocate_obj(sizeof(prop_trie_node) + namelen + 1, &new_offset);
+  if (p == nullptr) return nullptr;
 
-  return nullptr;
+  prop_trie_node* node = new (p) prop_trie_node(name, namelen);
+  *off = new_offset;
+  return node;
 }
 
 prop_info* prop_area::new_prop_info(const char* name, uint32_t namelen, const char* value,
@@ -200,9 +199,9 @@
   return (data_ + off);
 }
 
-inline prop_bt* prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
+inline prop_trie_node* prop_area::to_prop_trie_node(atomic_uint_least32_t* off_p) {
   uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
-  return reinterpret_cast<prop_bt*>(to_prop_obj(off));
+  return reinterpret_cast<prop_trie_node*>(to_prop_obj(off));
 }
 
 inline prop_info* prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
@@ -210,8 +209,8 @@
   return reinterpret_cast<prop_info*>(to_prop_obj(off));
 }
 
-inline prop_bt* prop_area::root_node() {
-  return reinterpret_cast<prop_bt*>(to_prop_obj(0));
+inline prop_trie_node* prop_area::root_node() {
+  return reinterpret_cast<prop_trie_node*>(to_prop_obj(0));
 }
 
 static int cmp_prop_name(const char* one, uint32_t one_len, const char* two, uint32_t two_len) {
@@ -223,9 +222,9 @@
     return strncmp(one, two, one_len);
 }
 
-prop_bt* prop_area::find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen,
-                                 bool alloc_if_needed) {
-  prop_bt* current = bt;
+prop_trie_node* prop_area::find_prop_trie_node(prop_trie_node* const trie, const char* name,
+                                               uint32_t namelen, bool alloc_if_needed) {
+  prop_trie_node* current = trie;
   while (true) {
     if (!current) {
       return nullptr;
@@ -239,46 +238,46 @@
     if (ret < 0) {
       uint_least32_t left_offset = atomic_load_explicit(&current->left, memory_order_relaxed);
       if (left_offset != 0) {
-        current = to_prop_bt(&current->left);
+        current = to_prop_trie_node(&current->left);
       } else {
         if (!alloc_if_needed) {
           return nullptr;
         }
 
         uint_least32_t new_offset;
-        prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
-        if (new_bt) {
+        prop_trie_node* new_node = new_prop_trie_node(name, namelen, &new_offset);
+        if (new_node) {
           atomic_store_explicit(&current->left, new_offset, memory_order_release);
         }
-        return new_bt;
+        return new_node;
       }
     } else {
       uint_least32_t right_offset = atomic_load_explicit(&current->right, memory_order_relaxed);
       if (right_offset != 0) {
-        current = to_prop_bt(&current->right);
+        current = to_prop_trie_node(&current->right);
       } else {
         if (!alloc_if_needed) {
           return nullptr;
         }
 
         uint_least32_t new_offset;
-        prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
-        if (new_bt) {
+        prop_trie_node* new_node = new_prop_trie_node(name, namelen, &new_offset);
+        if (new_node) {
           atomic_store_explicit(&current->right, new_offset, memory_order_release);
         }
-        return new_bt;
+        return new_node;
       }
     }
   }
 }
 
-const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen,
-                                          const char* value, uint32_t valuelen,
+const prop_info* prop_area::find_property(prop_trie_node* const trie, const char* name,
+                                          uint32_t namelen, const char* value, uint32_t valuelen,
                                           bool alloc_if_needed) {
   if (!trie) return nullptr;
 
   const char* remaining_name = name;
-  prop_bt* current = trie;
+  prop_trie_node* current = trie;
   while (true) {
     const char* sep = strchr(remaining_name, '.');
     const bool want_subtree = (sep != nullptr);
@@ -288,13 +287,13 @@
       return nullptr;
     }
 
-    prop_bt* root = nullptr;
+    prop_trie_node* root = nullptr;
     uint_least32_t children_offset = atomic_load_explicit(&current->children, memory_order_relaxed);
     if (children_offset != 0) {
-      root = to_prop_bt(&current->children);
+      root = to_prop_trie_node(&current->children);
     } else if (alloc_if_needed) {
       uint_least32_t new_offset;
-      root = new_prop_bt(remaining_name, substr_size, &new_offset);
+      root = new_prop_trie_node(remaining_name, substr_size, &new_offset);
       if (root) {
         atomic_store_explicit(&current->children, new_offset, memory_order_release);
       }
@@ -304,7 +303,7 @@
       return nullptr;
     }
 
-    current = find_prop_bt(root, remaining_name, substr_size, alloc_if_needed);
+    current = find_prop_trie_node(root, remaining_name, substr_size, alloc_if_needed);
     if (!current) {
       return nullptr;
     }
@@ -330,13 +329,13 @@
   }
 }
 
-bool prop_area::foreach_property(prop_bt* const trie,
+bool prop_area::foreach_property(prop_trie_node* const trie,
                                  void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
   if (!trie) return false;
 
   uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
   if (left_offset != 0) {
-    const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
+    const int err = foreach_property(to_prop_trie_node(&trie->left), propfn, cookie);
     if (err < 0) return false;
   }
   uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
@@ -347,12 +346,12 @@
   }
   uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
   if (children_offset != 0) {
-    const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
+    const int err = foreach_property(to_prop_trie_node(&trie->children), propfn, cookie);
     if (err < 0) return false;
   }
   uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
   if (right_offset != 0) {
-    const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
+    const int err = foreach_property(to_prop_trie_node(&trie->right), propfn, cookie);
     if (err < 0) return false;
   }
 
diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp
index 1cb15c3..049236f 100644
--- a/libc/system_properties/system_properties.cpp
+++ b/libc/system_properties/system_properties.cpp
@@ -67,26 +67,23 @@
     return true;
   }
 
-  if (strlen(filename) >= PROP_FILENAME_MAX) {
-    return false;
-  }
-  strcpy(property_filename_, filename);
+  properties_filename_ = filename;
 
-  if (is_dir(property_filename_)) {
+  if (is_dir(properties_filename_.c_str())) {
     if (access("/dev/__properties__/property_info", R_OK) == 0) {
       contexts_ = new (contexts_data_) ContextsSerialized();
-      if (!contexts_->Initialize(false, property_filename_, nullptr)) {
+      if (!contexts_->Initialize(false, properties_filename_.c_str(), nullptr)) {
         return false;
       }
     } else {
       contexts_ = new (contexts_data_) ContextsSplit();
-      if (!contexts_->Initialize(false, property_filename_, nullptr)) {
+      if (!contexts_->Initialize(false, properties_filename_.c_str(), nullptr)) {
         return false;
       }
     }
   } else {
     contexts_ = new (contexts_data_) ContextsPreSplit();
-    if (!contexts_->Initialize(false, property_filename_, nullptr)) {
+    if (!contexts_->Initialize(false, properties_filename_.c_str(), nullptr)) {
       return false;
     }
   }
@@ -95,13 +92,9 @@
 }
 
 bool SystemProperties::AreaInit(const char* filename, bool* fsetxattr_failed) {
-  if (strlen(filename) >= PROP_FILENAME_MAX) {
-    return false;
-  }
-  strcpy(property_filename_, filename);
-
+  properties_filename_ = filename;
   contexts_ = new (contexts_data_) ContextsSerialized();
-  if (!contexts_->Initialize(true, property_filename_, fsetxattr_failed)) {
+  if (!contexts_->Initialize(true, properties_filename_.c_str(), fsetxattr_failed)) {
     return false;
   }
   initialized_ = true;
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 4f33777..8c457c8 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -227,11 +227,6 @@
     aliases = syscall["aliases"]
     for alias in aliases:
         stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"])
-
-    # Use hidden visibility on LP64 for any functions beginning with underscores.
-    if pointer_length == 64 and syscall["func"].startswith("__"):
-        stub += '.hidden ' + syscall["func"] + '\n'
-
     return stub
 
 
diff --git a/libc/upstream-freebsd/android/include/libc_private.h b/libc/upstream-freebsd/android/include/libc_private.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libc/upstream-freebsd/android/include/libc_private.h
diff --git a/libc/upstream-freebsd/lib/libc/gen/ldexp.c b/libc/upstream-freebsd/lib/libc/gen/ldexp.c
deleted file mode 100644
index 887f673..0000000
--- a/libc/upstream-freebsd/lib/libc/gen/ldexp.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* @(#)s_scalbn.c 5.1 93/09/24 */
-/* @(#)fdlibm.h 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <machine/endian.h>
-#include <math.h>
-
-/* Bit fiddling routines copied from msun/src/math_private.h,v 1.15 */
-
-#if BYTE_ORDER == BIG_ENDIAN
-
-typedef union
-{
-  double value;
-  struct
-  {
-    u_int32_t msw;
-    u_int32_t lsw;
-  } parts;
-} ieee_double_shape_type;
-
-#endif
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-typedef union
-{
-  double value;
-  struct
-  {
-    u_int32_t lsw;
-    u_int32_t msw;
-  } parts;
-} ieee_double_shape_type;
-
-#endif
-
-/* Get two 32 bit ints from a double.  */
-
-#define EXTRACT_WORDS(ix0,ix1,d)				\
-do {								\
-  ieee_double_shape_type ew_u;					\
-  ew_u.value = (d);						\
-  (ix0) = ew_u.parts.msw;					\
-  (ix1) = ew_u.parts.lsw;					\
-} while (0)
-
-/* Get the more significant 32 bit int from a double.  */
-
-#define GET_HIGH_WORD(i,d)					\
-do {								\
-  ieee_double_shape_type gh_u;					\
-  gh_u.value = (d);						\
-  (i) = gh_u.parts.msw;						\
-} while (0)
-
-/* Set the more significant 32 bits of a double from an int.  */
-
-#define SET_HIGH_WORD(d,v)					\
-do {								\
-  ieee_double_shape_type sh_u;					\
-  sh_u.value = (d);						\
-  sh_u.parts.msw = (v);						\
-  (d) = sh_u.value;						\
-} while (0)
-
-
-static const double
-two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
-huge   = 1.0e+300,
-tiny   = 1.0e-300;
-
-static double
-_copysign(double x, double y)
-{
-	u_int32_t hx,hy;
-	GET_HIGH_WORD(hx,x);
-	GET_HIGH_WORD(hy,y);
-	SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
-	return x;
-}
-
-double
-ldexp(double x, int n)
-{
-	int32_t k,hx,lx;
-	EXTRACT_WORDS(hx,lx,x);
-        k = (hx&0x7ff00000)>>20;		/* extract exponent */
-        if (k==0) {				/* 0 or subnormal x */
-            if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
-	    x *= two54;
-	    GET_HIGH_WORD(hx,x);
-	    k = ((hx&0x7ff00000)>>20) - 54;
-            if (n< -50000) return tiny*x; 	/*underflow*/
-	    }
-        if (k==0x7ff) return x+x;		/* NaN or Inf */
-        k = k+n;
-        if (k >  0x7fe) return huge*_copysign(huge,x); /* overflow  */
-        if (k > 0) 				/* normal result */
-	    {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
-        if (k <= -54) {
-            if (n > 50000) 	/* in case integer overflow in n+k */
-		return huge*_copysign(huge,x);	/*overflow*/
-	    else return tiny*_copysign(tiny,x); 	/*underflow*/
-	}
-        k += 54;				/* subnormal result */
-	SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
-        return x*twom54;
-}
diff --git a/libc/upstream-freebsd/lib/libc/locale/wcsftime.c b/libc/upstream-freebsd/lib/libc/locale/wcsftime.c
index aabb632..4fe6ad5 100644
--- a/libc/upstream-freebsd/lib/libc/locale/wcsftime.c
+++ b/libc/upstream-freebsd/lib/libc/locale/wcsftime.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c b/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
index 6a3067c..1f3548b 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
@@ -55,7 +55,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/getopt_long.c 342757 2019-01-04 03:13:24Z kevans $");
+__FBSDID("$FreeBSD$");
 
 #include <err.h>
 #include <errno.h>
@@ -88,7 +88,7 @@
 #define	BADARG		((*options == ':') ? (int)':' : (int)'?')
 #define	INORDER 	(int)1
 
-#define	EMSG		""
+static char EMSG[] = "";
 
 #ifdef GNU_COMPATIBLE
 #define NO_PREFIX	(-1)
@@ -194,7 +194,7 @@
 {
 	char *current_argv, *has_equal;
 #ifdef GNU_COMPATIBLE
-	char *current_dash;
+	const char *current_dash;
 #endif
 	size_t current_argv_len;
 	int i, match, exact_match, second_partial_match;
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c b/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c
index b175d34..c9a0847 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2015 Nuxi, https://nuxi.nl/
  *
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hcreate.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <search.h>
 #include <stdbool.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c b/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c
index 34db88e..83e322a 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hcreate_r.c 292767 2015-12-27 07:50:11Z ed $");
+__FBSDID("$FreeBSD$");
 
 #include <search.h>
 #include <stdlib.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c b/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c
index 76d8a42..890bd08 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hdestroy_r.c 292767 2015-12-27 07:50:11Z ed $");
+__FBSDID("$FreeBSD$");
 
 #include <search.h>
 #include <stdlib.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h b/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h
index a0542b5..649933d 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h
@@ -22,7 +22,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libc/stdlib/hsearch.h 292767 2015-12-27 07:50:11Z ed $
+ * $FreeBSD$
  */
 
 #ifndef HSEARCH_H
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c b/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c
index 9a859d3..2fb5991 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hsearch_r.c 292767 2015-12-27 07:50:11Z ed $");
+__FBSDID("$FreeBSD$");
 
 #include <errno.h>
 #include <limits.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
index e0db4f3..0d65cd1 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
@@ -33,12 +33,20 @@
 static char sccsid[] = "@(#)qsort.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/qsort.c 334928 2018-06-10 17:54:44Z kib $");
+__FBSDID("$FreeBSD$");
 
+#include <errno.h>
+#include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
+#include "libc_private.h"
 
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
+typedef int		 cmp_t(const void *, const void *, void *);
+#elif defined(I_AM_QSORT_R_COMPAT)
 typedef int		 cmp_t(void *, const void *, const void *);
+#elif defined(I_AM_QSORT_S)
+typedef int		 cmp_t(const void *, const void *, void *);
 #else
 typedef int		 cmp_t(const void *, const void *);
 #endif
@@ -65,15 +73,19 @@
 #define	vecswap(a, b, n)				\
 	if ((n) > 0) swapfunc(a, b, n)
 
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
+#define	CMP(t, x, y) (cmp((x), (y), (t)))
+#elif defined(I_AM_QSORT_R_COMPAT)
 #define	CMP(t, x, y) (cmp((t), (x), (y)))
+#elif defined(I_AM_QSORT_S)
+#define	CMP(t, x, y) (cmp((x), (y), (t)))
 #else
 #define	CMP(t, x, y) (cmp((x), (y)))
 #endif
 
 static inline char *
 med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
-#ifndef I_AM_QSORT_R
+#if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_R_COMPAT) && !defined(I_AM_QSORT_S)
 __unused
 #endif
 )
@@ -83,20 +95,28 @@
 	      :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
 }
 
-#ifdef I_AM_QSORT_R
-void
-qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
-#else
-#define	thunk NULL
-void
-qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+/*
+ * The actual qsort() implementation is static to avoid preemptible calls when
+ * recursing. Also give them different names for improved debugging.
+ */
+#if defined(I_AM_QSORT_R)
+#define local_qsort local_qsort_r
+#elif defined(I_AM_QSORT_R_COMPAT)
+#define local_qsort local_qsort_r_compat
+#elif defined(I_AM_QSORT_S)
+#define local_qsort local_qsort_s
 #endif
+static void
+local_qsort(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk)
 {
 	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
 	size_t d1, d2;
 	int cmp_result;
 	int swap_cnt;
 
+	/* if there are less than 2 elements, then sorting is not needed */
+	if (__predict_false(n < 2))
+		return;
 loop:
 	swap_cnt = 0;
 	if (n < 7) {
@@ -160,7 +180,12 @@
 	pn = (char *)a + n * es;
 	d1 = MIN(pa - (char *)a, pb - pa);
 	vecswap(a, pb - d1, d1);
-	d1 = MIN(pd - pc, pn - pd - es);
+	/*
+	 * Cast es to preserve signedness of right-hand side of MIN()
+	 * expression, to avoid sign ambiguity in the implied comparison.  es
+	 * is safely within [0, SSIZE_MAX].
+	 */
+	d1 = MIN(pd - pc, pn - pd - (ssize_t)es);
 	vecswap(pb, pn - d1, d1);
 
 	d1 = pb - pa;
@@ -168,11 +193,7 @@
 	if (d1 <= d2) {
 		/* Recurse on left partition, then iterate on right partition */
 		if (d1 > es) {
-#ifdef I_AM_QSORT_R
-			qsort_r(a, d1 / es, es, thunk, cmp);
-#else
-			qsort(a, d1 / es, es, cmp);
-#endif
+			local_qsort(a, d1 / es, es, cmp, thunk);
 		}
 		if (d2 > es) {
 			/* Iterate rather than recurse to save stack space */
@@ -184,11 +205,7 @@
 	} else {
 		/* Recurse on right partition, then iterate on left partition */
 		if (d2 > es) {
-#ifdef I_AM_QSORT_R
-			qsort_r(pn - d2, d2 / es, es, thunk, cmp);
-#else
-			qsort(pn - d2, d2 / es, es, cmp);
-#endif
+			local_qsort(pn - d2, d2 / es, es, cmp, thunk);
 		}
 		if (d1 > es) {
 			/* Iterate rather than recurse to save stack space */
@@ -198,3 +215,53 @@
 		}
 	}
 }
+
+#if defined(I_AM_QSORT_R)
+void
+(qsort_r)(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk)
+{
+	local_qsort_r(a, n, es, cmp, thunk);
+}
+#elif defined(I_AM_QSORT_R_COMPAT)
+void
+__qsort_r_compat(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
+{
+	local_qsort_r_compat(a, n, es, cmp, thunk);
+}
+#elif defined(I_AM_QSORT_S)
+errno_t
+qsort_s(void *a, rsize_t n, rsize_t es, cmp_t *cmp, void *thunk)
+{
+	if (n > RSIZE_MAX) {
+		__throw_constraint_handler_s("qsort_s : n > RSIZE_MAX", EINVAL);
+		return (EINVAL);
+	} else if (es > RSIZE_MAX) {
+		__throw_constraint_handler_s("qsort_s : es > RSIZE_MAX",
+		    EINVAL);
+		return (EINVAL);
+	} else if (n != 0) {
+		if (a == NULL) {
+			__throw_constraint_handler_s("qsort_s : a == NULL",
+			    EINVAL);
+			return (EINVAL);
+		} else if (cmp == NULL) {
+			__throw_constraint_handler_s("qsort_s : cmp == NULL",
+			    EINVAL);
+			return (EINVAL);
+		} else if (es <= 0) {
+			__throw_constraint_handler_s("qsort_s : es <= 0",
+			    EINVAL);
+			return (EINVAL);
+		}
+	}
+
+	local_qsort_s(a, n, es, cmp, thunk);
+	return (0);
+}
+#else
+void
+qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+{
+	local_qsort(a, n, es, cmp, NULL);
+}
+#endif
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
index 9e4e79d..d486b1a 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Chisnall
  * All rights reserved.
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libc/stdlib/quick_exit.c 326193 2017-11-25 17:12:48Z pfg $
+ * $FreeBSD$
  */
 
 #include <sys/types.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcpcpy.c b/libc/upstream-freebsd/lib/libc/string/wcpcpy.c
index e040dba..41b7c51 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcpcpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcpcpy.c
@@ -35,7 +35,7 @@
 static char sccsid[] = "@(#)strcpy.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcpcpy.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcpncpy.c b/libc/upstream-freebsd/lib/libc/string/wcpncpy.c
index 8bf6e87..ccc64cd 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcpncpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcpncpy.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcpncpy.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c b/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c
index 5bd468d..03a61f8 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscasecmp.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 #include <wctype.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscat.c b/libc/upstream-freebsd/lib/libc/string/wcscat.c
index 792f61e..777a576 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscat.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscat.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c)1999 Citrus Project,
  * All rights reserved.
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcscat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscat.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcschr.c b/libc/upstream-freebsd/lib/libc/string/wcschr.c
index ca740c0..a7f1de0 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcschr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcschr.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcschr.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscmp.c b/libc/upstream-freebsd/lib/libc/string/wcscmp.c
index db01892..7205238 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscmp.c
@@ -39,7 +39,7 @@
 __RCSID("$NetBSD: wcscmp.c,v 1.3 2001/01/05 12:13:12 itojun Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscmp.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscpy.c b/libc/upstream-freebsd/lib/libc/string/wcscpy.c
index a639e74..b400fae 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscpy.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcscpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscpy.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscspn.c b/libc/upstream-freebsd/lib/libc/string/wcscspn.c
index 8a7682f..a0db715 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscspn.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscspn.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcscspn.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscspn.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsdup.c b/libc/upstream-freebsd/lib/libc/string/wcsdup.c
index b97f766..327574b 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsdup.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsdup.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Tim J. Robbins.
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsdup.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <stdlib.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcslcat.c b/libc/upstream-freebsd/lib/libc/string/wcslcat.c
index 9706fa6..f954b73 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcslcat.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcslcat.c
@@ -35,7 +35,7 @@
 __RCSID("$NetBSD: wcslcat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcslcat.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcslen.c b/libc/upstream-freebsd/lib/libc/string/wcslen.c
index c596825..cfd3aa2 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcslen.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcslen.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcslen.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcslen.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c b/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c
index a963444..39f58be 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncasecmp.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 #include <wctype.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncat.c b/libc/upstream-freebsd/lib/libc/string/wcsncat.c
index 0214af4..eb13fab 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncat.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncat.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcsncat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncat.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncmp.c b/libc/upstream-freebsd/lib/libc/string/wcsncmp.c
index 77b709c..55c88f6 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncmp.c
@@ -36,7 +36,7 @@
 __RCSID("$NetBSD: wcsncmp.c,v 1.3 2001/01/05 12:13:13 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncmp.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncpy.c b/libc/upstream-freebsd/lib/libc/string/wcsncpy.c
index 4075ecc..f86e40f 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncpy.c
@@ -38,7 +38,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncpy.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsnlen.c b/libc/upstream-freebsd/lib/libc/string/wcsnlen.c
index 271d341..15fd520 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsnlen.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsnlen.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsnlen.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcspbrk.c b/libc/upstream-freebsd/lib/libc/string/wcspbrk.c
index 63efb01..0e9ccf6 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcspbrk.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcspbrk.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcspbrk.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcspbrk.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsrchr.c b/libc/upstream-freebsd/lib/libc/string/wcsrchr.c
index 97665ca..cc5e7f2 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsrchr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsrchr.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsrchr.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsspn.c b/libc/upstream-freebsd/lib/libc/string/wcsspn.c
index b08a39e..2b08acb 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsspn.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsspn.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcsspn.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsspn.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsstr.c b/libc/upstream-freebsd/lib/libc/string/wcsstr.c
index 4309025..74921fe 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsstr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsstr.c
@@ -38,7 +38,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsstr.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcstok.c b/libc/upstream-freebsd/lib/libc/string/wcstok.c
index 8d62bf7..b4bdc86 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcstok.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcstok.c
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcstok.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemchr.c b/libc/upstream-freebsd/lib/libc/string/wmemchr.c
index 412a276..42ae286 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemchr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemchr.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemchr.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemchr.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemcmp.c b/libc/upstream-freebsd/lib/libc/string/wmemcmp.c
index c1e9f3c..f1b1b00 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemcmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemcmp.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemcmp.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemcmp.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemcpy.c b/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
index e0d6c04..30956eb 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemcpy.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemcpy.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <string.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemmove.c b/libc/upstream-freebsd/lib/libc/string/wmemmove.c
index b84c2c0..5e8da9f 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemmove.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemmove.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemmove.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemmove.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <string.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemset.c b/libc/upstream-freebsd/lib/libc/string/wmemset.c
index d4d6308..fcf40ef 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemset.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemset.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemset.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemset.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-netbsd/lib/libc/regex/regcomp.c b/libc/upstream-netbsd/lib/libc/regex/regcomp.c
index 957f8ac..86321c1 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.46 2021/03/11 15:00:29 christos Exp $	*/
+/*	$NetBSD: regcomp.c,v 1.47 2022/12/21 17:44:15 wiz Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
@@ -51,9 +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.46 2021/03/11 15:00:29 christos Exp $");
-
-#define _OPENBSD_SOURCE
+__RCSID("$NetBSD: regcomp.c,v 1.47 2022/12/21 17:44:15 wiz Exp $");
 
 #ifndef LIBHACK
 #define REGEX_GNU_EXTENSIONS
diff --git a/libc/upstream-netbsd/android/include/rand48.h b/libc/upstream-netbsd/lib/libc/stdlib/rand48.h
similarity index 80%
rename from libc/upstream-netbsd/android/include/rand48.h
rename to libc/upstream-netbsd/lib/libc/stdlib/rand48.h
index 1279906..1ad8b0d 100644
--- a/libc/upstream-netbsd/android/include/rand48.h
+++ b/libc/upstream-netbsd/lib/libc/stdlib/rand48.h
@@ -18,10 +18,10 @@
 
 #include <stdlib.h>
 
-__LIBC_HIDDEN__ void		__dorand48(unsigned short[3]);
-__LIBC_HIDDEN__ unsigned short	__rand48_seed[3];
-__LIBC_HIDDEN__ unsigned short	__rand48_mult[3];
-__LIBC_HIDDEN__ unsigned short	__rand48_add;
+extern void		__dorand48(unsigned short[3]);
+extern unsigned short	__rand48_seed[3];
+extern unsigned short	__rand48_mult[3];
+extern unsigned short	__rand48_add;
 
 #define	RAND48_SEED_0	(0x330e)
 #define	RAND48_SEED_1	(0xabcd)
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
index 6ee5a5c..af0169f 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_memstream.c,v 1.8 2019/05/02 08:30:10 yasuoka Exp $	*/
+/*	$OpenBSD: open_memstream.c,v 1.10 2023/07/11 12:14:16 claudio Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -53,7 +53,6 @@
 		p = recallocarray(st->string, st->size, sz, 1);
 		if (!p)
 			return (-1);
-		bzero(p + st->size, sz - st->size);
 		*st->pbuf = st->string = p;
 		st->size = sz;
 	}
@@ -136,7 +135,6 @@
 		return (NULL);
 	}
 
-	*st->string = '\0';
 	st->pos = 0;
 	st->len = 0;
 	st->pbuf = pbuf;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
index aceef35..fca0b71 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_wmemstream.c,v 1.8 2015/09/12 16:23:14 guenther Exp $	*/
+/*	$OpenBSD: open_wmemstream.c,v 1.10 2023/07/11 12:14:16 claudio Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -52,10 +52,9 @@
 
 		if (sz < end + 1)
 			sz = end + 1;
-		p = reallocarray(st->string, sz, sizeof(wchar_t));
+		p = recallocarray(st->string, st->size, sz, sizeof(wchar_t));
 		if (!p)
 			return (-1);
-		bzero(p + st->size, (sz - st->size) * sizeof(wchar_t));
 		*st->pbuf = st->string = p;
 		st->size = sz;
 	}
@@ -146,7 +145,6 @@
 		return (NULL);
 	}
 
-	*st->string = L'\0';
 	st->pos = 0;
 	st->len = 0;
 	st->pbuf = pbuf;
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 3b68fc7..23cd7f5 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -26,15 +26,15 @@
 // dlopen/dlclose.
 static struct {
   uintptr_t v;
-  char padding[PAGE_SIZE - sizeof(v)];
-} shadow_base_storage alignas(PAGE_SIZE);
+  char padding[max_page_size() - sizeof(v)];
+} shadow_base_storage alignas(max_page_size());
 
 // __cfi_init is called by the loader as soon as the shadow is mapped. This may happen very early
 // during startup, before libdl.so global constructors, and, on i386, even before __libc_sysinfo is
 // initialized. This function should not do any system calls.
 extern "C" uintptr_t* __cfi_init(uintptr_t shadow_base) {
   shadow_base_storage.v = shadow_base;
-  static_assert(sizeof(shadow_base_storage) == PAGE_SIZE, "");
+  static_assert(sizeof(shadow_base_storage) == max_page_size(), "");
   return &shadow_base_storage.v;
 }
 
diff --git a/libm/Android.bp b/libm/Android.bp
index 079fd9a..a89885f 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -466,8 +466,6 @@
     name: "libm",
     symbol_file: "libm.map.txt",
     first_version: "9",
-    // APIs implemented in asm don't have debug info: http://b/190554910.
-    allow_untyped_symbols: true,
 }
 
 genrule {
@@ -509,3 +507,8 @@
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
 }
+
+filegroup {
+    name: "libc_ldexp_srcs",
+    srcs: ["upstream-freebsd/lib/msun/src/s_scalbn.c"],
+}
diff --git a/libm/NOTICE b/libm/NOTICE
index 5e2f8ca..31337e7 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -1176,6 +1176,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2017, 2023 Steven G. Kargl
+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 unmodified, 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.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
 From: @(#)s_ilogb.c 5.1 93/09/24
 ====================================================
 Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/invtrig.c b/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
index ab93732..3ba767b 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/invtrig.h b/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
index 423b568..3f505c5 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
index 159338f..3faf7a7 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
@@ -1,7 +1,7 @@
 /* from: FreeBSD: head/lib/msun/ld128/s_expl.c 251345 2013-06-03 20:09:22Z kargl */
 
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009-2013 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c b/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
index ee3d2c7..bcbdc5f 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_expl.c b/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
index 5b786af..0274a8f 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009-2013 Steven G. Kargl
  * All rights reserved.
@@ -65,8 +65,6 @@
 	int k;
 	uint16_t hx, ix;
 
-	DOPRINT_START(&x);
-
 	/* Filter out exceptional cases. */
 	u.e = x;
 	hx = u.xbits.expsign;
@@ -74,15 +72,15 @@
 	if (ix >= BIAS + 13) {		/* |x| >= 8192 or x is NaN */
 		if (ix == BIAS + LDBL_MAX_EXP) {
 			if (hx & 0x8000)  /* x is -Inf or -NaN */
-				RETURNP(-1 / x);
-			RETURNP(x + x);	/* x is +Inf or +NaN */
+				RETURNF(-1 / x);
+			RETURNF(x + x);	/* x is +Inf or +NaN */
 		}
 		if (x > o_threshold)
-			RETURNP(huge * huge);
+			RETURNF(huge * huge);
 		if (x < u_threshold)
-			RETURNP(tiny * tiny);
+			RETURNF(tiny * tiny);
 	} else if (ix < BIAS - 114) {	/* |x| < 0x1p-114 */
-		RETURN2P(1, x);		/* 1 with inexact iff x != 0 */
+		RETURNF(1 + x);		/* 1 with inexact iff x != 0 */
 	}
 
 	ENTERI();
@@ -210,8 +208,6 @@
 	int k, n, n2;
 	uint16_t hx, ix;
 
-	DOPRINT_START(&x);
-
 	/* Filter out exceptional cases. */
 	u.e = x;
 	hx = u.xbits.expsign;
@@ -219,11 +215,11 @@
 	if (ix >= BIAS + 7) {		/* |x| >= 128 or x is NaN */
 		if (ix == BIAS + LDBL_MAX_EXP) {
 			if (hx & 0x8000)  /* x is -Inf or -NaN */
-				RETURNP(-1 / x - 1);
-			RETURNP(x + x);	/* x is +Inf or +NaN */
+				RETURNF(-1 / x - 1);
+			RETURNF(x + x);	/* x is +Inf or +NaN */
 		}
 		if (x > o_threshold)
-			RETURNP(huge * huge);
+			RETURNF(huge * huge);
 		/*
 		 * expm1l() never underflows, but it must avoid
 		 * unrepresentable large negative exponents.  We used a
@@ -232,7 +228,7 @@
 		 * in the same way as large ones here.
 		 */
 		if (hx & 0x8000)	/* x <= -128 */
-			RETURN2P(tiny, -1);	/* good for x < -114ln2 - eps */
+			RETURNF(tiny - 1);	/* good for x < -114ln2 - eps */
 	}
 
 	ENTERI();
@@ -244,7 +240,7 @@
 		if (x < T3) {
 			if (ix < BIAS - 113) {	/* |x| < 0x1p-113 */
 				/* x (rounded) with inexact if x != 0: */
-				RETURNPI(x == 0 ? x :
+				RETURNI(x == 0 ? x :
 				    (0x1p200 * x + fabsl(x)) * 0x1p-200);
 			}
 			q = x * x2 * C3 + x2 * x2 * (C4 + x * (C5 + x * (C6 +
@@ -265,9 +261,9 @@
 		hx2_hi = x_hi * x_hi / 2;
 		hx2_lo = x_lo * (x + x_hi) / 2;
 		if (ix >= BIAS - 7)
-			RETURN2PI(hx2_hi + x_hi, hx2_lo + x_lo + q);
+			RETURNI((hx2_hi + x_hi) + (hx2_lo + x_lo + q));
 		else
-			RETURN2PI(x, hx2_lo + q + hx2_hi);
+			RETURNI(x + (hx2_lo + q + hx2_hi));
 	}
 
 	/* Reduce x to (k*ln2 + endpoint[n2] + r1 + r2). */
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
index 4774a27..bc53884 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007-2013 Bruce D. Evans
  * All rights reserved.
@@ -573,24 +573,23 @@
 	int i, k;
 	int16_t ax, hx;
 
-	DOPRINT_START(&x);
 	EXTRACT_LDBL128_WORDS(hx, lx, llx, x);
 	if (hx < 0x3fff) {		/* x < 1, or x neg NaN */
 		ax = hx & 0x7fff;
 		if (ax >= 0x3fff) {	/* x <= -1, or x neg NaN */
 			if (ax == 0x3fff && (lx | llx) == 0)
-				RETURNP(-1 / zero);	/* log1p(-1) = -Inf */
+				RETURNF(-1 / zero);	/* log1p(-1) = -Inf */
 			/* log1p(x < 1, or x NaN) = qNaN: */
-			RETURNP((x - x) / (x - x));
+			RETURNF((x - x) / (x - x));
 		}
 		if (ax <= 0x3f8d) {	/* |x| < 2**-113 */
 			if ((int)x == 0)
-				RETURNP(x);	/* x with inexact if x != 0 */
+				RETURNF(x);	/* x with inexact if x != 0 */
 		}
 		f_hi = 1;
 		f_lo = x;
 	} else if (hx >= 0x7fff) {	/* x +Inf or non-neg NaN */
-		RETURNP(x + x);		/* log1p(Inf or NaN) = Inf or qNaN */
+		RETURNF(x + x);		/* log1p(Inf or NaN) = Inf or qNaN */
 	} else if (hx < 0x40e1) {	/* 1 <= x < 2**226 */
 		f_hi = x;
 		f_lo = 1;
@@ -669,7 +668,7 @@
 #endif
 
 	_3sumF(val_hi, val_lo, F_hi(i) + dk * ln2_hi);
-	RETURN2PI(val_hi, val_lo);
+	RETURNI(val_hi + val_lo);
 }
 
 #ifdef STRUCT_RETURN
@@ -680,7 +679,6 @@
 	struct ld r;
 
 	ENTERI();
-	DOPRINT_START(&x);
 	k_logl(x, &r);
 	RETURNSPI(&r);
 }
@@ -708,15 +706,13 @@
 	long double hi, lo;
 
 	ENTERI();
-	DOPRINT_START(&x);
 	k_logl(x, &r);
 	if (!r.lo_set)
-		RETURNPI(r.hi);
+		RETURNI(r.hi);
 	_2sumF(r.hi, r.lo);
 	hi = (float)r.hi;
 	lo = r.lo + (r.hi - hi);
-	RETURN2PI(invln10_hi * hi,
-	    invln10_lo_plus_hi * lo + invln10_lo * hi);
+	RETURNI(invln10_hi * hi + (invln10_lo_plus_hi * lo + invln10_lo * hi));
 }
 
 long double
@@ -726,15 +722,13 @@
 	long double hi, lo;
 
 	ENTERI();
-	DOPRINT_START(&x);
 	k_logl(x, &r);
 	if (!r.lo_set)
-		RETURNPI(r.hi);
+		RETURNI(r.hi);
 	_2sumF(r.hi, r.lo);
 	hi = (float)r.hi;
 	lo = r.lo + (r.hi - hi);
-	RETURN2PI(invln2_hi * hi,
-	    invln2_lo_plus_hi * lo + invln2_lo * hi);
+	RETURNI(invln2_hi * hi + (invln2_lo_plus_hi * lo + invln2_lo * hi));
 }
 
 #endif /* STRUCT_RETURN */
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c b/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
index 45d10e5..cde3f18 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/catrig.c b/libm/upstream-freebsd/lib/msun/src/catrig.c
index 431d8e6..82061b5 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrig.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrig.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/catrigf.c b/libm/upstream-freebsd/lib/msun/src/catrigf.c
index 62bcd39..fb4a6bf 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrigf.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrigf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acos.c b/libm/upstream-freebsd/lib/msun/src/e_acos.c
index 1f6dca5..6623355 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acos.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acos.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_acos(x)
+/* acos(x)
  * Method :                  
  *	acos(x)  = pi/2 - asin(x)
  *	acos(-x) = pi/2 + asin(x)
@@ -62,7 +62,7 @@
 qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
 
 double
-__ieee754_acos(double x)
+acos(double x)
 {
 	double z,p,q,r,w,s,c,df;
 	int32_t hx,ix;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acosf.c b/libm/upstream-freebsd/lib/msun/src/e_acosf.c
index c9f62cc..64f1c5a 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acosf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acosf.c
@@ -32,7 +32,7 @@
 qS1 = -7.0662963390e-01;
 
 float
-__ieee754_acosf(float x)
+acosf(float x)
 {
 	float z,p,q,r,w,s,c,df;
 	int32_t hx,ix;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acosh.c b/libm/upstream-freebsd/lib/msun/src/e_acosh.c
index 358c8bd..7947995 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acosh.c
@@ -15,7 +15,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_acosh(x)
+/* acosh(x)
  * Method :
  *	Based on 
  *		acosh(x) = log [ x + sqrt(x*x-1) ]
@@ -39,7 +39,7 @@
 ln2	= 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
 
 double
-__ieee754_acosh(double x)
+acosh(double x)
 {
 	double t;
 	int32_t hx;
@@ -51,12 +51,12 @@
 	    if(hx >=0x7ff00000) {	/* x is inf of NaN */
 	        return x+x;
 	    } else 
-		return __ieee754_log(x)+ln2;	/* acosh(huge)=log(2x) */
+		return log(x)+ln2;	/* acosh(huge)=log(2x) */
 	} else if(((hx-0x3ff00000)|lx)==0) {
 	    return 0.0;			/* acosh(1) = 0 */
 	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
 	    t=x*x;
-	    return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
+	    return log(2.0*x-one/(x+sqrt(t-one)));
 	} else {			/* 1<x<2 */
 	    t = x-one;
 	    return log1p(t+sqrt(2.0*t+t*t));
diff --git a/libm/upstream-freebsd/lib/msun/src/e_acoshf.c b/libm/upstream-freebsd/lib/msun/src/e_acoshf.c
index f529b20..781ccf2 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_acoshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_acoshf.c
@@ -24,7 +24,7 @@
 ln2	= 6.9314718246e-01;  /* 0x3f317218 */
 
 float
-__ieee754_acoshf(float x)
+acoshf(float x)
 {
 	float t;
 	int32_t hx;
@@ -35,14 +35,14 @@
 	    if(hx >=0x7f800000) {	/* x is inf of NaN */
 	        return x+x;
 	    } else
-		return __ieee754_logf(x)+ln2;	/* acosh(huge)=log(2x) */
+		return logf(x)+ln2;	/* acosh(huge)=log(2x) */
 	} else if (hx==0x3f800000) {
 	    return 0.0;			/* acosh(1) = 0 */
 	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
 	    t=x*x;
-	    return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one)));
+	    return logf((float)2.0*x-one/(x+sqrtf(t-one)));
 	} else {			/* 1<x<2 */
 	    t = x-one;
-	    return log1pf(t+__ieee754_sqrtf((float)2.0*t+t*t));
+	    return log1pf(t+sqrtf((float)2.0*t+t*t));
 	}
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_asin.c b/libm/upstream-freebsd/lib/msun/src/e_asin.c
index 931b270..fa180ab 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_asin.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_asin.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_asin(x)
+/* asin(x)
  * Method :                  
  *	Since  asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
  *	we approximate asin(x) on [0,0.5] by
@@ -68,7 +68,7 @@
 qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
 
 double
-__ieee754_asin(double x)
+asin(double x)
 {
 	double t=0.0,w,p,q,c,r,s;
 	int32_t hx,ix;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_asinf.c b/libm/upstream-freebsd/lib/msun/src/e_asinf.c
index deaabb6..db4b9b6 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_asinf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_asinf.c
@@ -32,7 +32,7 @@
 pio2 =  1.570796326794896558e+00;
 
 float
-__ieee754_asinf(float x)
+asinf(float x)
 {
 	double s;
 	float t,w,p,q;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atan2.c b/libm/upstream-freebsd/lib/msun/src/e_atan2.c
index 231a161..0b2e721 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atan2.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atan2.c
@@ -15,7 +15,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_atan2(y,x)
+/* atan2(y,x)
  * Method :
  *	1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
  *	2. Reduce x to positive by (if x and y are unexceptional): 
@@ -58,7 +58,7 @@
 pi_lo   = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
 
 double
-__ieee754_atan2(double y, double x)
+atan2(double y, double x)
 {
 	double z;
 	int32_t k,m,hx,hy,ix,iy;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atan2f.c b/libm/upstream-freebsd/lib/msun/src/e_atan2f.c
index 346d767..4ea001d 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atan2f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atan2f.c
@@ -30,7 +30,7 @@
 pi_lo   = -8.7422776573e-08; /* 0xb3bbbd2e */
 
 float
-__ieee754_atan2f(float y, float x)
+atan2f(float y, float x)
 {
 	float z;
 	int32_t k,m,hx,hy,ix,iy;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atanh.c b/libm/upstream-freebsd/lib/msun/src/e_atanh.c
index 422ff26..41f3bca 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atanh.c
@@ -15,7 +15,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_atanh(x)
+/* atanh(x)
  * Method :
  *    1.Reduced x to positive by atanh(-x) = -atanh(x)
  *    2.For x>=0.5
@@ -42,7 +42,7 @@
 static const double zero = 0.0;
 
 double
-__ieee754_atanh(double x)
+atanh(double x)
 {
 	double t;
 	int32_t hx,ix;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_atanhf.c b/libm/upstream-freebsd/lib/msun/src/e_atanhf.c
index 4bd6a8f..46643be 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_atanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_atanhf.c
@@ -24,7 +24,7 @@
 static const float zero = 0.0;
 
 float
-__ieee754_atanhf(float x)
+atanhf(float x)
 {
 	float t;
 	int32_t hx,ix;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_cosh.c b/libm/upstream-freebsd/lib/msun/src/e_cosh.c
index 246b5fb..071663e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_cosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_cosh.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_cosh(x)
+/* cosh(x)
  * Method : 
  * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
  *	1. Replace x by |x| (cosh(x) = cosh(-x)). 
@@ -43,7 +43,7 @@
 static const double one = 1.0, half=0.5, huge = 1.0e300;
 
 double
-__ieee754_cosh(double x)
+cosh(double x)
 {
 	double t,w;
 	int32_t ix;
@@ -65,12 +65,12 @@
 
     /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
 	if (ix < 0x40360000) {
-		t = __ieee754_exp(fabs(x));
+		t = exp(fabs(x));
 		return half*t+half/t;
 	}
 
     /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
-	if (ix < 0x40862E42)  return half*__ieee754_exp(fabs(x));
+	if (ix < 0x40862E42)  return half*exp(fabs(x));
 
     /* |x| in [log(maxdouble), overflowthresold] */
 	if (ix<=0x408633CE)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_coshf.c b/libm/upstream-freebsd/lib/msun/src/e_coshf.c
index 95a0d6e..1673315 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_coshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_coshf.c
@@ -22,7 +22,7 @@
 static const float one = 1.0, half=0.5, huge = 1.0e30;
 
 float
-__ieee754_coshf(float x)
+coshf(float x)
 {
 	float t,w;
 	int32_t ix;
@@ -43,12 +43,12 @@
 
     /* |x| in [0.5*ln2,9], return (exp(|x|)+1/exp(|x|))/2; */
 	if (ix < 0x41100000) {
-		t = __ieee754_expf(fabsf(x));
+		t = expf(fabsf(x));
 		return half*t+half/t;
 	}
 
     /* |x| in [9, log(maxfloat)] return half*exp(|x|) */
-	if (ix < 0x42b17217)  return half*__ieee754_expf(fabsf(x));
+	if (ix < 0x42b17217)  return half*expf(fabsf(x));
 
     /* |x| in [log(maxfloat), overflowthresold] */
 	if (ix<=0x42b2d4fc)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_exp.c b/libm/upstream-freebsd/lib/msun/src/e_exp.c
index dd04d8e..59da392 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_exp.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_exp.c
@@ -13,7 +13,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_exp(x)
+/* exp(x)
  * Returns the exponential of x.
  *
  * Method
@@ -102,7 +102,7 @@
 twom1000= 9.33263618503218878990e-302;     /* 2**-1000=0x01700000,0*/
 
 double
-__ieee754_exp(double x)	/* default IEEE double exp */
+exp(double x)	/* default IEEE double exp */
 {
 	double y,hi=0.0,lo=0.0,c,t,twopk;
 	int32_t k=0,xsb;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_expf.c b/libm/upstream-freebsd/lib/msun/src/e_expf.c
index 4903d55..620d341 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_expf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_expf.c
@@ -43,7 +43,7 @@
 twom100 = 7.8886090522e-31;      /* 2**-100=0x0d800000 */
 
 float
-__ieee754_expf(float x)
+expf(float x)
 {
 	float y,hi=0.0,lo=0.0,c,t,twopk;
 	int32_t k=0,xsb;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_fmod.c b/libm/upstream-freebsd/lib/msun/src/e_fmod.c
index 3a28dc4..6d5f533 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_fmod.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_fmod.c
@@ -15,7 +15,7 @@
 __FBSDID("$FreeBSD$");
 
 /* 
- * __ieee754_fmod(x,y)
+ * fmod(x,y)
  * Return x mod y in exact arithmetic
  * Method: shift and subtract
  */
@@ -28,7 +28,7 @@
 static const double one = 1.0, Zero[] = {0.0, -0.0,};
 
 double
-__ieee754_fmod(double x, double y)
+fmod(double x, double y)
 {
 	int32_t n,hx,hy,hz,ix,iy,sx,i;
 	u_int32_t lx,ly,lz;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_fmodf.c b/libm/upstream-freebsd/lib/msun/src/e_fmodf.c
index 1b6bf36..3cef921 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_fmodf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_fmodf.c
@@ -17,7 +17,7 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * __ieee754_fmodf(x,y)
+ * fmodf(x,y)
  * Return x mod y in exact arithmetic
  * Method: shift and subtract
  */
@@ -28,7 +28,7 @@
 static const float one = 1.0, Zero[] = {0.0, -0.0,};
 
 float
-__ieee754_fmodf(float x, float y)
+fmodf(float x, float y)
 {
 	int32_t n,hx,hy,hz,ix,iy,sx,i;
 
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gamma.c b/libm/upstream-freebsd/lib/msun/src/e_gamma.c
index 28fb5cc..a13f3e2 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gamma.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gamma.c
@@ -15,10 +15,10 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_gamma(x)
+/* gamma(x)
  * Return the logarithm of the Gamma function of x.
  *
- * Method: call __ieee754_gamma_r
+ * Method: call gamma_r
  */
 
 #include "math.h"
@@ -27,7 +27,7 @@
 extern int signgam;
 
 double
-__ieee754_gamma(double x)
+gamma(double x)
 {
-	return __ieee754_gamma_r(x,&signgam);
+	return gamma_r(x,&signgam);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c b/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c
index 2c423dc..2d996ca 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gamma_r.c
@@ -15,18 +15,18 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_gamma_r(x, signgamp)
+/* gamma_r(x, signgamp)
  * Reentrant version of the logarithm of the Gamma function 
  * with user provide pointer for the sign of Gamma(x). 
  *
- * Method: See __ieee754_lgamma_r
+ * Method: See lgamma_r
  */
 
 #include "math.h"
 #include "math_private.h"
 
 double
-__ieee754_gamma_r(double x, int *signgamp)
+gamma_r(double x, int *signgamp)
 {
-	return __ieee754_lgamma_r(x,signgamp);
+	return lgamma_r(x,signgamp);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gammaf.c b/libm/upstream-freebsd/lib/msun/src/e_gammaf.c
index c1b1668..563c148 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gammaf.c
@@ -16,10 +16,10 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_gammaf(x)
+/* gammaf(x)
  * Return the logarithm of the Gamma function of x.
  *
- * Method: call __ieee754_gammaf_r
+ * Method: call gammaf_r
  */
 
 #include "math.h"
@@ -28,7 +28,7 @@
 extern int signgam;
 
 float
-__ieee754_gammaf(float x)
+gammaf(float x)
 {
-	return __ieee754_gammaf_r(x,&signgam);
+	return gammaf_r(x,&signgam);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c b/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c
index 9d7831b..d7fc2db 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_gammaf_r.c
@@ -16,18 +16,18 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_gammaf_r(x, signgamp)
+/* gammaf_r(x, signgamp)
  * Reentrant version of the logarithm of the Gamma function
  * with user provide pointer for the sign of Gamma(x).
  *
- * Method: See __ieee754_lgammaf_r
+ * Method: See lgammaf_r
  */
 
 #include "math.h"
 #include "math_private.h"
 
 float
-__ieee754_gammaf_r(float x, int *signgamp)
+gammaf_r(float x, int *signgamp)
 {
-	return __ieee754_lgammaf_r(x,signgamp);
+	return lgammaf_r(x,signgamp);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_hypot.c b/libm/upstream-freebsd/lib/msun/src/e_hypot.c
index 7c455bb..8e3f931 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_hypot.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_hypot.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_hypot(x,y)
+/* hypot(x,y)
  *
  * Method :                  
  *	If (assume round-to-nearest) z=x*x+y*y 
@@ -52,7 +52,7 @@
 #include "math_private.h"
 
 double
-__ieee754_hypot(double x, double y)
+hypot(double x, double y)
 {
 	double a,b,t1,t2,y1,y2,w;
 	int32_t j,k,ha,hb;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_hypotf.c b/libm/upstream-freebsd/lib/msun/src/e_hypotf.c
index 0061026..a3b8c86 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_hypotf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_hypotf.c
@@ -20,7 +20,7 @@
 #include "math_private.h"
 
 float
-__ieee754_hypotf(float x, float y)
+hypotf(float x, float y)
 {
 	float a,b,t1,t2,y1,y2,w;
 	int32_t j,k,ha,hb;
@@ -67,14 +67,14 @@
 	if (w>b) {
 	    SET_FLOAT_WORD(t1,ha&0xfffff000);
 	    t2 = a-t1;
-	    w  = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
+	    w  = sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
 	} else {
 	    a  = a+a;
 	    SET_FLOAT_WORD(y1,hb&0xfffff000);
 	    y2 = b - y1;
 	    SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000);
 	    t2 = a - t1;
-	    w  = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+	    w  = sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
 	}
 	if(k!=0) {
 	    SET_FLOAT_WORD(t1,(127+k)<<23);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j0.c b/libm/upstream-freebsd/lib/msun/src/e_j0.c
index 5d862b6..c43ab69 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j0.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j0.c
@@ -13,7 +13,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_j0(x), __ieee754_y0(x)
+/* j0(x), y0(x)
  * Bessel function of the first and second kinds of order zero.
  * Method -- j0(x):
  *	1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
@@ -83,7 +83,7 @@
 static const double zero = 0, qrtr = 0.25;
 
 double
-__ieee754_j0(double x)
+j0(double x)
 {
 	double z, s,c,ss,cc,r,u,v;
 	int32_t hx,ix;
@@ -143,7 +143,7 @@
 v04  =  4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
 
 double
-__ieee754_y0(double x)
+y0(double x)
 {
 	double z, s,c,ss,cc,u,v;
 	int32_t hx,ix,lx;
@@ -192,12 +192,12 @@
                 return z;
 	}
 	if(ix<=0x3e400000) {	/* x < 2**-27 */
-	    return(u00 + tpi*__ieee754_log(x));
+	    return(u00 + tpi*log(x));
 	}
 	z = x*x;
 	u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
 	v = one+z*(v01+z*(v02+z*(v03+z*v04)));
-	return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
+	return(u/v + tpi*(j0(x)*log(x)));
 }
 
 /* The asymptotic expansions of pzero is
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j0f.c b/libm/upstream-freebsd/lib/msun/src/e_j0f.c
index 1c5ef4d..290be04 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j0f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j0f.c
@@ -45,7 +45,7 @@
 static const float zero = 0, qrtr = 0.25;
 
 float
-__ieee754_j0f(float x)
+j0f(float x)
 {
 	float z, s,c,ss,cc,r,u,v;
 	int32_t hx,ix;
@@ -105,7 +105,7 @@
 v04  =  4.4111031494e-10; /* 0x2ff280c2 */
 
 float
-__ieee754_y0f(float x)
+y0f(float x)
 {
 	float z, s,c,ss,cc,u,v;
 	int32_t hx,ix;
@@ -147,12 +147,12 @@
                 return z;
 	}
 	if(ix<=0x39000000) {	/* x < 2**-13 */
-	    return(u00 + tpi*__ieee754_logf(x));
+	    return(u00 + tpi*logf(x));
 	}
 	z = x*x;
 	u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
 	v = one+z*(v01+z*(v02+z*(v03+z*v04)));
-	return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x)));
+	return(u/v + tpi*(j0f(x)*logf(x)));
 }
 
 /* The asymptotic expansions of pzero is
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j1.c b/libm/upstream-freebsd/lib/msun/src/e_j1.c
index fb44627..ee3f6fc 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j1.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j1.c
@@ -13,7 +13,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_j1(x), __ieee754_y1(x)
+/* j1(x), y1(x)
  * Bessel function of the first and second kinds of order zero.
  * Method -- j1(x):
  *	1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
@@ -84,7 +84,7 @@
 static const double zero    = 0.0;
 
 double
-__ieee754_j1(double x)
+j1(double x)
 {
 	double z, s,c,ss,cc,r,u,v,y;
 	int32_t hx,ix;
@@ -140,7 +140,7 @@
 };
 
 double
-__ieee754_y1(double x)
+y1(double x)
 {
 	double z, s,c,ss,cc,u,v;
 	int32_t hx,ix,lx;
@@ -190,7 +190,7 @@
         z = x*x;
         u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
         v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
-        return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x));
+        return(x*(u/v) + tpi*(j1(x)*log(x)-one/x));
 }
 
 /* For x >= 8, the asymptotic expansions of pone is
diff --git a/libm/upstream-freebsd/lib/msun/src/e_j1f.c b/libm/upstream-freebsd/lib/msun/src/e_j1f.c
index c6c45c1..e1f4498 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_j1f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_j1f.c
@@ -46,7 +46,7 @@
 static const float zero    = 0.0;
 
 float
-__ieee754_j1f(float x)
+j1f(float x)
 {
 	float z, s,c,ss,cc,r,u,v,y;
 	int32_t hx,ix;
@@ -102,7 +102,7 @@
 };
 
 float
-__ieee754_y1f(float x)
+y1f(float x)
 {
 	float z, s,c,ss,cc,u,v;
 	int32_t hx,ix;
@@ -145,7 +145,7 @@
         z = x*x;
         u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
         v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
-        return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x));
+        return(x*(u/v) + tpi*(j1f(x)*logf(x)-one/x));
 }
 
 /* For x >= 8, the asymptotic expansions of pone is
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jn.c b/libm/upstream-freebsd/lib/msun/src/e_jn.c
index c7ba7da..6b876ce 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jn.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jn.c
@@ -14,7 +14,7 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * __ieee754_jn(n, x), __ieee754_yn(n, x)
+ * jn(n, x), yn(n, x)
  * floating point Bessel's function of the 1st and 2nd kind
  * of order n
  *
@@ -22,15 +22,15 @@
  *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
  *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
  * Note 2. About jn(n,x), yn(n,x)
- *	For n=0, j0(x) is called,
- *	for n=1, j1(x) is called,
- *	for n<x, forward recursion us used starting
+ *	For n=0, j0(x) is called.
+ *	For n=1, j1(x) is called.
+ *	For n<x, forward recursion is used starting
  *	from values of j0(x) and j1(x).
- *	for n>x, a continued fraction approximation to
+ *	For n>x, a continued fraction approximation to
  *	j(n,x)/j(n-1,x) is evaluated and then backward
  *	recursion is used starting from a supposed value
- *	for j(n,x). The resulting value of j(0,x) is
- *	compared with the actual value to correct the
+ *	for j(n,x). The resulting values of j(0,x) or j(1,x) are
+ *	compared with the actual values to correct the
  *	supposed value of j(n,x).
  *
  *	yn(n,x) is similar in all respects, except
@@ -51,7 +51,7 @@
 static const double zero  =  0.00000000000000000000e+00;
 
 double
-__ieee754_jn(int n, double x)
+jn(int n, double x)
 {
 	int32_t i,hx,ix,lx, sgn;
 	double a, b, c, s, temp, di;
@@ -69,8 +69,8 @@
 		x = -x;
 		hx ^= 0x80000000;
 	}
-	if(n==0) return(__ieee754_j0(x));
-	if(n==1) return(__ieee754_j1(x));
+	if(n==0) return(j0(x));
+	if(n==1) return(j1(x));
 	sgn = (n&1)&(hx>>31);	/* even n -- 0, odd n -- sign(x) */
 	x = fabs(x);
 	if((ix|lx)==0||ix>=0x7ff00000) 	/* if x is 0 or inf */
@@ -100,8 +100,8 @@
 		}
 		b = invsqrtpi*temp/sqrt(x);
 	    } else {
-	        a = __ieee754_j0(x);
-	        b = __ieee754_j1(x);
+	        a = j0(x);
+	        b = j1(x);
 	        for(i=1;i<n;i++){
 		    temp = b;
 		    b = b*((double)(i+i)/x) - a; /* avoid underflow */
@@ -177,7 +177,7 @@
 		 */
 		tmp = n;
 		v = two/x;
-		tmp = tmp*__ieee754_log(fabs(v*tmp));
+		tmp = tmp*log(fabs(v*tmp));
 		if(tmp<7.09782712893383973096e+02) {
 	    	    for(i=n-1,di=(double)(i+i);i>0;i--){
 		        temp = b;
@@ -201,8 +201,8 @@
 			}
 	     	    }
 		}
-		z = __ieee754_j0(x);
-		w = __ieee754_j1(x);
+		z = j0(x);
+		w = j1(x);
 		if (fabs(z) >= fabs(w))
 		    b = (t*z/b);
 		else
@@ -213,7 +213,7 @@
 }
 
 double
-__ieee754_yn(int n, double x)
+yn(int n, double x)
 {
 	int32_t i,hx,ix,lx;
 	int32_t sign;
@@ -232,8 +232,8 @@
 		n = -n;
 		sign = 1 - ((n&1)<<1);
 	}
-	if(n==0) return(__ieee754_y0(x));
-	if(n==1) return(sign*__ieee754_y1(x));
+	if(n==0) return(y0(x));
+	if(n==1) return(sign*y1(x));
 	if(ix==0x7ff00000) return zero;
 	if(ix>=0x52D00000) { /* x > 2**302 */
     /* (x >> n**2)
@@ -259,8 +259,8 @@
 		b = invsqrtpi*temp/sqrt(x);
 	} else {
 	    u_int32_t high;
-	    a = __ieee754_y0(x);
-	    b = __ieee754_y1(x);
+	    a = y0(x);
+	    b = y1(x);
 	/* quit if b is -inf */
 	    GET_HIGH_WORD(high,b);
 	    for(i=1;i<n&&high!=0xfff00000;i++){
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jnf.c b/libm/upstream-freebsd/lib/msun/src/e_jnf.c
index 965feeb..ba58622 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jnf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jnf.c
@@ -32,7 +32,7 @@
 static const float zero  =  0.0000000000e+00;
 
 float
-__ieee754_jnf(int n, float x)
+jnf(int n, float x)
 {
 	int32_t i,hx,ix, sgn;
 	float a, b, temp, di;
@@ -50,16 +50,16 @@
 		x = -x;
 		hx ^= 0x80000000;
 	}
-	if(n==0) return(__ieee754_j0f(x));
-	if(n==1) return(__ieee754_j1f(x));
+	if(n==0) return(j0f(x));
+	if(n==1) return(j1f(x));
 	sgn = (n&1)&(hx>>31);	/* even n -- 0, odd n -- sign(x) */
 	x = fabsf(x);
 	if(ix==0||ix>=0x7f800000) 	/* if x is 0 or inf */
 	    b = zero;
 	else if((float)n<=x) {
 		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
-	    a = __ieee754_j0f(x);
-	    b = __ieee754_j1f(x);
+	    a = j0f(x);
+	    b = j1f(x);
 	    for(i=1;i<n;i++){
 		temp = b;
 		b = b*((float)(i+i)/x) - a; /* avoid underflow */
@@ -134,7 +134,7 @@
 		 */
 		tmp = n;
 		v = two/x;
-		tmp = tmp*__ieee754_logf(fabsf(v*tmp));
+		tmp = tmp*logf(fabsf(v*tmp));
 		if(tmp<(float)8.8721679688e+01) {
 	    	    for(i=n-1,di=(float)(i+i);i>0;i--){
 		        temp = b;
@@ -158,8 +158,8 @@
 			}
 	     	    }
 		}
-		z = __ieee754_j0f(x);
-		w = __ieee754_j1f(x);
+		z = j0f(x);
+		w = j1f(x);
 		if (fabsf(z) >= fabsf(w))
 		    b = (t*z/b);
 		else
@@ -170,7 +170,7 @@
 }
 
 float
-__ieee754_ynf(int n, float x)
+ynf(int n, float x)
 {
 	int32_t i,hx,ix,ib;
 	int32_t sign;
@@ -186,12 +186,12 @@
 		n = -n;
 		sign = 1 - ((n&1)<<1);
 	}
-	if(n==0) return(__ieee754_y0f(x));
-	if(n==1) return(sign*__ieee754_y1f(x));
+	if(n==0) return(y0f(x));
+	if(n==1) return(sign*y1f(x));
 	if(ix==0x7f800000) return zero;
 
-	a = __ieee754_y0f(x);
-	b = __ieee754_y1f(x);
+	a = y0f(x);
+	b = y1f(x);
 	/* quit if b is -inf */
 	GET_FLOAT_WORD(ib,b);
 	for(i=1;i<n&&ib!=0xff800000;i++){
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgamma.c b/libm/upstream-freebsd/lib/msun/src/e_lgamma.c
index 43f5175..9c4a30e 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgamma.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgamma.c
@@ -15,10 +15,10 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_lgamma(x)
+/* lgamma(x)
  * Return the logarithm of the Gamma function of x.
  *
- * Method: call __ieee754_lgamma_r
+ * Method: call lgamma_r
  */
 
 #include <float.h>
@@ -29,9 +29,9 @@
 extern int signgam;
 
 double
-__ieee754_lgamma(double x)
+lgamma(double x)
 {
-	return __ieee754_lgamma_r(x,&signgam);
+	return lgamma_r(x,&signgam);
 }
 
 #if (LDBL_MANT_DIG == 53)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c b/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
index be70767..c020b63 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
@@ -13,7 +13,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_lgamma_r(x, signgamp)
+/* lgamma_r(x, signgamp)
  * Reentrant version of the logarithm of the Gamma function
  * with user provide pointer for the sign of Gamma(x).
  *
@@ -27,7 +27,7 @@
  *			    = log(6.3*5.3) + lgamma(5.3)
  *			    = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
  *   2. Polynomial approximation of lgamma around its
- *	minimun ymin=1.461632144968362245 to maintain monotonicity.
+ *	minimum ymin=1.461632144968362245 to maintain monotonicity.
  *	On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
  *		Let z = x-ymin;
  *		lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
@@ -199,7 +199,7 @@
 
 
 double
-__ieee754_lgamma_r(double x, int *signgamp)
+lgamma_r(double x, int *signgamp)
 {
 	double nadj,p,p1,p2,p3,q,r,t,w,y,z;
 	int32_t hx;
@@ -217,7 +217,7 @@
 	if(ix<0x3c700000) {	/* |x|<2**-56, return -log(|x|) */
 	    if((ix|lx)==0)
 	        return one/vzero;
-	    return -__ieee754_log(fabs(x));
+	    return -log(fabs(x));
 	}
 
     /* purge negative integers and start evaluation for other x < 0 */
@@ -227,7 +227,7 @@
 		return one/vzero;
 	    t = sin_pi(x);
 	    if(t==zero) return one/vzero; /* -integer */
-	    nadj = __ieee754_log(pi/fabs(t*x));
+	    nadj = log(pi/fabs(t*x));
 	    if(t<zero) *signgamp = -1;
 	    x = -x;
 	}
@@ -237,7 +237,7 @@
     /* for x < 2.0 */
 	else if(ix<0x40000000) {
 	    if(ix<=0x3feccccc) { 	/* lgamma(x) = lgamma(x+1)-log(x) */
-		r = -__ieee754_log(x);
+		r = -log(x);
 		if(ix>=0x3FE76944) {y = one-x; i= 0;}
 		else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
 	  	else {y = x; i=2;}
@@ -282,18 +282,18 @@
 	    case 5: z *= (y+4);		/* FALLTHRU */
 	    case 4: z *= (y+3);		/* FALLTHRU */
 	    case 3: z *= (y+2);		/* FALLTHRU */
-		    r += __ieee754_log(z); break;
+		    r += log(z); break;
 	    }
     /* 8.0 <= x < 2**56 */
 	} else if (ix < 0x43700000) {
-	    t = __ieee754_log(x);
+	    t = log(x);
 	    z = one/x;
 	    y = z*z;
 	    w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
 	    r = (x-half)*(t-one)+w;
 	} else
     /* 2**56 <= x <= inf */
-	    r =  x*(__ieee754_log(x)-one);
+	    r =  x*(log(x)-one);
 	if(hx<0) r = nadj - r;
 	return r;
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c b/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c
index 1e2c552..00a816c 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgammaf.c
@@ -16,10 +16,10 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_lgammaf(x)
+/* lgammaf(x)
  * Return the logarithm of the Gamma function of x.
  *
- * Method: call __ieee754_lgammaf_r
+ * Method: call lgammaf_r
  */
 
 #include "math.h"
@@ -28,7 +28,7 @@
 extern int signgam;
 
 float
-__ieee754_lgammaf(float x)
+lgammaf(float x)
 {
-	return __ieee754_lgammaf_r(x,&signgam);
+	return lgammaf_r(x,&signgam);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c b/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c
index 48346c3..fdd2321 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgammaf_r.c
@@ -120,7 +120,7 @@
 
 
 float
-__ieee754_lgammaf_r(float x, int *signgamp)
+lgammaf_r(float x, int *signgamp)
 {
 	float nadj,p,p1,p2,q,r,t,w,y,z;
 	int32_t hx;
@@ -138,7 +138,7 @@
 	if(ix<0x32000000) {		/* |x|<2**-27, return -log(|x|) */
 	    if(ix==0)
 	        return one/vzero;
-	    return -__ieee754_logf(fabsf(x));
+	    return -logf(fabsf(x));
 	}
 
     /* purge negative integers and start evaluation for other x < 0 */
@@ -148,7 +148,7 @@
 		return one/vzero;
 	    t = sin_pif(x);
 	    if(t==zero) return one/vzero; /* -integer */
-	    nadj = __ieee754_logf(pi/fabsf(t*x));
+	    nadj = logf(pi/fabsf(t*x));
 	    if(t<zero) *signgamp = -1;
 	    x = -x;
 	}
@@ -158,7 +158,7 @@
     /* for x < 2.0 */
 	else if(ix<0x40000000) {
 	    if(ix<=0x3f666666) { 	/* lgamma(x) = lgamma(x+1)-log(x) */
-		r = -__ieee754_logf(x);
+		r = -logf(x);
 		if(ix>=0x3f3b4a20) {y = one-x; i= 0;}
 		else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;}
 	  	else {y = x; i=2;}
@@ -198,18 +198,18 @@
 	    case 5: z *= (y+4);		/* FALLTHRU */
 	    case 4: z *= (y+3);		/* FALLTHRU */
 	    case 3: z *= (y+2);		/* FALLTHRU */
-		    r += __ieee754_logf(z); break;
+		    r += logf(z); break;
 	    }
     /* 8.0 <= x < 2**27 */
 	} else if (ix < 0x4d000000) {
-	    t = __ieee754_logf(x);
+	    t = logf(x);
 	    z = one/x;
 	    y = z*z;
 	    w = w0+z*(w1+y*w2);
 	    r = (x-half)*(t-one)+w;
 	} else
     /* 2**27 <= x <= inf */
-	    r =  x*(__ieee754_logf(x)-one);
+	    r =  x*(logf(x)-one);
 	if(hx<0) r = nadj - r;
 	return r;
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log.c b/libm/upstream-freebsd/lib/msun/src/e_log.c
index 68bc107..03ce820 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_log(x)
+/* log(x)
  * Return the logrithm of x
  *
  * Method :                  
@@ -86,7 +86,7 @@
 static volatile double vzero = 0.0;
 
 double
-__ieee754_log(double x)
+log(double x)
 {
 	double hfsq,f,s,z,R,w,t1,t2,dk;
 	int32_t k,hx,i,j;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log10.c b/libm/upstream-freebsd/lib/msun/src/e_log10.c
index 3c89ed2..595c238 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log10.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log10.c
@@ -39,7 +39,7 @@
 static volatile double vzero = 0.0;
 
 double
-__ieee754_log10(double x)
+log10(double x)
 {
 	double f,hfsq,hi,lo,r,val_hi,val_lo,w,y,y2;
 	int32_t i,k,hx;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log10f.c b/libm/upstream-freebsd/lib/msun/src/e_log10f.c
index 9856df2..d0c3a53 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log10f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log10f.c
@@ -31,7 +31,7 @@
 static volatile float vzero = 0.0;
 
 float
-__ieee754_log10f(float x)
+log10f(float x)
 {
 	float f,hfsq,hi,lo,r,y;
 	int32_t i,k,hx;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log2.c b/libm/upstream-freebsd/lib/msun/src/e_log2.c
index 4766cdb..10b1c00 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log2.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log2.c
@@ -39,7 +39,7 @@
 static volatile double vzero = 0.0;
 
 double
-__ieee754_log2(double x)
+log2(double x)
 {
 	double f,hfsq,hi,lo,r,val_hi,val_lo,w,y;
 	int32_t i,k,hx;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_log2f.c b/libm/upstream-freebsd/lib/msun/src/e_log2f.c
index 1794484..956f33a 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_log2f.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_log2f.c
@@ -29,7 +29,7 @@
 static volatile float vzero = 0.0;
 
 float
-__ieee754_log2f(float x)
+log2f(float x)
 {
 	float f,hfsq,hi,lo,r,y;
 	int32_t i,k,hx;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_logf.c b/libm/upstream-freebsd/lib/msun/src/e_logf.c
index ec3985f..68a4d5d 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_logf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_logf.c
@@ -33,7 +33,7 @@
 static volatile float vzero = 0.0;
 
 float
-__ieee754_logf(float x)
+logf(float x)
 {
 	float hfsq,f,s,z,R,w,t1,t2,dk;
 	int32_t k,ix,i,j;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_pow.c b/libm/upstream-freebsd/lib/msun/src/e_pow.c
index 52b2f5c..adc64c9 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_pow.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_pow.c
@@ -12,7 +12,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_pow(x,y) return x**y
+/* pow(x,y) return x**y
  *
  *		      n
  * Method:  Let x =  2   * (1+f)
@@ -98,7 +98,7 @@
 ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
 
 double
-__ieee754_pow(double x, double y)
+pow(double x, double y)
 {
 	double z,ax,z_h,z_l,p_h,p_l;
 	double y1,t1,t2,r,s,t,u,v,w;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_powf.c b/libm/upstream-freebsd/lib/msun/src/e_powf.c
index 122da45..f5a2c70 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_powf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_powf.c
@@ -56,7 +56,7 @@
 ivln2_l  =  7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
 
 float
-__ieee754_powf(float x, float y)
+powf(float x, float y)
 {
 	float z,ax,z_h,z_l,p_h,p_l;
 	float y1,t1,t2,r,s,sn,t,u,v,w;
@@ -108,7 +108,7 @@
 	if(hy==0x40000000) return x*x; /* y is  2 */
 	if(hy==0x3f000000) {	/* y is  0.5 */
 	    if(hx>=0)	/* x >= +0 */
-	    return __ieee754_sqrtf(x);
+	    return sqrtf(x);
 	}
 
 	ax   = fabsf(x);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainder.c b/libm/upstream-freebsd/lib/msun/src/e_remainder.c
index a4ae0b7..13156d8 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainder.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainder.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_remainder(x,p)
+/* remainder(x,p)
  * Return :                  
  * 	returns  x REM p  =  x - [x/p]*p as if in infinite 
  * 	precise arithmetic, where [x/p] is the (infinite bit) 
@@ -32,7 +32,7 @@
 
 
 double
-__ieee754_remainder(double x, double p)
+remainder(double x, double p)
 {
 	int32_t hx,hp;
 	u_int32_t sx,lx,lp;
@@ -52,7 +52,7 @@
 	    return nan_mix_op(x, p, *)/nan_mix_op(x, p, *);
 
 
-	if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p);	/* now x < 2p */
+	if (hp<=0x7fdfffff) x = fmod(x,p+p);	/* now x < 2p */
 	if (((hx-hp)|(lx-lp))==0) return zero*x;
 	x  = fabs(x);
 	p  = fabs(p);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainderf.c b/libm/upstream-freebsd/lib/msun/src/e_remainderf.c
index 8004493..e0dcfd1 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainderf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainderf.c
@@ -23,7 +23,7 @@
 
 
 float
-__ieee754_remainderf(float x, float p)
+remainderf(float x, float p)
 {
 	int32_t hx,hp;
 	u_int32_t sx;
@@ -42,7 +42,7 @@
 	    return nan_mix_op(x, p, *)/nan_mix_op(x, p, *);
 
 
-	if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p);	/* now x < 2p */
+	if (hp<=0x7effffff) x = fmodf(x,p+p);	/* now x < 2p */
 	if ((hx-hp)==0) return zero*x;
 	x  = fabsf(x);
 	p  = fabsf(p);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainderl.c b/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
index 4a67863..2295673 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_scalb.c b/libm/upstream-freebsd/lib/msun/src/e_scalb.c
index c0a7b5b..84a6893 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_scalb.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_scalb.c
@@ -15,7 +15,7 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * __ieee754_scalb(x, fn) is provide for
+ * scalb(x, fn) is provide for
  * passing various standard test suite. One 
  * should use scalbn() instead.
  */
@@ -25,10 +25,10 @@
 
 #ifdef _SCALB_INT
 double
-__ieee754_scalb(double x, int fn)
+scalb(double x, int fn)
 #else
 double
-__ieee754_scalb(double x, double fn)
+scalb(double x, double fn)
 #endif
 {
 #ifdef _SCALB_INT
diff --git a/libm/upstream-freebsd/lib/msun/src/e_scalbf.c b/libm/upstream-freebsd/lib/msun/src/e_scalbf.c
index d49e904..28483a5 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_scalbf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_scalbf.c
@@ -21,10 +21,10 @@
 
 #ifdef _SCALB_INT
 float
-__ieee754_scalbf(float x, int fn)
+scalbf(float x, int fn)
 #else
 float
-__ieee754_scalbf(float x, float fn)
+scalbf(float x, float fn)
 #endif
 {
 #ifdef _SCALB_INT
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sinh.c b/libm/upstream-freebsd/lib/msun/src/e_sinh.c
index 6c01f4a..9fe8999 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sinh.c
@@ -14,7 +14,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-/* __ieee754_sinh(x)
+/* sinh(x)
  * Method : 
  * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
  *	1. Replace x by |x| (sinh(-x) = -sinh(x)). 
@@ -40,7 +40,7 @@
 static const double one = 1.0, shuge = 1.0e307;
 
 double
-__ieee754_sinh(double x)
+sinh(double x)
 {
 	double t,h;
 	int32_t ix,jx;
@@ -64,7 +64,7 @@
 	}
 
     /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
-	if (ix < 0x40862E42)  return h*__ieee754_exp(fabs(x));
+	if (ix < 0x40862E42)  return h*exp(fabs(x));
 
     /* |x| in [log(maxdouble), overflowthresold] */
 	if (ix<=0x408633CE)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sinhf.c b/libm/upstream-freebsd/lib/msun/src/e_sinhf.c
index 1be2dc3..082beb1 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sinhf.c
@@ -22,7 +22,7 @@
 static const float one = 1.0, shuge = 1.0e37;
 
 float
-__ieee754_sinhf(float x)
+sinhf(float x)
 {
 	float t,h;
 	int32_t ix,jx;
@@ -45,7 +45,7 @@
 	}
 
     /* |x| in [9, logf(maxfloat)] return 0.5*exp(|x|) */
-	if (ix < 0x42b17217)  return h*__ieee754_expf(fabsf(x));
+	if (ix < 0x42b17217)  return h*expf(fabsf(x));
 
     /* |x| in [logf(maxfloat), overflowthresold] */
 	if (ix<=0x42b2d4fc)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c b/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
index 565d963..67c777f 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_exp.c b/libm/upstream-freebsd/lib/msun/src/k_exp.c
index dd15ff4..1b86cd6 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_exp.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_exp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_expf.c b/libm/upstream-freebsd/lib/msun/src/k_expf.c
index 80e629b..7071632 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_expf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_expf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_tanf.c b/libm/upstream-freebsd/lib/msun/src/k_tanf.c
index 52f1aaa..5be1445 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_tanf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_tanf.c
@@ -50,7 +50,7 @@
 	 * We add the small terms from lowest degree up for efficiency on
 	 * non-sequential machines (the lowest degree terms tend to be ready
 	 * earlier).  Apart from this, we don't care about order of
-	 * operations, and don't need to to care since we have precision to
+	 * operations, and don't need to care since we have precision to
 	 * spare.  However, the chosen splitting is good for accuracy too,
 	 * and would give results as accurate as Horner's method if the
 	 * small terms were added from highest degree down.
diff --git a/libm/upstream-freebsd/lib/msun/src/math_private.h b/libm/upstream-freebsd/lib/msun/src/math_private.h
index df526e7..a55d97a 100644
--- a/libm/upstream-freebsd/lib/msun/src/math_private.h
+++ b/libm/upstream-freebsd/lib/msun/src/math_private.h
@@ -624,7 +624,7 @@
  * The complications for extra precision are smaller for rnintl() since it
  * can safely assume that the rounding precision has been increased from
  * its default to FP_PE on x86.  We don't exploit that here to get small
- * optimizations from limiting the rangle to double.  We just need it for
+ * optimizations from limiting the range to double.  We just need it for
  * the magic number to work with long doubles.  ld128 callers should use
  * rnint() instead of this if possible.  ld80 callers should prefer
  * rnintl() since for amd64 this avoids swapping the register set, while
@@ -688,6 +688,59 @@
 }
 #endif
 
+/*
+ * The following are fast floor macros for 0 <= |x| < 0x1p(N-1), where
+ * N is the precision of the type of x. These macros are used in the
+ * half-cycle trignometric functions (e.g., sinpi(x)).
+ */
+#define	FFLOORF(x, j0, ix) do {			\
+	(j0) = (((ix) >> 23) & 0xff) - 0x7f;	\
+	(ix) &= ~(0x007fffff >> (j0));		\
+	SET_FLOAT_WORD((x), (ix));		\
+} while (0)
+
+#define	FFLOOR(x, j0, ix, lx) do {				\
+	(j0) = (((ix) >> 20) & 0x7ff) - 0x3ff;			\
+	if ((j0) < 20) {					\
+		(ix) &= ~(0x000fffff >> (j0));			\
+		(lx) = 0;					\
+	} else {						\
+		(lx) &= ~((uint32_t)0xffffffff >> ((j0) - 20));	\
+	}							\
+	INSERT_WORDS((x), (ix), (lx));				\
+} while (0)
+
+#define	FFLOORL80(x, j0, ix, lx) do {			\
+	j0 = ix - 0x3fff + 1;				\
+	if ((j0) < 32) {				\
+		(lx) = ((lx) >> 32) << 32;		\
+		(lx) &= ~((((lx) << 32)-1) >> (j0));	\
+	} else {					\
+		uint64_t _m;				\
+		_m = (uint64_t)-1 >> (j0);		\
+		if ((lx) & _m) (lx) &= ~_m;		\
+	}						\
+	INSERT_LDBL80_WORDS((x), (ix), (lx));		\
+} while (0)
+
+#define FFLOORL128(x, ai, ar) do {			\
+	union IEEEl2bits u;				\
+	uint64_t m;					\
+	int e;						\
+	u.e = (x);					\
+	e = u.bits.exp - 16383;				\
+	if (e < 48) {					\
+		m = ((1llu << 49) - 1) >> (e + 1);	\
+		u.bits.manh &= ~m;			\
+		u.bits.manl = 0;			\
+	} else {					\
+		m = (uint64_t)-1 >> (e - 48);		\
+		u.bits.manl &= ~m;			\
+	}						\
+	(ai) = u.e;					\
+	(ar) = (x) - (ai);				\
+} while (0)
+
 #ifdef DEBUG
 #if defined(__amd64__) || defined(__i386__)
 #define	breakpoint()	asm("int $3")
@@ -698,191 +751,25 @@
 #endif
 #endif
 
-/* Write a pari script to test things externally. */
-#ifdef DOPRINT
-#include <stdio.h>
-
-#ifndef DOPRINT_SWIZZLE
-#define	DOPRINT_SWIZZLE		0
-#endif
-
-#ifdef DOPRINT_LD80
-
-#define	DOPRINT_START(xp) do {						\
-	uint64_t __lx;							\
-	uint16_t __hx;							\
-									\
-	/* Hack to give more-problematic args. */			\
-	EXTRACT_LDBL80_WORDS(__hx, __lx, *xp);				\
-	__lx ^= DOPRINT_SWIZZLE;					\
-	INSERT_LDBL80_WORDS(*xp, __hx, __lx);				\
-	printf("x = %.21Lg; ", (long double)*xp);			\
-} while (0)
-#define	DOPRINT_END1(v)							\
-	printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
-#define	DOPRINT_END2(hi, lo)						\
-	printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n",		\
-	    (long double)(hi), (long double)(lo))
-
-#elif defined(DOPRINT_D64)
-
-#define	DOPRINT_START(xp) do {						\
-	uint32_t __hx, __lx;						\
-									\
-	EXTRACT_WORDS(__hx, __lx, *xp);					\
-	__lx ^= DOPRINT_SWIZZLE;					\
-	INSERT_WORDS(*xp, __hx, __lx);					\
-	printf("x = %.21Lg; ", (long double)*xp);			\
-} while (0)
-#define	DOPRINT_END1(v)							\
-	printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
-#define	DOPRINT_END2(hi, lo)						\
-	printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n",		\
-	    (long double)(hi), (long double)(lo))
-
-#elif defined(DOPRINT_F32)
-
-#define	DOPRINT_START(xp) do {						\
-	uint32_t __hx;							\
-									\
-	GET_FLOAT_WORD(__hx, *xp);					\
-	__hx ^= DOPRINT_SWIZZLE;					\
-	SET_FLOAT_WORD(*xp, __hx);					\
-	printf("x = %.21Lg; ", (long double)*xp);			\
-} while (0)
-#define	DOPRINT_END1(v)							\
-	printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v))
-#define	DOPRINT_END2(hi, lo)						\
-	printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n",		\
-	    (long double)(hi), (long double)(lo))
-
-#else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */
-
-#ifndef DOPRINT_SWIZZLE_HIGH
-#define	DOPRINT_SWIZZLE_HIGH	0
-#endif
-
-#define	DOPRINT_START(xp) do {						\
-	uint64_t __lx, __llx;						\
-	uint16_t __hx;							\
-									\
-	EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp);			\
-	__llx ^= DOPRINT_SWIZZLE;					\
-	__lx ^= DOPRINT_SWIZZLE_HIGH;					\
-	INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx);			\
-	printf("x = %.36Lg; ", (long double)*xp);					\
-} while (0)
-#define	DOPRINT_END1(v)							\
-	printf("y = %.36Lg; z = 0; show(x, y, z);\n", (long double)(v))
-#define	DOPRINT_END2(hi, lo)						\
-	printf("y = %.36Lg; z = %.36Lg; show(x, y, z);\n",		\
-	    (long double)(hi), (long double)(lo))
-
-#endif /* DOPRINT_LD80 */
-
-#else /* !DOPRINT */
-#define	DOPRINT_START(xp)
-#define	DOPRINT_END1(v)
-#define	DOPRINT_END2(hi, lo)
-#endif /* DOPRINT */
-
-#define	RETURNP(x) do {			\
-	DOPRINT_END1(x);		\
-	RETURNF(x);			\
-} while (0)
-#define	RETURNPI(x) do {		\
-	DOPRINT_END1(x);		\
-	RETURNI(x);			\
-} while (0)
-#define	RETURN2P(x, y) do {		\
-	DOPRINT_END2((x), (y));		\
-	RETURNF((x) + (y));		\
-} while (0)
-#define	RETURN2PI(x, y) do {		\
-	DOPRINT_END2((x), (y));		\
-	RETURNI((x) + (y));		\
-} while (0)
 #ifdef STRUCT_RETURN
 #define	RETURNSP(rp) do {		\
 	if (!(rp)->lo_set)		\
-		RETURNP((rp)->hi);	\
-	RETURN2P((rp)->hi, (rp)->lo);	\
+		RETURNF((rp)->hi);	\
+	RETURNF((rp)->hi + (rp)->lo);	\
 } while (0)
 #define	RETURNSPI(rp) do {		\
 	if (!(rp)->lo_set)		\
-		RETURNPI((rp)->hi);	\
-	RETURN2PI((rp)->hi, (rp)->lo);	\
+		RETURNI((rp)->hi);	\
+	RETURNI((rp)->hi + (rp)->lo);	\
 } while (0)
 #endif
+
 #define	SUM2P(x, y) ({			\
 	const __typeof (x) __x = (x);	\
 	const __typeof (y) __y = (y);	\
-					\
-	DOPRINT_END2(__x, __y);		\
 	__x + __y;			\
 })
 
-/*
- * ieee style elementary functions
- *
- * We rename functions here to improve other sources' diffability
- * against fdlibm.
- */
-#define	__ieee754_sqrt	sqrt
-#define	__ieee754_acos	acos
-#define	__ieee754_acosh	acosh
-#define	__ieee754_log	log
-#define	__ieee754_log2	log2
-#define	__ieee754_atanh	atanh
-#define	__ieee754_asin	asin
-#define	__ieee754_atan2	atan2
-#define	__ieee754_exp	exp
-#define	__ieee754_cosh	cosh
-#define	__ieee754_fmod	fmod
-#define	__ieee754_pow	pow
-#define	__ieee754_lgamma lgamma
-#define	__ieee754_gamma	gamma
-#define	__ieee754_lgamma_r lgamma_r
-#define	__ieee754_gamma_r gamma_r
-#define	__ieee754_log10	log10
-#define	__ieee754_sinh	sinh
-#define	__ieee754_hypot	hypot
-#define	__ieee754_j0	j0
-#define	__ieee754_j1	j1
-#define	__ieee754_y0	y0
-#define	__ieee754_y1	y1
-#define	__ieee754_jn	jn
-#define	__ieee754_yn	yn
-#define	__ieee754_remainder remainder
-#define	__ieee754_scalb	scalb
-#define	__ieee754_sqrtf	sqrtf
-#define	__ieee754_acosf	acosf
-#define	__ieee754_acoshf acoshf
-#define	__ieee754_logf	logf
-#define	__ieee754_atanhf atanhf
-#define	__ieee754_asinf	asinf
-#define	__ieee754_atan2f atan2f
-#define	__ieee754_expf	expf
-#define	__ieee754_coshf	coshf
-#define	__ieee754_fmodf	fmodf
-#define	__ieee754_powf	powf
-#define	__ieee754_lgammaf lgammaf
-#define	__ieee754_gammaf gammaf
-#define	__ieee754_lgammaf_r lgammaf_r
-#define	__ieee754_gammaf_r gammaf_r
-#define	__ieee754_log10f log10f
-#define	__ieee754_log2f log2f
-#define	__ieee754_sinhf	sinhf
-#define	__ieee754_hypotf hypotf
-#define	__ieee754_j0f	j0f
-#define	__ieee754_j1f	j1f
-#define	__ieee754_y0f	y0f
-#define	__ieee754_y1f	y1f
-#define	__ieee754_jnf	jnf
-#define	__ieee754_ynf	ynf
-#define	__ieee754_remainderf remainderf
-#define	__ieee754_scalbf scalbf
-
 /* fdlibm kernel function */
 int	__kernel_rem_pio2(double*,double*,int,int,int);
 
diff --git a/libm/upstream-freebsd/lib/msun/src/s_asinh.c b/libm/upstream-freebsd/lib/msun/src/s_asinh.c
index cbb3d46..a1b9169 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_asinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_asinh.c
@@ -46,13 +46,13 @@
 	    if(huge+x>one) return x;	/* return x inexact except 0 */
 	}
 	if(ix>0x41b00000) {	/* |x| > 2**28 */
-	    w = __ieee754_log(fabs(x))+ln2;
+	    w = log(fabs(x))+ln2;
 	} else if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
 	    t = fabs(x);
-	    w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t));
+	    w = log(2.0*t+one/(sqrt(x*x+one)+t));
 	} else {		/* 2.0 > |x| > 2**-28 */
 	    t = x*x;
-	    w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
+	    w =log1p(fabs(x)+t/(one+sqrt(one+t)));
 	}
 	if(hx>0) return w; else return -w;
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_asinhf.c b/libm/upstream-freebsd/lib/msun/src/s_asinhf.c
index c1620dd..72bcefe 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_asinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_asinhf.c
@@ -36,13 +36,13 @@
 	    if(huge+x>one) return x;	/* return x inexact except 0 */
 	}
 	if(ix>0x4d800000) {	/* |x| > 2**28 */
-	    w = __ieee754_logf(fabsf(x))+ln2;
+	    w = logf(fabsf(x))+ln2;
 	} else if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
 	    t = fabsf(x);
-	    w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t));
+	    w = logf((float)2.0*t+one/(sqrtf(x*x+one)+t));
 	} else {		/* 2.0 > |x| > 2**-28 */
 	    t = x*x;
-	    w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t)));
+	    w =log1pf(fabsf(x)+t/(one+sqrtf(one+t)));
 	}
 	if(hx>0) return w; else return -w;
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_carg.c b/libm/upstream-freebsd/lib/msun/src/s_carg.c
index 1611b9d..f203198 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_carg.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_carg.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cargf.c b/libm/upstream-freebsd/lib/msun/src/s_cargf.c
index 71c705d..6ea487c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cargf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cargf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cargl.c b/libm/upstream-freebsd/lib/msun/src/s_cargl.c
index 96c3336..ba39438 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cargl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cargl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrt.c b/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
index 0e609e1..4353d34 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
@@ -108,7 +108,7 @@
 	r=x/s;				/* error <= 0.5 ulps; |r| < |t| */
 	w=t+t;				/* t+t is exact */
 	r=(r-t)/(w+r);			/* r-t is exact; w+r ~= 3*t */
-	t=t+t*r;			/* error <= 0.5 + 0.5/3 + epsilon */
+	t=t+t*r;			/* error <= (0.5 + 0.5/3) * ulp */
 
 	return(t);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c b/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
index 2236c0f..b15c96e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
@@ -136,7 +136,7 @@
 	r=x/s;				/* error <= 0.5 ulps; |r| < |t| */
 	w=t+t;				/* t+t is exact */
 	r=(r-t)/(w+r);			/* r-t is exact; w+r ~= 3*t */
-	t=t+t*r;			/* error <= 0.5 + 0.5/3 + epsilon */
+	t=t+t*r;			/* error <= (0.5 + 0.5/3) * ulp */
 
 	t *= v.e;
 	RETURNI(t);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
index 7652b3c..0fd9206 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
index 5d7a09b..2db8403 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexp.c b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
index a1f853e..8db763d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexp.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
index d905b74..7247301 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimag.c b/libm/upstream-freebsd/lib/msun/src/s_cimag.c
index 1f383cb..0b14fd7 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimag.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimag.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimagf.c b/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
index 86a43c1..42a1efd 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimagl.c b/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
index 6d87950..9707bc3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conj.c b/libm/upstream-freebsd/lib/msun/src/s_conj.c
index dc56f48..a83abd8 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conj.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjf.c b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
index 3fd8b8f..f9eb146 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjl.c b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
index d2f8d0f..4b86f2e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_copysignl.c b/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
index bd67447..666a2ba 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cosl.c b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
index 3d06648..6f0b36f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cospi.c b/libm/upstream-freebsd/lib/msun/src/s_cospi.c
index 860219e..f97570d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cospi.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cospi.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2017 Steven G. Kargl
+ * Copyright (c) 2017, 2023 Steven G. Kargl
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -104,20 +104,10 @@
 	}
 
 	if (ix < 0x43300000) {		/* 1 <= |x| < 0x1p52 */
-		/* Determine integer part of ax. */
-		j0 = ((ix >> 20) & 0x7ff) - 0x3ff;
-		if (j0 < 20) {
-			ix &= ~(0x000fffff >> j0);
-			lx = 0;
-		} else {
-			lx &= ~((uint32_t)0xffffffff >> (j0 - 20));
-		}
-		INSERT_WORDS(x, ix, lx);
-
+		FFLOOR(x, j0, ix, lx);	/* Integer part of ax. */
 		ax -= x;
 		EXTRACT_WORDS(ix, lx, ax);
 
-
 		if (ix < 0x3fe00000) {		/* |x| < 0.5 */
 			if (ix < 0x3fd00000)	/* |x| < 0.25 */
 				c = ix == 0 ? 1 : __kernel_cospi(ax);
@@ -138,13 +128,16 @@
 		return (j0 & 1 ? -c : c);
 	}
 
-	if (ix >= 0x7f800000)
+	/* x = +-inf or nan. */
+	if (ix >= 0x7ff00000)
 		return (vzero / vzero);
 
 	/*
-	 * |x| >= 0x1p52 is always an even integer, so return 1.
+	 * For 0x1p52 <= |x| < 0x1p53 need to determine if x is an even
+	 * or odd integer to return +1 or -1.
+	 * For |x| >= 0x1p53, it is always an even integer, so return 1.
 	 */
-	return (1);
+	return (ix < 0x43400000 ? ((lx & 1) ? -1 : 1) : 1);
 }
 
 #if LDBL_MANT_DIG == 53
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cproj.c b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
index 38e7747..5b0d4ed 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cproj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
index af4c3a8..0d76e75 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
index 16df514..7fc35d2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_creal.c b/libm/upstream-freebsd/lib/msun/src/s_creal.c
index 69a10f2..5c8734e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_creal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_creal.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_crealf.c b/libm/upstream-freebsd/lib/msun/src/s_crealf.c
index 83e4d46..a93421f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_crealf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_crealf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_creall.c b/libm/upstream-freebsd/lib/msun/src/s_creall.c
index 538b7d5..b4eb9ef 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_creall.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_creall.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinh.c b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
index 09b2dcb..b3928ce 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
index ba1a794..a8d6f2d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
index d172efc..d96c344 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
index 6836a39..e3ef4d0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
index 40bc59d..d564133 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007-2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
index e5840a1..aa4e10c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
index c46f86d..e9ebe4f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_erf.c b/libm/upstream-freebsd/lib/msun/src/s_erf.c
index 5f22847..ab2dc19 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_erf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_erf.c
@@ -238,7 +238,7 @@
 	}
 	z  = x;
 	SET_LOW_WORD(z,0);
-	r  =  __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
+	r  =  exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S);
 	if(hx>=0) return one-r/x; else return  r/x-one;
 }
 
@@ -297,7 +297,7 @@
 	    }
 	    z  = x;
 	    SET_LOW_WORD(z,0);
-	    r  =  __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
+	    r  =  exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S);
 	    if(hx>0) return r/x; else return two-r/x;
 	} else {
 	    if(hx>0) return tiny*tiny; else return two-tiny;
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2.c b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
index bc36e55..1dd9673 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2f.c b/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
index c082924..c5b4c8e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fdim.c b/libm/upstream-freebsd/lib/msun/src/s_fdim.c
index c40c3e9..b81dbac 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fdim.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fdim.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fma.c b/libm/upstream-freebsd/lib/msun/src/s_fma.c
index 95cffd0..2fd7075 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fma.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fma.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
index 4591cc2..ae979cb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmal.c b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
index a379346..a0622a2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmax.c b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
index b53b1e6..42bd11c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmax.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
index 8d3d14f..10667d3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
index c0d7c88..bf42587 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmin.c b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
index 53f36c1..e79071d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmin.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminf.c b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
index 58b6a48..19ffd42 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminl.c b/libm/upstream-freebsd/lib/msun/src/s_fminl.c
index 97604b3..c906f1d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_frexpl.c b/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
index 66e284f..7101615 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lrint.c b/libm/upstream-freebsd/lib/msun/src/s_lrint.c
index ad9b978..be00cbb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lrint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lrint.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lround.c b/libm/upstream-freebsd/lib/msun/src/s_lround.c
index 1dd8e69..00f4b95 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lround.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lround.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_modfl.c b/libm/upstream-freebsd/lib/msun/src/s_modfl.c
index 2d83bbe..8e5c4d3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_modfl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_modfl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nan.c b/libm/upstream-freebsd/lib/msun/src/s_nan.c
index 1769244..1345f22 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nan.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nan.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c b/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
index 796dbaf..ae6ffde 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_rintl.c b/libm/upstream-freebsd/lib/msun/src/s_rintl.c
index 1e9824d..790edbc 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_rintl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_rintl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_round.c b/libm/upstream-freebsd/lib/msun/src/s_round.c
index ca25f8e..a112bc5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_round.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_round.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003, Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_roundf.c b/libm/upstream-freebsd/lib/msun/src/s_roundf.c
index 5bbf6b3..bb6f77c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_roundf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_roundf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003, Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_roundl.c b/libm/upstream-freebsd/lib/msun/src/s_roundl.c
index 8d1c02a..9e85423 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_roundl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_roundl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003, Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
index c27420c..e8c6377 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_significand.c b/libm/upstream-freebsd/lib/msun/src/s_significand.c
index 356e300..eed80ec 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_significand.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_significand.c
@@ -25,5 +25,5 @@
 double
 significand(double x)
 {
-	return __ieee754_scalb(x,(double) -ilogb(x));
+	return scalb(x,(double) -ilogb(x));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_significandf.c b/libm/upstream-freebsd/lib/msun/src/s_significandf.c
index ad030e2..b33ab7b 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_significandf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_significandf.c
@@ -22,5 +22,5 @@
 float
 significandf(float x)
 {
-	return __ieee754_scalbf(x,(float) -ilogbf(x));
+	return scalbf(x,(float) -ilogbf(x));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinl.c b/libm/upstream-freebsd/lib/msun/src/s_sinl.c
index f1ef84c..c5ee106 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sinl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sinl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinpi.c b/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
index 858459a..8b388de 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2017 Steven G. Kargl
+ * Copyright (c) 2017, 2023 Steven G. Kargl
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -118,16 +118,7 @@
 	}
 
 	if (ix < 0x43300000) {			/* 1 <= |x| < 0x1p52 */
-		/* Determine integer part of ax. */
-		j0 = ((ix >> 20) & 0x7ff) - 0x3ff;
-		if (j0 < 20) {
-			ix &= ~(0x000fffff >> j0);
-			lx = 0;
-		} else {
-			lx &= ~((uint32_t)0xffffffff >> (j0 - 20));
-		}
-		INSERT_WORDS(x, ix, lx);
-
+		FFLOOR(x, j0, ix, lx);	/* Integer part of ax. */
 		ax -= x;
 		EXTRACT_WORDS(ix, lx, ax);
 
@@ -155,7 +146,8 @@
 		return ((hx & 0x80000000) ? -s : s);
 	}
 
-	if (ix >= 0x7f800000)
+	/* x = +-inf or nan. */
+	if (ix >= 0x7ff00000)
 		return (vzero / vzero);
 
 	/*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanl.c b/libm/upstream-freebsd/lib/msun/src/s_tanl.c
index 0c5228e..c21e38d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c b/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
index 1fd46e8..6cbd356 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/linker/Android.bp b/linker/Android.bp
index 020bd7d..0ccd16d 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -169,6 +169,7 @@
     srcs: [
         "dlfcn.cpp",
         "linker.cpp",
+        "linker_auxv.cpp",
         "linker_block_allocator.cpp",
         "linker_dlwarning.cpp",
         "linker_cfi.cpp",
diff --git a/linker/NOTICE b/linker/NOTICE
index d61a193..7fd1877 100644
--- a/linker/NOTICE
+++ b/linker/NOTICE
@@ -362,3 +362,31 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2023 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a3f5246..fee19f4 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -97,7 +97,7 @@
                                     void* context) __LINKER_PUBLIC__;
 }
 
-static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
 static char* __bionic_set_dlerror(char* new_value) {
   char* old_value = __get_thread()->current_dlerror;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 5c26944..1553ba9 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -27,6 +27,7 @@
  */
 
 #include <android/api-level.h>
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
diff --git a/linker/linker_auxv.cpp b/linker/linker_auxv.cpp
new file mode 100644
index 0000000..d8e4a3e
--- /dev/null
+++ b/linker/linker_auxv.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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 "linker_auxv.h"
+
+#include <elf.h>
+#include <stdio.h>
+#include <sys/auxv.h>
+#include <unistd.h>
+
+#include <async_safe/log.h>
+
+static const char* auxv_name(int at) {
+  switch (at) {
+  case AT_NULL: return "AT_NULL";
+  case AT_IGNORE: return "AT_IGNORE";
+  case AT_EXECFD: return "AT_EXECFD";
+  case AT_PHDR: return "AT_PHDR";
+  case AT_PHENT: return "AT_PHENT";
+  case AT_PHNUM: return "AT_PHNUM";
+  case AT_PAGESZ: return "AT_PAGESZ";
+  case AT_BASE: return "AT_BASE";
+  case AT_FLAGS: return "AT_FLAGS";
+  case AT_ENTRY: return "AT_ENTRY";
+  case AT_NOTELF: return "AT_NOTELF";
+  case AT_UID: return "AT_UID";
+  case AT_EUID: return "AT_EUID";
+  case AT_GID: return "AT_GID";
+  case AT_EGID: return "AT_EGID";
+  case AT_PLATFORM: return "AT_PLATFORM";
+  case AT_HWCAP: return "AT_HWCAP";
+  case AT_CLKTCK: return "AT_CLKTCK";
+  case AT_SECURE: return "AT_SECURE";
+  case AT_BASE_PLATFORM: return "AT_BASE_PLATFORM";
+  case AT_RANDOM: return "AT_RANDOM";
+  case AT_HWCAP2: return "AT_HWCAP2";
+  case AT_RSEQ_FEATURE_SIZE: return "AT_RSEQ_FEATURE_SIZE";
+  case AT_RSEQ_ALIGN: return "AT_RSEQ_ALIGN";
+  case AT_EXECFN: return "AT_EXECFN";
+  case AT_SYSINFO_EHDR: return "AT_SYSINFO_EHDR";
+#if defined(AT_MINSIGSTKSZ)
+  case AT_MINSIGSTKSZ: return "AT_MINSIGSTKSZ";
+#endif
+#if defined(AT_SYSINFO)
+  case AT_SYSINFO: return "AT_SYSINFO";
+#endif
+#if defined(AT_L1I_CACHESIZE)
+  case AT_L1I_CACHESIZE: return "AT_L1I_CACHESIZE";
+#endif
+#if defined(AT_L1I_CACHEGEOMETRY)
+  case AT_L1I_CACHEGEOMETRY: return "AT_L1I_CACHEGEOMETRY";
+#endif
+#if defined(AT_L1D_CACHESIZE)
+  case AT_L1D_CACHESIZE: return "AT_L1D_CACHESIZE";
+#endif
+#if defined(AT_L1D_CACHEGEOMETRY)
+  case AT_L1D_CACHEGEOMETRY: return "AT_L1D_CACHEGEOMETRY";
+#endif
+#if defined(AT_L2_CACHESIZE)
+  case AT_L2_CACHESIZE: return "AT_L2_CACHESIZE";
+#endif
+#if defined(AT_L2_CACHEGEOMETRY)
+  case AT_L2_CACHEGEOMETRY: return "AT_L2_CACHEGEOMETRY";
+#endif
+  }
+  static char name[32];
+  snprintf(name, sizeof(name), "AT_??? (%d)", at);
+  return name;
+}
+
+void ld_show_auxv(ElfW(auxv_t)* auxv) {
+  for (ElfW(auxv_t)* v = auxv; v->a_type != AT_NULL; ++v) {
+    const char* name = auxv_name(v->a_type);
+    long value = v->a_un.a_val;
+    switch (v->a_type) {
+    case AT_SYSINFO_EHDR:
+    case AT_PHDR:
+    case AT_BASE:
+    case AT_ENTRY:
+    case AT_RANDOM:
+      async_safe_format_fd(STDOUT_FILENO, "%-20s %#lx\n", name, value);
+      break;
+    case AT_FLAGS:
+    case AT_HWCAP:
+    case AT_HWCAP2:
+      async_safe_format_fd(STDOUT_FILENO, "%-20s %#lb\n", name, value);
+      break;
+    case AT_EXECFN:
+    case AT_PLATFORM:
+      async_safe_format_fd(STDOUT_FILENO, "%-20s \"%s\"\n", name, reinterpret_cast<char*>(value));
+      break;
+    default:
+      async_safe_format_fd(STDOUT_FILENO, "%-20s %ld\n", name, value);
+      break;
+    }
+  }
+}
diff --git a/linker/linker_auxv.h b/linker/linker_auxv.h
new file mode 100644
index 0000000..c093283
--- /dev/null
+++ b/linker/linker_auxv.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <elf.h>
+#include <link.h>
+
+void ld_show_auxv(ElfW(auxv_t)* auxv);
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index 60e5e1c..e70e6ae 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -37,8 +37,9 @@
 
 #include "linker_debug.h"
 
-static constexpr size_t kAllocateSize = PAGE_SIZE * 100;
-static_assert(kAllocateSize % PAGE_SIZE == 0, "Invalid kAllocateSize.");
+static constexpr size_t kMaxPageSize = 65536;
+static constexpr size_t kAllocateSize = kMaxPageSize * 6;
+static_assert(kAllocateSize % kMaxPageSize == 0, "Invalid kAllocateSize.");
 
 struct LinkerBlockAllocatorPage {
   LinkerBlockAllocatorPage* next;
diff --git a/linker/linker_globals.h b/linker/linker_globals.h
index 0998629..0cb7ca9 100644
--- a/linker/linker_globals.h
+++ b/linker/linker_globals.h
@@ -104,3 +104,4 @@
 };
 
 __LIBC_HIDDEN__ extern bool g_is_ldd;
+__LIBC_HIDDEN__ extern pthread_mutex_t g_dl_mutex;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index f7c8ea9..5a33a63 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -32,6 +32,7 @@
 #include <sys/auxv.h>
 
 #include "linker.h"
+#include "linker_auxv.h"
 #include "linker_cfi.h"
 #include "linker_debug.h"
 #include "linker_debuggerd.h"
@@ -43,10 +44,10 @@
 #include "linker_tls.h"
 #include "linker_utils.h"
 
+#include "private/KernelArgumentBlock.h"
 #include "private/bionic_call_ifunc_resolver.h"
 #include "private/bionic_globals.h"
 #include "private/bionic_tls.h"
-#include "private/KernelArgumentBlock.h"
 
 #include "android-base/unique_fd.h"
 #include "android-base/strings.h"
@@ -324,12 +325,14 @@
 
   g_linker_logger.ResetState();
 
-  // Get a few environment variables.
+  // Enable debugging logs?
   const char* LD_DEBUG = getenv("LD_DEBUG");
   if (LD_DEBUG != nullptr) {
     g_ld_debug_verbosity = atoi(LD_DEBUG);
   }
 
+  if (getenv("LD_SHOW_AUXV") != nullptr) ld_show_auxv(args.auxv);
+
 #if defined(__LP64__)
   INFO("[ Android dynamic linker (64-bit) ]");
 #else
@@ -690,6 +693,13 @@
  * function, or other GOT reference will generate a segfault.
  */
 extern "C" ElfW(Addr) __linker_init(void* raw_args) {
+  // Unlock the loader mutex immediately before transferring to the executable's
+  // entry point. This must happen after destructors are called in this function
+  // (e.g. ~soinfo), so declare this variable very early.
+  struct DlMutexUnlocker {
+    ~DlMutexUnlocker() { pthread_mutex_unlock(&g_dl_mutex); }
+  } unlocker;
+
   // Initialize TLS early so system calls and errno work.
   KernelArgumentBlock args(raw_args);
   bionic_tcb temp_tcb __attribute__((uninitialized));
@@ -752,6 +762,11 @@
   // Initialize the linker's static libc's globals
   __libc_init_globals();
 
+  // A constructor could spawn a thread that calls into the loader, so as soon
+  // as we've called a constructor, we need to hold the lock until transferring
+  // to the entry point.
+  pthread_mutex_lock(&g_dl_mutex);
+
   // Initialize the linker's own global variables
   tmp_linker_so.call_constructors();
 
diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp
index 456d254..7ce53b8 100644
--- a/linker/linker_memory.cpp
+++ b/linker/linker_memory.cpp
@@ -76,6 +76,10 @@
   return get_allocator().memalign(alignment, byte_count);
 }
 
+void* aligned_alloc(size_t alignment, size_t byte_count) {
+  return get_allocator().memalign(alignment, byte_count);
+}
+
 void* calloc(size_t item_count, size_t item_size) {
   return get_allocator().alloc(item_count*item_size);
 }
diff --git a/tests/Android.bp b/tests/Android.bp
index bdb46c0..14b4e3e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -59,6 +59,9 @@
         // Needed to test pthread_internal_t layout.
         "-Wno-invalid-offsetof",
 
+        // This warning does not provide any benefit to the tests.
+        "-Wno-reorder-init-list",
+
         // For glibc.
         "-D__STDC_LIMIT_MACROS",
     ],
@@ -470,7 +473,9 @@
         "struct_layout_test.cpp",
         "sstream_test.cpp",
         "sys_auxv_test.cpp",
+        "sys_cachectl_test.cpp",
         "sys_epoll_test.cpp",
+        "sys_hwprobe_test.cpp",
         "sys_mman_test.cpp",
         "sys_msg_test.cpp",
         "sys_param_test.cpp",
@@ -849,79 +854,8 @@
     ],
 }
 
-// -----------------------------------------------------------------------------
-// Tests for the device using bionic's .so. Run with:
-//   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
-//   adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests
-// -----------------------------------------------------------------------------
 cc_defaults {
-    name: "bionic_unit_tests_defaults",
-    host_supported: false,
-    gtest: false,
-
-    defaults: [
-        "bionic_tests_defaults",
-    ],
-
-    whole_static_libs: [
-        "libBionicTests",
-        "libBionicLoaderTests",
-        "libBionicElfTlsLoaderTests",
-    ],
-
-    static_libs: [
-        "libtinyxml2",
-        "liblog",
-        "libbase",
-        "libgtest_isolated",
-    ],
-
-    srcs: [
-        // TODO: Include __cxa_thread_atexit_test.cpp to glibc tests once it is upgraded (glibc 2.18+)
-        "__cxa_thread_atexit_test.cpp",
-        "gtest_globals.cpp",
-        "gtest_main.cpp",
-        "gwp_asan_test.cpp",
-        "thread_local_test.cpp",
-    ],
-
-    conlyflags: [
-        "-fexceptions",
-        "-fnon-call-exceptions",
-    ],
-
-    ldflags: ["-Wl,--export-dynamic"],
-
-    include_dirs: ["bionic/libc"],
-
-    stl: "libc++_static",
-
-    target: {
-        android: {
-            shared_libs: [
-                "ld-android",
-                "libdl",
-                "libdl_android",
-                "libdl_preempt_test_1",
-                "libdl_preempt_test_2",
-                "libdl_test_df_1_global",
-                "libtest_elftls_shared_var",
-                "libtest_elftls_tprel",
-            ],
-            static_libs: [
-                // The order of these libraries matters, do not shuffle them.
-                "libmeminfo",
-                "libziparchive",
-                "libz",
-                "libutils",
-            ],
-            ldflags: [
-                "-Wl,--rpath,${ORIGIN}/bionic-loader-test-libs",
-                "-Wl,--enable-new-dtags",
-            ],
-        },
-    },
-
+    name: "bionic_unit_tests_data",
     data_bins: [
         "cfi_test_helper",
         "cfi_test_helper2",
@@ -949,7 +883,6 @@
         "thread_exit_cb_helper",
         "tls_properties_helper",
     ],
-
     data_libs: [
         "libatest_simple_zip",
         "libcfi-test",
@@ -1086,6 +1019,81 @@
     ],
 }
 
+// -----------------------------------------------------------------------------
+// Tests for the device using bionic's .so. Run with:
+//   adb shell /data/nativetest/bionic-unit-tests/bionic-unit-tests
+//   adb shell /data/nativetest64/bionic-unit-tests/bionic-unit-tests
+// -----------------------------------------------------------------------------
+cc_defaults {
+    name: "bionic_unit_tests_defaults",
+    host_supported: false,
+    gtest: false,
+
+    defaults: [
+        "bionic_tests_defaults",
+        "bionic_unit_tests_data",
+    ],
+
+    whole_static_libs: [
+        "libBionicTests",
+        "libBionicLoaderTests",
+        "libBionicElfTlsLoaderTests",
+    ],
+
+    static_libs: [
+        "libtinyxml2",
+        "liblog",
+        "libbase",
+        "libgtest_isolated",
+    ],
+
+    srcs: [
+        // TODO: Include __cxa_thread_atexit_test.cpp to glibc tests once it is upgraded (glibc 2.18+)
+        "__cxa_thread_atexit_test.cpp",
+        "gtest_globals.cpp",
+        "gtest_main.cpp",
+        "gwp_asan_test.cpp",
+        "thread_local_test.cpp",
+    ],
+
+    conlyflags: [
+        "-fexceptions",
+        "-fnon-call-exceptions",
+    ],
+
+    ldflags: ["-Wl,--export-dynamic"],
+
+    include_dirs: ["bionic/libc"],
+
+    stl: "libc++_static",
+
+    target: {
+        android: {
+            shared_libs: [
+                "ld-android",
+                "libdl",
+                "libdl_android",
+                "libdl_preempt_test_1",
+                "libdl_preempt_test_2",
+                "libdl_test_df_1_global",
+                "libtest_elftls_shared_var",
+                "libtest_elftls_tprel",
+            ],
+            static_libs: [
+                // The order of these libraries matters, do not shuffle them.
+                "libmeminfo",
+                "libziparchive",
+                "libz",
+                "libutils",
+            ],
+            ldflags: [
+                "-Wl,--rpath,${ORIGIN}/bionic-loader-test-libs",
+                "-Wl,--enable-new-dtags",
+            ],
+        },
+    },
+}
+
 cc_test {
     name: "bionic-unit-tests",
     defaults: [
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index dc4db07..cc1b598 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -45,6 +45,15 @@
   async_safe_format_buffer(buf, sizeof(buf), "aa%scc", "bb");
   EXPECT_STREQ("aabbcc", buf);
 
+  async_safe_format_buffer(buf, sizeof(buf), "a%bb", 1234);
+  EXPECT_STREQ("a10011010010b", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#bb", 1234);
+  EXPECT_STREQ("a0b10011010010b", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#Bb", 1234);
+  EXPECT_STREQ("a0B10011010010b", buf);
+
   async_safe_format_buffer(buf, sizeof(buf), "a%cc", 'b');
   EXPECT_STREQ("abc", buf);
 
@@ -76,9 +85,15 @@
   async_safe_format_buffer(buf, sizeof(buf), "a%xz", 0x12ab);
   EXPECT_STREQ("a12abz", buf);
 
+  async_safe_format_buffer(buf, sizeof(buf), "a%#xz", 0x12ab);
+  EXPECT_STREQ("a0x12abz", buf);
+
   async_safe_format_buffer(buf, sizeof(buf), "a%Xz", 0x12ab);
   EXPECT_STREQ("a12ABz", buf);
 
+  async_safe_format_buffer(buf, sizeof(buf), "a%#Xz", 0x12ab);
+  EXPECT_STREQ("a0X12ABz", buf);
+
   async_safe_format_buffer(buf, sizeof(buf), "a%08xz", 0x123456);
   EXPECT_STREQ("a00123456z", buf);
 
diff --git a/tests/execinfo_test.cpp b/tests/execinfo_test.cpp
index b8e1325..1a0c51b 100644
--- a/tests/execinfo_test.cpp
+++ b/tests/execinfo_test.cpp
@@ -79,9 +79,13 @@
 }
 
 static size_t FindFunction(std::vector<void*>& frames, uintptr_t func_addr) {
+  Dl_info func_info;
+  if (!dladdr(reinterpret_cast<void*>(func_addr), &func_info)) {
+    return 0;
+  }
   for (size_t i = 0; i < frames.size(); i++) {
-    uintptr_t frame_addr = reinterpret_cast<uintptr_t>(frames[i]);
-    if (frame_addr >= func_addr && frame_addr <= func_addr + 0x100) {
+    Dl_info frame_info;
+    if (dladdr(frames[i], &frame_info) && func_info.dli_saddr == frame_info.dli_saddr) {
       return i + 1;
     }
   }
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index 862f498..c1c586c 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -360,6 +360,6 @@
 #endif
 }
 
-TEST(fcntl_DeathTest, fcntl_F_SETFD) {
+TEST_F(fcntl_DeathTest, fcntl_F_SETFD) {
   EXPECT_DEATH(fcntl(0, F_SETFD, O_NONBLOCK), "non-FD_CLOEXEC");
 }
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index c31f48c..709a939 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -34,12 +34,15 @@
 #if defined(__BIONIC__)
 
 #include "android-base/file.h"
+#include "android-base/silent_death_test.h"
 #include "android-base/test_utils.h"
 #include "gwp_asan/options.h"
 #include "platform/bionic/malloc.h"
 #include "sys/system_properties.h"
 #include "utils.h"
 
+using gwp_asan_integration_DeathTest = SilentDeathTest;
+
 // basename is a mess, use gnu basename explicitly to avoid the need for string
 // mutation.
 extern "C" const char* __gnu_basename(const char* path);
@@ -133,7 +136,7 @@
   }
 };
 
-TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled) {
+TEST_F(gwp_asan_integration_DeathTest, DISABLED_assert_gwp_asan_enabled) {
   std::string maps;
   EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
   EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
@@ -173,7 +176,7 @@
   __system_property_set((std::string("libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                         "40000");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 TEST(gwp_asan_integration, sysprops_persist_program_specific) {
@@ -191,7 +194,7 @@
   __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                         "40000");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
@@ -235,7 +238,7 @@
   __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
   __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 TEST(gwp_asan_integration, sysprops_can_disable) {
@@ -261,7 +264,7 @@
   __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
   __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
 
-  RunGwpAsanTest("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunGwpAsanTest("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 #endif  // defined(__BIONIC__)
diff --git a/tests/headers/posix/termios_h.c b/tests/headers/posix/termios_h.c
index 1255c16..0a67eaa 100644
--- a/tests/headers/posix/termios_h.c
+++ b/tests/headers/posix/termios_h.c
@@ -42,6 +42,12 @@
   STRUCT_MEMBER(struct termios, tcflag_t, c_lflag);
   STRUCT_MEMBER_ARRAY(struct termios, cc_t/*[]*/, c_cc);
 
+#if !defined(__GLIBC__)  // Our glibc is too old.
+  TYPE(struct winsize);
+  STRUCT_MEMBER(struct winsize, unsigned short, ws_row);
+  STRUCT_MEMBER(struct winsize, unsigned short, ws_col);
+#endif
+
   MACRO(NCCS);
 
   MACRO(VEOF);
@@ -162,6 +168,12 @@
   FUNCTION(tcflush, int (*f)(int, int));
   FUNCTION(tcgetattr, int (*f)(int, struct termios*));
   FUNCTION(tcgetsid, pid_t (*f)(int));
+#if !defined(__GLIBC__)  // Our glibc is too old.
+  FUNCTION(tcgetwinsize, int (*f)(int, struct winsize*));
+#endif
   FUNCTION(tcsendbreak, int (*f)(int, int));
   FUNCTION(tcsetattr, int (*f)(int, int, const struct termios*));
+#if !defined(__GLIBC__)  // Our glibc is too old.
+  FUNCTION(tcsetwinsize, int (*f)(int, const struct winsize*));
+#endif
 }
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index 5d85e97..b88d64a 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -19,6 +19,8 @@
 #include <malloc.h>
 #include <sys/prctl.h>
 
+#include <android-base/silent_death_test.h>
+
 #if defined(__BIONIC__)
 #include "gtest_globals.h"
 #include "platform/bionic/mte.h"
@@ -44,7 +46,9 @@
 }
 #endif
 
-TEST(heap_tagging_level, tagged_pointer_dies) {
+using heap_tagging_level_DeathTest = SilentDeathTest;
+
+TEST_F(heap_tagging_level_DeathTest, tagged_pointer_dies) {
 #if defined(__BIONIC__)
   if (!KernelSupportsTaggedPointers()) {
     GTEST_SKIP() << "Kernel doesn't support tagged pointers.";
diff --git a/tests/ifunc_test.cpp b/tests/ifunc_test.cpp
index e3c437e..1fdbf1a 100644
--- a/tests/ifunc_test.cpp
+++ b/tests/ifunc_test.cpp
@@ -60,6 +60,26 @@
   return ret42;
 }
 
+#elif defined(__riscv)
+
+#include <sys/hwprobe.h>
+
+static uint64_t g_hwcap;
+
+static riscv_hwprobe g_hwprobes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0}};
+
+extern "C" fn_ptr_t hwcap_resolver(uint64_t hwcap, void* null) {
+  // Check hwcap like arm32/arm64.
+  g_hwcap = hwcap;
+
+  // For now, the pointer argument is reserved for future expansion.
+  if (null != NULL) abort();
+
+  // Ensure that __riscv_hwprobe() can be called from an ifunc.
+  if (__riscv_hwprobe(g_hwprobes, 1, 0, nullptr, 0) != 0) return nullptr;
+  return ret42;
+}
+
 #else
 
 extern "C" fn_ptr_t hwcap_resolver() {
@@ -81,6 +101,12 @@
   EXPECT_EQ(getauxval(AT_HWCAP2), g_arg._hwcap2);
 #elif defined(__arm__)
   EXPECT_EQ(getauxval(AT_HWCAP), g_hwcap);
+#elif defined(__riscv)
+  EXPECT_EQ(getauxval(AT_HWCAP), g_hwcap);
+
+  riscv_hwprobe probes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0}};
+  ASSERT_EQ(0, __riscv_hwprobe(probes, 1, 0, nullptr, 0));
+  EXPECT_EQ(probes[0].value, g_hwprobes[0].value);
 #endif
 }
 
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 5df694c..776643d 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -1347,45 +1347,44 @@
 }
 
 #if defined(__BIONIC__)
-static void* SetAllocationLimit(void* data) {
-  std::atomic_bool* go = reinterpret_cast<std::atomic_bool*>(data);
-  while (!go->load()) {
-  }
-  size_t limit = 500 * 1024 * 1024;
-  if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
-    return reinterpret_cast<void*>(-1);
-  }
-  return nullptr;
-}
-
 static void SetAllocationLimitMultipleThreads() {
-  std::atomic_bool go;
-  go = false;
-
   static constexpr size_t kNumThreads = 4;
-  pthread_t threads[kNumThreads];
+  std::atomic_bool start_running = false;
+  std::atomic<size_t> num_running;
+  std::atomic<size_t> num_successful;
+  std::unique_ptr<std::thread> threads[kNumThreads];
   for (size_t i = 0; i < kNumThreads; i++) {
-    ASSERT_EQ(0, pthread_create(&threads[i], nullptr, SetAllocationLimit, &go));
+    threads[i].reset(new std::thread([&num_running, &start_running, &num_successful] {
+      ++num_running;
+      while (!start_running) {
+      }
+      size_t limit = 500 * 1024 * 1024;
+      if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
+        ++num_successful;
+      }
+    }));
   }
 
-  // Let them go all at once.
-  go = true;
+  // Wait until all of the threads have started.
+  while (num_running != kNumThreads)
+    ;
+
+  // Now start all of the threads setting the mallopt at once.
+  start_running = true;
+
   // Send hardcoded signal (BIONIC_SIGNAL_PROFILER with value 0) to trigger
-  // heapprofd handler.
-  union sigval signal_value;
-  signal_value.sival_int = 0;
+  // heapprofd handler. This will verify that changing the limit while
+  // the allocation handlers are being changed at the same time works,
+  // or that the limit handler is changed first and this also works properly.
+  union sigval signal_value {};
   ASSERT_EQ(0, sigqueue(getpid(), BIONIC_SIGNAL_PROFILER, signal_value));
 
-  size_t num_successful = 0;
+  // Wait for all of the threads to finish.
   for (size_t i = 0; i < kNumThreads; i++) {
-    void* result;
-    ASSERT_EQ(0, pthread_join(threads[i], &result));
-    if (result != nullptr) {
-      num_successful++;
-    }
+    threads[i]->join();
   }
-  ASSERT_EQ(1U, num_successful);
-  exit(0);
+  ASSERT_EQ(1U, num_successful) << "Only one thread should be able to set the limit.";
+  _exit(0);
 }
 #endif
 
diff --git a/tests/run-on-host.sh b/tests/run-on-host.sh
index fe2c25a..19bbacf 100755
--- a/tests/run-on-host.sh
+++ b/tests/run-on-host.sh
@@ -2,9 +2,14 @@
 
 . $(dirname $0)/../build/run-on-host.sh
 
-if [ "$1" = glibc ]; then
+if [ "$1" = glibc -o "$1" = musl ]; then
+  if [ "$1" = musl ]; then
+    BUILD_ARGS=USE_HOST_MUSL=true
+  else
+    BUILD_ARGS=
+  fi
   shift
-  m -j bionic-unit-tests-glibc
+  m -j $BUILD_ARGS bionic-unit-tests-glibc
   (
     cd ${ANDROID_BUILD_TOP}
     export ANDROID_DATA=${TARGET_OUT_DATA}
@@ -13,7 +18,7 @@
   )
   exit 0
 elif [ "$1" != 32 -a "$1" != 64 ]; then
-  echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
+  echo "Usage: $0 [ 32 | 64 | glibc | musl ] [gtest flags]"
   exit 1
 fi
 
diff --git a/tests/scs_test.cpp b/tests/scs_test.cpp
index 0776a43..3d5ebc1 100644
--- a/tests/scs_test.cpp
+++ b/tests/scs_test.cpp
@@ -16,8 +16,12 @@
 
 #include <gtest/gtest.h>
 
+#include <android-base/silent_death_test.h>
+
 #include "private/bionic_constants.h"
 
+using scs_DeathTest = SilentDeathTest;
+
 int recurse2(int count);
 
 __attribute__((weak, noinline)) int recurse1(int count) {
@@ -30,7 +34,7 @@
   return 0;
 }
 
-TEST(scs_test, stack_overflow) {
+TEST_F(scs_DeathTest, stack_overflow) {
 #if defined(__aarch64__) || defined(__riscv)
   ASSERT_EXIT(recurse1(SCS_SIZE), testing::KilledBySignal(SIGSEGV), "");
 #else
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index fa648d2..2e6908c 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -530,14 +530,15 @@
 #endif
 }
 
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) && !defined(__riscv)
 // Not exposed via headers, but the symbols are available if you declare them yourself.
 extern "C" int sigblock(int);
 extern "C" int sigsetmask(int);
+#define HAVE_SIGBLOCK_SIGSETMASK
 #endif
 
 TEST(signal, sigblock_filter) {
-#if defined(__BIONIC__)
+#if defined(HAVE_SIGBLOCK_SIGSETMASK)
   TestSignalMaskFunction([]() {
     sigblock(~0U);
   });
@@ -545,7 +546,7 @@
 }
 
 TEST(signal, sigsetmask_filter) {
-#if defined(__BIONIC__)
+#if defined(HAVE_SIGBLOCK_SIGSETMASK)
   TestSignalMaskFunction([]() {
     sigsetmask(~0U);
   });
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index b3a296d..b0f59bb 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -1049,11 +1049,13 @@
 }
 
 TEST(STDIO_TEST, popen_return_value_signal) {
-  FILE* fp = popen("kill -7 $$", "r");
+  // Use a realtime signal to avoid creating a tombstone when running.
+  std::string cmd = android::base::StringPrintf("kill -%d $$", SIGRTMIN);
+  FILE* fp = popen(cmd.c_str(), "r");
   ASSERT_TRUE(fp != nullptr);
   int status = pclose(fp);
   EXPECT_TRUE(WIFSIGNALED(status));
-  EXPECT_EQ(7, WTERMSIG(status));
+  EXPECT_EQ(SIGRTMIN, WTERMSIG(status));
 }
 
 TEST(STDIO_TEST, getc) {
@@ -3310,7 +3312,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, snprintf_invalid_w_width) {
+TEST_F(STDIO_DEATHTEST, snprintf_invalid_w_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
@@ -3323,7 +3325,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, swprintf_invalid_w_width) {
+TEST_F(STDIO_DEATHTEST, swprintf_invalid_w_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
@@ -3459,7 +3461,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, snprintf_invalid_wf_width) {
+TEST_F(STDIO_DEATHTEST, snprintf_invalid_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
@@ -3473,7 +3475,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, swprintf_invalid_wf_width) {
+TEST_F(STDIO_DEATHTEST, swprintf_invalid_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
@@ -3572,7 +3574,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, sscanf_invalid_w_or_wf_width) {
+TEST_F(STDIO_DEATHTEST, sscanf_invalid_w_or_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
@@ -3672,7 +3674,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, swscanf_invalid_w_or_wf_width) {
+TEST_F(STDIO_DEATHTEST, swscanf_invalid_w_or_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
diff --git a/tests/sys_cachectl_test.cpp b/tests/sys_cachectl_test.cpp
new file mode 100644
index 0000000..d9ece4f
--- /dev/null
+++ b/tests/sys_cachectl_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#if __has_include(<sys/cachectl.h>)
+#include <sys/cachectl.h>
+#endif
+
+TEST(sys_cachectl, __riscv_flush_icache) {
+#if defined(__riscv) && __has_include(<sys/cachectl.h>)
+  // As of Linux 6.4, the address range is ignored (so nullptr is fine),
+  // and the flags you actually want are 0 ("all threads"),
+  // but we test the unusual flag just to make sure it works.
+  ASSERT_EQ(0, __riscv_flush_icache(nullptr, nullptr, SYS_RISCV_FLUSH_ICACHE_LOCAL));
+#else
+  GTEST_SKIP() << "__riscv_flush_icache requires riscv64";
+#endif
+}
diff --git a/tests/sys_epoll_test.cpp b/tests/sys_epoll_test.cpp
index fb2a48f..8dee93f 100644
--- a/tests/sys_epoll_test.cpp
+++ b/tests/sys_epoll_test.cpp
@@ -24,29 +24,101 @@
 
 #include "utils.h"
 
-TEST(sys_epoll, smoke) {
+TEST(sys_epoll, epoll_wait) {
   int epoll_fd = epoll_create(1);
-  ASSERT_NE(-1, epoll_fd) << strerror(errno);
-  epoll_event events[1];
+  ASSERT_NE(-1, epoll_fd);
 
   // Regular epoll_wait.
+  epoll_event events[1] = {};
   ASSERT_EQ(0, epoll_wait(epoll_fd, events, 1, 1));
+}
+
+TEST(sys_epoll, epoll_pwait_no_sigset) {
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd);
 
   // epoll_pwait without a sigset (which is equivalent to epoll_wait).
+  epoll_event events[1] = {};
   ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, nullptr));
+}
 
+TEST(sys_epoll, epoll_pwait64_no_sigset) {
 #if defined(__BIONIC__)
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd);
+
   // epoll_pwait64 without a sigset (which is equivalent to epoll_wait).
+  epoll_event events[1] = {};
   ASSERT_EQ(0, epoll_pwait64(epoll_fd, events, 1, 1, nullptr));
+#else
+  GTEST_SKIP() << "epoll_pwait64 is bionic-only";
 #endif
+}
+
+TEST(sys_epoll, epoll_pwait2_no_sigset) {
+#if defined(__BIONIC__)
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd);
+
+  // epoll_pwait2 without a sigset (which is equivalent to epoll_wait).
+  epoll_event events[1] = {};
+  timespec ts = {.tv_nsec = 500};
+  int rc = epoll_pwait2(epoll_fd, events, 1, &ts, nullptr);
+  if (rc == -1 && errno == ENOSYS) GTEST_SKIP() << "no epoll_pwait2 in this kernel";
+  ASSERT_EQ(0, rc) << strerror(errno);
+#else
+  GTEST_SKIP() << "epoll_pwait2 is only in glibc 2.35+";
+#endif
+}
+
+TEST(sys_epoll, epoll_pwait_with_sigset) {
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd);
 
   // epoll_pwait with a sigset.
+  epoll_event events[1] = {};
   sigset_t ss;
   sigemptyset(&ss);
   sigaddset(&ss, SIGPIPE);
   ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, &ss));
 }
 
+TEST(sys_epoll, epoll_pwait2_with_sigset) {
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd);
+
+#if defined(__BIONIC__)
+  epoll_event events[1] = {};
+  timespec ts = {.tv_nsec = 500};
+  sigset_t ss2;
+  sigemptyset(&ss2);
+  sigaddset(&ss2, SIGPIPE);
+  int rc = epoll_pwait2(epoll_fd, events, 1, &ts, &ss2);
+  if (rc == -1 && errno == ENOSYS) GTEST_SKIP() << "no epoll_pwait2 in this kernel";
+  ASSERT_EQ(0, rc) << strerror(errno);
+#else
+  GTEST_SKIP() << "epoll_pwait2 is only in glibc 2.35+";
+#endif
+}
+
+TEST(sys_epoll, epoll_pwait2_64_with_sigset) {
+  int epoll_fd = epoll_create(1);
+  ASSERT_NE(-1, epoll_fd);
+
+#if defined(__BIONIC__)
+  epoll_event events[1] = {};
+  timespec ts = {.tv_nsec = 500};
+  sigset64_t ss2;
+  sigemptyset64(&ss2);
+  sigaddset64(&ss2, SIGPIPE);
+  int rc = epoll_pwait2_64(epoll_fd, events, 1, &ts, &ss2);
+  if (rc == -1 && errno == ENOSYS) GTEST_SKIP() << "no epoll_pwait2 in this kernel";
+  ASSERT_EQ(0, rc) << strerror(errno);
+#else
+  GTEST_SKIP() << "epoll_pwait2_64 is bionic-only";
+#endif
+}
+
 TEST(sys_epoll, epoll_create_invalid_size) {
   errno = 0;
   ASSERT_EQ(-1, epoll_create(0));
diff --git a/tests/sys_hwprobe_test.cpp b/tests/sys_hwprobe_test.cpp
new file mode 100644
index 0000000..3c8dce2
--- /dev/null
+++ b/tests/sys_hwprobe_test.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#if __has_include(<sys/hwprobe.h>)
+#include <sys/hwprobe.h>
+#include <sys/syscall.h>
+#endif
+
+TEST(sys_hwprobe, __riscv_hwprobe) {
+#if defined(__riscv) && __has_include(<sys/hwprobe.h>)
+  riscv_hwprobe probes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0},
+                            {.key = RISCV_HWPROBE_KEY_CPUPERF_0}};
+  ASSERT_EQ(0, __riscv_hwprobe(probes, 2, 0, nullptr, 0));
+  EXPECT_EQ(RISCV_HWPROBE_KEY_IMA_EXT_0, probes[0].key);
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_IMA_FD) != 0);
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_IMA_C) != 0);
+  // TODO: remove #define when our uapi headers are new enough.
+#define RISCV_HWPROBE_IMA_V (1 << 2)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_IMA_V) != 0);
+  // TODO: remove #ifs when our kernel is new enough.
+#if defined(RISCV_HWPROBE_EXT_ZBA)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_EXT_ZBA) != 0);
+#endif
+#if defined(RISCV_HWPROBE_EXT_ZBB)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_EXT_ZBB) != 0);
+#endif
+#if defined(RISCV_HWPROBE_EXT_ZBS)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_EXT_ZBS) != 0);
+#endif
+
+  EXPECT_EQ(RISCV_HWPROBE_KEY_CPUPERF_0, probes[1].key);
+  EXPECT_TRUE((probes[1].value & RISCV_HWPROBE_MISALIGNED_MASK) == RISCV_HWPROBE_MISALIGNED_FAST);
+#else
+  GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
+#endif
+}
+
+TEST(sys_hwprobe, __riscv_hwprobe_syscall_vdso) {
+#if defined(__riscv) && __has_include(<sys/hwprobe.h>)
+  riscv_hwprobe probes_vdso[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0},
+                                 {.key = RISCV_HWPROBE_KEY_CPUPERF_0}};
+  ASSERT_EQ(0, __riscv_hwprobe(probes_vdso, 2, 0, nullptr, 0));
+
+  riscv_hwprobe probes_syscall[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0},
+                                    {.key = RISCV_HWPROBE_KEY_CPUPERF_0}};
+  ASSERT_EQ(0, syscall(SYS_riscv_hwprobe, probes_syscall, 2, 0, nullptr, 0));
+
+  // Check we got the same answers from the vdso and the syscall.
+  EXPECT_EQ(RISCV_HWPROBE_KEY_IMA_EXT_0, probes_syscall[0].key);
+  EXPECT_EQ(probes_vdso[0].key, probes_syscall[0].key);
+  EXPECT_EQ(probes_vdso[0].value, probes_syscall[0].value);
+  EXPECT_EQ(RISCV_HWPROBE_KEY_CPUPERF_0, probes_syscall[1].key);
+  EXPECT_EQ(probes_vdso[1].key, probes_syscall[1].key);
+  EXPECT_EQ(probes_vdso[1].value, probes_syscall[1].value);
+#else
+  GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
+#endif
+}
+
+TEST(sys_hwprobe, __riscv_hwprobe_fail) {
+#if defined(__riscv) && __has_include(<sys/hwprobe.h>)
+  riscv_hwprobe probes[] = {};
+  ASSERT_EQ(EINVAL, __riscv_hwprobe(probes, 0, 0, nullptr, ~0));
+#else
+  GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
+#endif
+}
diff --git a/tests/termios_test.cpp b/tests/termios_test.cpp
index 6290771..a8d5890 100644
--- a/tests/termios_test.cpp
+++ b/tests/termios_test.cpp
@@ -29,6 +29,8 @@
 #include <termios.h>
 
 #include <errno.h>
+#include <fcntl.h>
+#include <pty.h>
 
 #include <gtest/gtest.h>
 
@@ -96,3 +98,49 @@
   EXPECT_EQ(1, t.c_cc[VMIN]);
   EXPECT_EQ(0, t.c_cc[VTIME]);
 }
+
+TEST(termios, tcgetwinsize_tcsetwinsize_invalid) {
+#if !defined(__GLIBC__)
+  winsize ws = {};
+
+  errno = 0;
+  ASSERT_EQ(-1, tcgetwinsize(-1, &ws));
+  ASSERT_EQ(EBADF, errno);
+
+  errno = 0;
+  ASSERT_EQ(-1, tcsetwinsize(-1, &ws));
+  ASSERT_EQ(EBADF, errno);
+#else
+  GTEST_SKIP() << "glibc too old";
+#endif
+}
+
+TEST(termios, tcgetwinsize_tcsetwinsize) {
+#if !defined(__GLIBC__)
+  int pty, tty;
+  winsize ws = {123, 456, 9999, 9999};
+  ASSERT_EQ(0, openpty(&pty, &tty, nullptr, nullptr, &ws));
+
+  winsize actual = {};
+  ASSERT_EQ(0, tcgetwinsize(tty, &actual));
+  EXPECT_EQ(ws.ws_xpixel, actual.ws_xpixel);
+  EXPECT_EQ(ws.ws_ypixel, actual.ws_ypixel);
+  EXPECT_EQ(ws.ws_row, actual.ws_row);
+  EXPECT_EQ(ws.ws_col, actual.ws_col);
+
+  ws = {1, 2, 3, 4};
+  ASSERT_EQ(0, tcsetwinsize(tty, &ws));
+
+  actual = {};
+  ASSERT_EQ(0, tcgetwinsize(tty, &actual));
+  EXPECT_EQ(ws.ws_xpixel, actual.ws_xpixel);
+  EXPECT_EQ(ws.ws_ypixel, actual.ws_ypixel);
+  EXPECT_EQ(ws.ws_row, actual.ws_row);
+  EXPECT_EQ(ws.ws_col, actual.ws_col);
+
+  close(pty);
+  close(tty);
+#else
+  GTEST_SKIP() << "glibc too old";
+#endif
+}
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index 4dc6314..512f098 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -24,22 +24,64 @@
 #include <locale.h>
 #include <stdint.h>
 
+// Modern versions of UTF-8 (https://datatracker.ietf.org/doc/html/rfc3629 and
+// newer) explicitly disallow code points beyond U+10FFFF, which exclude all 5-
+// and 6-byte sequences. Earlier versions of UTF-8 allowed the wider range:
+// https://datatracker.ietf.org/doc/html/rfc2279.
+//
+// Bionic's unicode implementation was written after the high values were
+// excluded, so it has never supported them. Other implementations (at least
+// as of glibc 2.36), do support those sequences.
+#if defined(__ANDROID__) || defined(ANDROID_HOST_MUSL)
+constexpr bool kLibcRejectsOverLongUtf8Sequences = true;
+#elif defined(__GLIBC__)
+constexpr bool kLibcRejectsOverLongUtf8Sequences = false;
+#else
+#error kLibcRejectsOverLongUtf8Sequences must be configured for this platform
+#endif
+
 TEST(uchar, sizeof_uchar_t) {
   EXPECT_EQ(2U, sizeof(char16_t));
   EXPECT_EQ(4U, sizeof(char32_t));
 }
 
 TEST(uchar, start_state) {
+  // C23 does not appear to specify the behavior of the conversion functions if
+  // a state is reused before the character is completed. In the wchar.h section
+  // (7.31.6.3) it says:
+  //
+  //     If an mbstate_t object has been altered by any of the functions
+  //     described in this subclause, and is then used with a different
+  //     multibyte character sequence, or in the other conversion direction, or
+  //     with a different LC_CTYPE category setting than on earlier function
+  //     calls, the behavior is undefined.
+  //
+  // But "described in this subclause" refers to the wchar.h functions, not the
+  // uchar.h ones.
+  //
+  // Since C has no opinion, we need to make a choice. While no caller should
+  // ever do this (what does it mean to begin decoding a UTF-32 character while
+  // still in the middle of a UTF-8 sequence?), considering that a decoding
+  // error seems the least surprising. Bionic and glibc both have that behavior.
+  // musl ignores the state (it also doesn't make much sense to read the state
+  // when the entire conversion completes in a single call) and decodes the
+  // UTF-32 character.
+#if !defined(ANDROID_HOST_MUSL)
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char out[MB_LEN_MAX];
   mbstate_t ps;
 
-  // Any non-initial state is invalid when calling c32rtomb.
   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));
   EXPECT_EQ(EILSEQ, errno);
 
+  // Similarly (but not in compliance with the standard afaict), musl seems to
+  // ignore the state entirely for the UTF-32 functions rather than reset it.
+
   // 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));
@@ -51,14 +93,21 @@
   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));
+#endif
 }
 
 TEST(uchar, c16rtomb_null_out) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   EXPECT_EQ(1U, c16rtomb(nullptr, L'\0', nullptr));
   EXPECT_EQ(1U, c16rtomb(nullptr, L'h', nullptr));
 }
 
 TEST(uchar, c16rtomb_null_char) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char bytes[MB_LEN_MAX];
   EXPECT_EQ(1U, c16rtomb(bytes, L'\0', nullptr));
 }
@@ -99,6 +148,9 @@
 }
 
 TEST(uchar, c16rtomb_invalid) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char bytes[MB_LEN_MAX];
 
   memset(bytes, 0, sizeof(bytes));
@@ -109,20 +161,26 @@
 }
 
 TEST(uchar, mbrtoc16_null) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   ASSERT_EQ(0U, mbrtoc16(nullptr, nullptr, 0, nullptr));
 }
 
 TEST(uchar, mbrtoc16_zero_len) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char16_t out;
 
   out = L'x';
-  ASSERT_EQ(0U, mbrtoc16(&out, "hello", 0, nullptr));
-  ASSERT_EQ(L'x', out);
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "hello", 0, nullptr));
+  EXPECT_EQ(L'x', out);
 
-  ASSERT_EQ(0U, mbrtoc16(&out, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtoc16(&out, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtoc16(&out, "hello", 1, nullptr));
-  ASSERT_EQ(L'h', out);
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtoc16(&out, "hello", 1, nullptr));
+  EXPECT_EQ(L'h', out);
 }
 
 TEST(uchar, mbrtoc16) {
@@ -141,27 +199,60 @@
   ASSERT_EQ(3U, mbrtoc16(&out, "\xe2\x82\xac" "def", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0x20ac), out);
   // 4-byte UTF-8 will be returned as a surrogate pair...
-  ASSERT_EQ(static_cast<size_t>(-3),
-            mbrtoc16(&out, "\xf4\x8a\xaf\x8d", 6, nullptr));
+  ASSERT_EQ(4U, mbrtoc16(&out, "\xf4\x8a\xaf\x8d", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0xdbea), out);
-  ASSERT_EQ(4U, mbrtoc16(&out, "\xf4\x8a\xaf\x8d" "ef", 6, nullptr));
+  ASSERT_EQ(static_cast<size_t>(-3), mbrtoc16(&out,
+                                              "\xf4\x8a\xaf\x8d"
+                                              "ef",
+                                              6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
-  // Illegal 5-byte UTF-8.
+}
+
+TEST(uchar, mbrtoc16_long_sequences) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
+  char16_t out = u'\0';
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc16(&out, "\xf8\xa1\xa2\xa3\xa4", 5, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  auto result = mbrtoc16(&out, "\xf8\xa1\xa2\xa3\xa4", 5, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    EXPECT_EQ(static_cast<size_t>(-1), result);
+    EXPECT_EQ(EILSEQ, errno);
+    EXPECT_EQ(u'\0', out);
+  } else {
+    EXPECT_EQ(5U, result);
+    EXPECT_EQ(0, errno);
+    EXPECT_EQ(u'\uf94a', out);
+  }
 }
 
 TEST(uchar, mbrtoc16_reserved_range) {
-  char16_t out;
-  ASSERT_EQ(static_cast<size_t>(-1),
-            mbrtoc16(&out, "\xf0\x80\xbf\xbf", 6, nullptr));
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
+  errno = 0;
+  char16_t out = u'\0';
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtoc16(&out, "\xf0\x80\xbf\xbf", 6, nullptr));
+  EXPECT_EQ(u'\0', out);
+  EXPECT_EQ(EILSEQ, errno);
 }
 
 TEST(uchar, mbrtoc16_beyond_range) {
-  char16_t out;
-  ASSERT_EQ(static_cast<size_t>(-1),
-            mbrtoc16(&out, "\xf5\x80\x80\x80", 6, nullptr));
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
+  errno = 0;
+  char16_t out = u'\0';
+  auto result = mbrtoc16(&out, "\xf5\x80\x80\x80", 6, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    EXPECT_EQ(static_cast<size_t>(-1), result);
+    EXPECT_EQ(u'\0', out);
+    EXPECT_EQ(EILSEQ, errno);
+  } else {
+    EXPECT_EQ(4U, result);
+    EXPECT_EQ(u'\xdcc0', out);
+    EXPECT_EQ(0, errno);
+  }
 }
 
 void test_mbrtoc16_incomplete(mbstate_t* ps) {
@@ -183,9 +274,15 @@
   // 4-byte UTF-8.
   ASSERT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "\xf4", 1, ps));
   ASSERT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "\x8a\xaf", 2, ps));
-  ASSERT_EQ(static_cast<size_t>(-3), mbrtoc16(&out, "\x8d" "ef", 3, ps));
+  ASSERT_EQ(1U, mbrtoc16(&out,
+                         "\x8d"
+                         "ef",
+                         3, ps));
   ASSERT_EQ(static_cast<char16_t>(0xdbea), out);
-  ASSERT_EQ(1U, mbrtoc16(&out, "\x80" "ef", 3, ps));
+  ASSERT_EQ(static_cast<size_t>(-3), mbrtoc16(&out,
+                                              "\x80"
+                                              "ef",
+                                              3, ps));
   ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
   ASSERT_TRUE(mbsinit(ps));
 
@@ -197,6 +294,9 @@
 }
 
 TEST(uchar, mbrtoc16_incomplete) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   mbstate_t ps;
   memset(&ps, 0, sizeof(ps));
 
@@ -265,55 +365,78 @@
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
-  char32_t out[8] = {};
+  char32_t out = U'\0';
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf5\x80\x80\x80", 4, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  auto result = mbrtoc32(&out, "\xf5\x80\x80\x80", 4, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    EXPECT_EQ(static_cast<size_t>(-1), result);
+    EXPECT_EQ(EILSEQ, errno);
+    EXPECT_EQ(U'\0', out);
+  } else {
+    EXPECT_EQ(4U, result);
+    EXPECT_EQ(0, errno);
+    EXPECT_EQ(U'\x140000', out);
+  }
 }
 
 TEST(uchar, mbrtoc32) {
   char32_t out[8];
 
   out[0] = L'x';
-  ASSERT_EQ(0U, mbrtoc32(out, "hello", 0, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(L'x'), out[0]);
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(out, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(L'x'), out[0]);
 
-  ASSERT_EQ(0U, mbrtoc32(out, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtoc32(out, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtoc32(out, "hello", 1, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(L'h'), out[0]);
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(out, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(out, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtoc32(out, "hello", 1, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(L'h'), out[0]);
 
-  ASSERT_EQ(0U, mbrtoc32(nullptr, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtoc32(nullptr, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtoc32(nullptr, "hello", 1, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtoc32(nullptr, "hello", 1, nullptr));
 
-  ASSERT_EQ(0U, mbrtoc32(nullptr, nullptr, 0, nullptr));
+  EXPECT_EQ(0U, mbrtoc32(nullptr, nullptr, 0, nullptr));
 
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
   // 1-byte UTF-8.
-  ASSERT_EQ(1U, mbrtoc32(out, "abcdef", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(L'a'), out[0]);
+  EXPECT_EQ(1U, mbrtoc32(out, "abcdef", 6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(L'a'), out[0]);
   // 2-byte UTF-8.
-  ASSERT_EQ(2U, mbrtoc32(out, "\xc2\xa2" "cdef", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(0x00a2), out[0]);
+  EXPECT_EQ(2U, mbrtoc32(out,
+                         "\xc2\xa2"
+                         "cdef",
+                         6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(0x00a2), out[0]);
   // 3-byte UTF-8.
-  ASSERT_EQ(3U, mbrtoc32(out, "\xe2\x82\xac" "def", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(0x20ac), out[0]);
+  EXPECT_EQ(3U, mbrtoc32(out,
+                         "\xe2\x82\xac"
+                         "def",
+                         6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(0x20ac), out[0]);
   // 4-byte UTF-8.
-  ASSERT_EQ(4U, mbrtoc32(out, "\xf0\xa4\xad\xa2" "ef", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(0x24b62), out[0]);
+  EXPECT_EQ(4U, mbrtoc32(out,
+                         "\xf0\xa4\xad\xa2"
+                         "ef",
+                         6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(0x24b62), out[0]);
 #if defined(__BIONIC__) // glibc allows this.
   // Illegal 5-byte UTF-8.
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtoc32(out,
+                                              "\xf8\xa1\xa2\xa3\xa4"
+                                              "f",
+                                              6, nullptr));
+  EXPECT_EQ(EILSEQ, errno);
 #endif
   // Illegal over-long sequence.
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf0\x82\x82\xac" "ef", 6, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtoc32(out,
+                                              "\xf0\x82\x82\xac"
+                                              "ef",
+                                              6, nullptr));
+  EXPECT_EQ(EILSEQ, errno);
 }
 
 void test_mbrtoc32_incomplete(mbstate_t* ps) {
@@ -347,6 +470,9 @@
 }
 
 TEST(uchar, mbrtoc32_incomplete) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   mbstate_t ps;
   memset(&ps, 0, sizeof(ps));
 
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 4c21627..ac39f96 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1166,6 +1166,30 @@
   VERIFY_SYSCONF_UNKNOWN(666);
 }
 
+[[maybe_unused]] static void show_cache(const char* name, long size, long assoc, long line_size) {
+  printf("%s cache size: %ld bytes, line size %ld bytes, ", name, size, line_size);
+  if (assoc == 0) {
+    printf("fully");
+  } else {
+    printf("%ld-way", assoc);
+  }
+  printf(" associative\n");
+}
+
+TEST(UNISTD_TEST, sysconf_cache) {
+#if defined(ANDROID_HOST_MUSL)
+  GTEST_SKIP() << "musl does not have _SC_LEVEL?_?CACHE_SIZE";
+#else
+  // It's not obvious we can _test_ any of these, but we can at least
+  // show the output for humans to inspect.
+  show_cache("L1D", sysconf(_SC_LEVEL1_DCACHE_SIZE), sysconf(_SC_LEVEL1_DCACHE_ASSOC), sysconf(_SC_LEVEL1_DCACHE_LINESIZE));
+  show_cache("L1I", sysconf(_SC_LEVEL1_ICACHE_SIZE), sysconf(_SC_LEVEL1_ICACHE_ASSOC), sysconf(_SC_LEVEL1_ICACHE_LINESIZE));
+  show_cache("L2", sysconf(_SC_LEVEL2_CACHE_SIZE), sysconf(_SC_LEVEL2_CACHE_ASSOC), sysconf(_SC_LEVEL2_CACHE_LINESIZE));
+  show_cache("L3", sysconf(_SC_LEVEL3_CACHE_SIZE), sysconf(_SC_LEVEL3_CACHE_ASSOC), sysconf(_SC_LEVEL3_CACHE_LINESIZE));
+  show_cache("L4", sysconf(_SC_LEVEL4_CACHE_SIZE), sysconf(_SC_LEVEL4_CACHE_ASSOC), sysconf(_SC_LEVEL4_CACHE_LINESIZE));
+#endif
+}
+
 TEST(UNISTD_TEST, dup2_same) {
   // POSIX says of dup2:
   // If fildes2 is already a valid open file descriptor ...
diff --git a/tests/utils.cpp b/tests/utils.cpp
index 92ab145..948d0ec 100644
--- a/tests/utils.cpp
+++ b/tests/utils.cpp
@@ -28,6 +28,7 @@
 
 #include "utils.h"
 
+#include <syscall.h>
 #include <string>
 
 #include <android-base/properties.h>
@@ -63,3 +64,9 @@
          (android::base::GetBoolProperty("ro.debuggable", false) &&
           android::base::GetBoolProperty("debug.force_low_ram", false));
 }
+
+#if defined(__GLIBC__) && __GLIBC_MINOR__ < 30
+pid_t gettid() {
+  return syscall(__NR_gettid);
+}
+#endif
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 8716810..28c1046 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -29,6 +29,37 @@
 
 #define NUM_WCHARS(num_bytes) ((num_bytes)/sizeof(wchar_t))
 
+#ifdef __GLIBC__
+// glibc immediately dereferences the locale passed to all wcsto*_l functions,
+// even if it won't be used, and even if it's LC_GLOBAL_LOCALE, which isn't a
+// pointer to valid memory.
+static locale_t SAFE_LC_GLOBAL_LOCALE = duplocale(LC_GLOBAL_LOCALE);
+#else
+static locale_t SAFE_LC_GLOBAL_LOCALE = LC_GLOBAL_LOCALE;
+#endif
+
+// Modern versions of UTF-8 (https://datatracker.ietf.org/doc/html/rfc3629 and
+// newer) explicitly disallow code points beyond U+10FFFF, which exclude all 5-
+// and 6-byte sequences. Earlier versions of UTF-8 allowed the wider range:
+// https://datatracker.ietf.org/doc/html/rfc2279.
+//
+// Bionic's unicode implementation was written after the high values were
+// excluded, so it has never supported them. Other implementations (at least
+// as of glibc 2.36), do support those sequences.
+#if defined(__ANDROID__) || defined(ANDROID_HOST_MUSL)
+constexpr bool kLibcRejectsOverLongUtf8Sequences = true;
+#elif defined(__GLIBC__)
+constexpr bool kLibcRejectsOverLongUtf8Sequences = false;
+#else
+#error kLibcRejectsOverLongUtf8Sequences must be configured for this platform
+#endif
+
+#if defined(__GLIBC__)
+constexpr bool kLibcSupportsParsingBinaryLiterals = __GLIBC_PREREQ(2, 38);
+#else
+constexpr bool kLibcSupportsParsingBinaryLiterals = true;
+#endif
+
 TEST(wchar, sizeof_wchar_t) {
   EXPECT_EQ(4U, sizeof(wchar_t));
   EXPECT_EQ(4U, sizeof(wint_t));
@@ -36,7 +67,7 @@
 
 TEST(wchar, mbrlen) {
   char bytes[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
-  EXPECT_EQ(0U, mbrlen(&bytes[0], 0, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrlen(&bytes[0], 0, nullptr));
   EXPECT_EQ(1U, mbrlen(&bytes[0], 1, nullptr));
 
   EXPECT_EQ(1U, mbrlen(&bytes[4], 1, nullptr));
@@ -95,6 +126,9 @@
 }
 
 TEST(wchar, wcrtomb_start_state) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char out[MB_LEN_MAX];
   mbstate_t ps;
 
@@ -118,6 +152,9 @@
 }
 
 TEST(wchar, wcstombs_wcrtombs) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   const wchar_t chars[] = { L'h', L'e', L'l', L'l', L'o', 0 };
   const wchar_t bad_chars[] = { L'h', L'i', static_cast<wchar_t>(0xffffffff), 0 };
   const wchar_t* src;
@@ -255,63 +292,97 @@
 TEST(wchar, mbtowc) {
   wchar_t out[8];
 
+  // mbtowc and all the mbrto* APIs behave slightly differently when n is 0:
+  //
+  // mbrtowc returns 0 "if the next n or fewer bytes complete the multibyte
+  // character that corresponds to the null wide character"
+  //
+  // mbrtoc says: "If s is not a null pointer, the mbtowc function either
+  // returns 0 (if s points to the null character)..."
+  //
+  // So mbrtowc will not provide the correct mbtowc return value for "" and
+  // n = 0.
+  //
+  // glibc gets this right, but all the BSDs (including macOS) and bionic (by
+  // way of openbsd) return -1 instead of 0.
+#ifdef __GLIBC__
+  int expected_result_for_zero_length_empty_string = 0;
+#else
+  int expected_result_for_zero_length_empty_string = -1;
+#endif
+
   out[0] = 'x';
-  ASSERT_EQ(0, mbtowc(out, "hello", 0));
-  ASSERT_EQ('x', out[0]);
+  EXPECT_EQ(-1, mbtowc(out, "hello", 0));
+  EXPECT_EQ('x', out[0]);
 
-  ASSERT_EQ(0, mbtowc(out, "hello", 0));
-  ASSERT_EQ(0, mbtowc(out, "", 0));
-  ASSERT_EQ(1, mbtowc(out, "hello", 1));
-  ASSERT_EQ(L'h', out[0]);
+  EXPECT_EQ(-1, mbtowc(out, "hello", 0));
+  EXPECT_EQ(expected_result_for_zero_length_empty_string, mbtowc(out, "", 0));
+  EXPECT_EQ(1, mbtowc(out, "hello", 1));
+  EXPECT_EQ(L'h', out[0]);
 
-  ASSERT_EQ(0, mbtowc(nullptr, "hello", 0));
-  ASSERT_EQ(0, mbtowc(nullptr, "", 0));
-  ASSERT_EQ(1, mbtowc(nullptr, "hello", 1));
+  EXPECT_EQ(-1, mbtowc(nullptr, "hello", 0));
+  EXPECT_EQ(expected_result_for_zero_length_empty_string, mbtowc(nullptr, "", 0));
+  EXPECT_EQ(1, mbtowc(nullptr, "hello", 1));
 
-  ASSERT_EQ(0, mbtowc(nullptr, nullptr, 0));
+  EXPECT_EQ(0, mbtowc(nullptr, nullptr, 0));
 }
 
 TEST(wchar, mbrtowc) {
   wchar_t out[8];
 
   out[0] = 'x';
-  ASSERT_EQ(0U, mbrtowc(out, "hello", 0, nullptr));
-  ASSERT_EQ('x', out[0]);
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(out, "hello", 0, nullptr));
+  EXPECT_EQ('x', out[0]);
 
-  ASSERT_EQ(0U, mbrtowc(out, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtowc(out, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtowc(out, "hello", 1, nullptr));
-  ASSERT_EQ(L'h', out[0]);
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(out, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(out, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtowc(out, "hello", 1, nullptr));
+  EXPECT_EQ(L'h', out[0]);
 
-  ASSERT_EQ(0U, mbrtowc(nullptr, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtowc(nullptr, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtowc(nullptr, "hello", 1, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<size_t>(-2), mbrtowc(nullptr, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtowc(nullptr, "hello", 1, nullptr));
 
-  ASSERT_EQ(0U, mbrtowc(nullptr, nullptr, 0, nullptr));
+  EXPECT_EQ(0U, mbrtowc(nullptr, nullptr, 0, nullptr));
 
-  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  EXPECT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
   // 1-byte UTF-8.
-  ASSERT_EQ(1U, mbrtowc(out, "abcdef", 6, nullptr));
-  ASSERT_EQ(L'a', out[0]);
+  EXPECT_EQ(1U, mbrtowc(out, "abcdef", 6, nullptr));
+  EXPECT_EQ(L'a', out[0]);
   // 2-byte UTF-8.
-  ASSERT_EQ(2U, mbrtowc(out, "\xc2\xa2" "cdef", 6, nullptr));
-  ASSERT_EQ(static_cast<wchar_t>(0x00a2), out[0]);
+  EXPECT_EQ(2U, mbrtowc(out,
+                        "\xc2\xa2"
+                        "cdef",
+                        6, nullptr));
+  EXPECT_EQ(static_cast<wchar_t>(0x00a2), out[0]);
   // 3-byte UTF-8.
-  ASSERT_EQ(3U, mbrtowc(out, "\xe2\x82\xac" "def", 6, nullptr));
-  ASSERT_EQ(static_cast<wchar_t>(0x20ac), out[0]);
+  EXPECT_EQ(3U, mbrtowc(out,
+                        "\xe2\x82\xac"
+                        "def",
+                        6, nullptr));
+  EXPECT_EQ(static_cast<wchar_t>(0x20ac), out[0]);
   // 4-byte UTF-8.
-  ASSERT_EQ(4U, mbrtowc(out, "\xf0\xa4\xad\xa2" "ef", 6, nullptr));
-  ASSERT_EQ(static_cast<wchar_t>(0x24b62), out[0]);
+  EXPECT_EQ(4U, mbrtowc(out,
+                        "\xf0\xa4\xad\xa2"
+                        "ef",
+                        6, nullptr));
+  EXPECT_EQ(static_cast<wchar_t>(0x24b62), out[0]);
 #if defined(__BIONIC__) // glibc allows this.
   // Illegal 5-byte UTF-8.
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtowc(out,
+                                             "\xf8\xa1\xa2\xa3\xa4"
+                                             "f",
+                                             6, nullptr));
+  EXPECT_EQ(EILSEQ, errno);
 #endif
   // Illegal over-long sequence.
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf0\x82\x82\xac" "ef", 6, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtowc(out,
+                                             "\xf0\x82\x82\xac"
+                                             "ef",
+                                             6, nullptr));
+  EXPECT_EQ(EILSEQ, errno);
 }
 
 TEST(wchar, mbrtowc_valid_non_characters) {
@@ -332,8 +403,14 @@
 
   wchar_t out[8] = {};
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtowc(out, "\xf5\x80\x80\x80", 4, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  auto result = mbrtowc(out, "\xf5\x80\x80\x80", 4, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    ASSERT_EQ(static_cast<size_t>(-1), result);
+    ASSERT_EQ(EILSEQ, errno);
+  } else {
+    ASSERT_EQ(4U, result);
+    ASSERT_EQ(0, errno);
+  }
 }
 
 static void test_mbrtowc_incomplete(mbstate_t* ps) {
@@ -446,8 +523,8 @@
 void TestSingleWcsToInt(WcsToIntFn<T> fn, const wchar_t* str, int base,
                         T expected_value, ptrdiff_t expected_len) {
   wchar_t* p;
-  ASSERT_EQ(expected_value, fn(str, &p, base));
-  ASSERT_EQ(expected_len, p - str) << str;
+  EXPECT_EQ(expected_value, fn(str, &p, base)) << str << " " << base;
+  EXPECT_EQ(expected_len, p - str) << str << " " << base;
 }
 
 template <typename T>
@@ -460,7 +537,9 @@
   TestSingleWcsToInt(fn, L"   123 45", 0, static_cast<T>(123), 6);
   TestSingleWcsToInt(fn, L"  -123", 0, static_cast<T>(-123), 6);
   TestSingleWcsToInt(fn, L"0x10000", 0, static_cast<T>(65536), 7);
-  TestSingleWcsToInt(fn, L"0b1011", 0, static_cast<T>(0b1011), 6);
+  if (kLibcSupportsParsingBinaryLiterals) {
+    TestSingleWcsToInt(fn, L"0b1011", 0, static_cast<T>(0b1011), 6);
+  }
 }
 
 template <typename T>
@@ -584,7 +663,7 @@
 
   EXPECT_EQ(24U, wcsftime(buf, sizeof(buf), L"%c", &t));
   EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf);
-  EXPECT_EQ(24U, wcsftime_l(buf, sizeof(buf), L"%c", &t, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(24U, wcsftime_l(buf, sizeof(buf), L"%c", &t, SAFE_LC_GLOBAL_LOCALE));
   EXPECT_STREQ(L"Sun Mar 10 00:00:00 2100", buf);
 }
 
@@ -781,25 +860,25 @@
 
 TEST(wchar, wcstoll_l_EINVAL) {
   errno = 0;
-  wcstoll_l(L"123", nullptr, -1, LC_GLOBAL_LOCALE);
+  wcstoll_l(L"123", nullptr, -1, SAFE_LC_GLOBAL_LOCALE);
   ASSERT_EQ(EINVAL, errno);
   errno = 0;
-  wcstoll_l(L"123", nullptr, 1, LC_GLOBAL_LOCALE);
+  wcstoll_l(L"123", nullptr, 1, SAFE_LC_GLOBAL_LOCALE);
   ASSERT_EQ(EINVAL, errno);
   errno = 0;
-  wcstoll_l(L"123", nullptr, 37, LC_GLOBAL_LOCALE);
+  wcstoll_l(L"123", nullptr, 37, SAFE_LC_GLOBAL_LOCALE);
   ASSERT_EQ(EINVAL, errno);
 }
 
 TEST(wchar, wcstoull_l_EINVAL) {
   errno = 0;
-  wcstoull_l(L"123", nullptr, -1, LC_GLOBAL_LOCALE);
+  wcstoull_l(L"123", nullptr, -1, SAFE_LC_GLOBAL_LOCALE);
   ASSERT_EQ(EINVAL, errno);
   errno = 0;
-  wcstoull_l(L"123", nullptr, 1, LC_GLOBAL_LOCALE);
+  wcstoull_l(L"123", nullptr, 1, SAFE_LC_GLOBAL_LOCALE);
   ASSERT_EQ(EINVAL, errno);
   errno = 0;
-  wcstoull_l(L"123", nullptr, 37, LC_GLOBAL_LOCALE);
+  wcstoull_l(L"123", nullptr, 37, SAFE_LC_GLOBAL_LOCALE);
   ASSERT_EQ(EINVAL, errno);
 }
 
@@ -922,7 +1001,7 @@
 
 TEST(wchar, wcstod_l) {
 #if !defined(ANDROID_HOST_MUSL)
-  EXPECT_EQ(1.23, wcstod_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(1.23, wcstod_l(L"1.23", nullptr, SAFE_LC_GLOBAL_LOCALE));
 #else
   GTEST_SKIP() << "musl doesn't have wcstod_l";
 #endif
@@ -930,7 +1009,7 @@
 
 TEST(wchar, wcstof_l) {
 #if !defined(ANDROID_HOST_MUSL)
-  EXPECT_EQ(1.23f, wcstof_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(1.23f, wcstof_l(L"1.23", nullptr, SAFE_LC_GLOBAL_LOCALE));
 #else
   GTEST_SKIP() << "musl doesn't have wcstof_l";
 #endif
@@ -938,30 +1017,30 @@
 
 TEST(wchar, wcstol_l) {
 #if !defined(ANDROID_HOST_MUSL)
-  EXPECT_EQ(123L, wcstol_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(123L, wcstol_l(L"123", nullptr, 10, SAFE_LC_GLOBAL_LOCALE));
 #else
   GTEST_SKIP() << "musl doesn't have wcstol_l";
 #endif
 }
 
 TEST(wchar, wcstold_l) {
-  EXPECT_EQ(1.23L, wcstold_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(1.23L, wcstold_l(L"1.23", nullptr, SAFE_LC_GLOBAL_LOCALE));
 }
 
 TEST(wchar, wcstoll_l) {
-  EXPECT_EQ(123LL, wcstoll_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(123LL, wcstoll_l(L"123", nullptr, 10, SAFE_LC_GLOBAL_LOCALE));
 }
 
 TEST(wchar, wcstoul_l) {
 #if !defined(ANDROID_HOST_MUSL)
-  EXPECT_EQ(123UL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(123UL, wcstoul_l(L"123", nullptr, 10, SAFE_LC_GLOBAL_LOCALE));
 #else
   GTEST_SKIP() << "musl doesn't have wcstoul_l";
 #endif
 }
 
 TEST(wchar, wcstoull_l) {
-  EXPECT_EQ(123ULL, wcstoull_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(123ULL, wcstoull_l(L"123", nullptr, 10, SAFE_LC_GLOBAL_LOCALE));
 }
 
 static void AssertWcwidthRange(wchar_t begin, wchar_t end, int expected) {