Snap for 8562061 from 9f8e44f9ae19fc0f16fdb13ee8ecf81a3f41abb0 to mainline-media-release

Change-Id: I3751f602c5a31ceae9a95730caefc817c36756a3
diff --git a/OWNERS b/OWNERS
index 4cb95a3..670f88d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,11 +2,5 @@
 
 cferris@google.com
 danalbert@google.com
-hhb@google.com
-jmgao@google.com
 rprichard@google.com
-tomcherry@google.com
 yabinc@google.com
-
-# Still the best reviewer for changes related to the dynamic linker.
-dimitry@google.com
diff --git a/README.md b/README.md
index 388a139..f397fee 100644
--- a/README.md
+++ b/README.md
@@ -147,11 +147,11 @@
 The answer is "yes" if the system call is part of the POSIX standard.
 
 The answer is probably "yes" if the system call has a wrapper in at
-least one other C library.
+least one other C library (typically glibc/musl or Apple's libc).
 
 The answer may be "yes" if the system call has three/four distinct
-users in different projects, and there isn't a more specific library
-that would make more sense as the place to add the wrapper.
+users in different projects, and there isn't a more specific higher-level
+library that would make more sense as the place to add the wrapper.
 
 In all other cases, you should use
 [syscall(3)](http://man7.org/linux/man-pages/man2/syscall.2.html) instead.
@@ -166,14 +166,47 @@
      the appropriate POSIX header file in libc/include/ includes the
      relevant file or files.
   3. Add function declarations to the appropriate header file. Don't forget
-     to include the appropriate `__INTRODUCED_IN()`.
-  4. Add the function name to the correct section in libc/libc.map.txt.
-  5. Add at least basic tests. Even a test that deliberately supplies
-     an invalid argument helps check that we're generating the right symbol
-     and have the right declaration in the header file, and that you correctly
-     updated the maps in step 5. (You can use strace(1) to confirm that the
-     correct system call is being made.)
+     to include the appropriate `__INTRODUCED_IN()`. If you need to create a new
+     header file, libc/include/sys/sysinfo.h is a good short example to copy and
+     paste from.
+  4. Add basic documentation to the header file. libc/include/sys/sysinfo.h is a
+     good short example that shows the expected style. Most of the detail
+     should actually be left to the man7.org page, with only a brief
+     one-sentence explanation in our documentation. Alway include the return
+     value/error reporting details. Explicitly say which version of Android the
+     function was added to. Explicitly call out any Android-specific
+     changes/additions/limitations because they won't be on the man7.org page.
+  5. Add the function name to the correct section in libc/libc.map.txt.
+  6. Add a basic test. Don't try to test everything; concentrate on just testing
+     the code that's actually in *bionic*, not all the functionality that's
+     implemented in the kernel. For simple syscalls, that's just the
+     auto-generated argument and return value marshalling.
 
+     A trivial test that deliberately supplies an invalid argument helps check
+     that we're generating the right symbol and have the right declaration in
+     the header file, and that the change to libc.map.txt from step 5 is
+     correct. (You can use strace(1) manually to confirm that the correct
+     system call is being made.)
+
+     For testing the *kernel* side of things, we should prefer to rely on
+     https://github.com/linux-test-project/ltp for kernel testing, but you'll
+     want to check that external/ltp does contain tests for the syscall you're
+     adding. Also check that external/ltp is using the libc wrapper for the
+     syscall rather than calling it "directly" via syscall(3)!
+
+Some system calls are harder than others. The most common problem is a 64-bit
+argument such as `off64_t` (a *pointer* to a 64-bit argument is fine, since
+pointers are always the "natural" size for the architecture regardless of the
+size of the thing they point to). Whenever you have a function that takes
+`off_t` or `off64_t`, you'll need to consider whether you actually need a foo()
+and a foo64(), and whether they will use the same underlying system call or are
+implemented as two different system calls. It's usually easiest to find a
+similar system call and copy and paste from that. You'll definitely need to test
+both on 32-bit and 64-bit. (These special cases warrant more testing than the
+easy cases, even if only manual testing with strace. Sadly it isn't always
+feasible to write a working test for the interesting cases -- offsets larger
+than 2GiB, say -- so you may end up just writing a "meaningless" program whose
+only purpose is to give you patterns to look for when run under strace(1).)
 
 ## Updating kernel header files
 
@@ -271,39 +304,11 @@
 
     $ ./tests/run-on-host.sh glibc
 
-
 ## Gathering test coverage
 
-For either host or target coverage, you must first:
-
- * `$ export NATIVE_COVERAGE=true`
-     * Note that the build system is ignorant to this flag being toggled, i.e. if
-       you change this flag, you will have to manually rebuild bionic.
- * Set `bionic_coverage=true` in `libc/Android.mk` and `libm/Android.mk`.
-
-### Coverage from device tests
-
-    $ mma
-    $ adb sync
-    $ adb shell \
-        GCOV_PREFIX=/data/local/tmp/gcov \
-        GCOV_PREFIX_STRIP=`echo $ANDROID_BUILD_TOP | grep -o / | wc -l` \
-        /data/nativetest/bionic-unit-tests/bionic-unit-tests
-    $ acov
-
-`acov` will pull all coverage information from the device, push it to the right
-directories, run `lcov`, and open the coverage report in your browser.
-
-### Coverage from host tests
-
-First, build and run the host tests as usual (see above).
-
-    $ croot
-    $ lcov -c -d $ANDROID_PRODUCT_OUT -o coverage.info
-    $ genhtml -o covreport coverage.info # or lcov --list coverage.info
-
-The coverage report is now available at `covreport/index.html`.
-
+To get test coverage for bionic, use `//bionic/build/coverage.sh`. Before
+running, follow the instructions at the top of the file to rebuild bionic with
+coverage instrumentation.
 
 ## Attaching GDB to the tests
 
diff --git a/TEST_MAPPING b/TEST_MAPPING
index da16e65..2db0efe 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,9 +1,21 @@
 {
   "presubmit": [
     {
+      "name": "bionic-unit-tests"
+    },
+    {
+      "name": "bionic-unit-tests-static"
+    },
+    {
+      "name": "linker-unit-tests"
+    },
+    {
       "name": "CtsBionicTestCases"
     },
     {
+      "name": "CtsGwpAsanTestCases"
+    },
+    {
       "name": "CtsTaggingHostTestCases"
     },
     {
@@ -16,6 +28,9 @@
       "name": "gwp_asan_unittest"
     },
     {
+      "name": "malloc_debug_unit_tests"
+    },
+    {
       "name": "malloc_debug_system_tests"
     },
     {
@@ -24,5 +39,40 @@
     {
       "name": "memunreachable_unit_test"
     }
+  ],
+  "hwasan-presubmit": [
+    {
+      "name": "bionic-unit-tests"
+    },
+    {
+      "name": "bionic-unit-tests-static"
+    },
+    {
+      "name": "linker-unit-tests"
+    },
+    {
+      "name": "CtsBionicTestCases"
+    },
+    {
+      "name": "CtsGwpAsanTestCases"
+    },
+    {
+      "name": "debuggerd_test"
+    },
+    {
+      "name": "fdtrack_test"
+    },
+    {
+      "name": "gwp_asan_unittest"
+    },
+    {
+      "name": "malloc_debug_unit_tests"
+    },
+    {
+      "name": "malloc_debug_system_tests"
+    },
+    {
+      "name": "malloc_hooks_system_tests"
+    }
   ]
 }
diff --git a/apex/Android.bp b/apex/Android.bp
index 4879f47..90a14b2 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -58,7 +58,6 @@
         "bionic-linker-config",
     ],
     updatable: false,
-    generate_hashtree: false,
 }
 
 sdk {
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 856f150..6790c77 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -75,6 +75,7 @@
 }
 BIONIC_BENCHMARK(BM_pthread_mutex_lock);
 
+#if !defined(ANDROID_HOST_MUSL)
 static void BM_pthread_mutex_lock_ERRORCHECK(benchmark::State& state) {
   pthread_mutex_t mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 
@@ -84,7 +85,9 @@
   }
 }
 BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK);
+#endif
 
+#if !defined(ANDROID_HOST_MUSL)
 static void BM_pthread_mutex_lock_RECURSIVE(benchmark::State& state) {
   pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
@@ -94,6 +97,7 @@
   }
 }
 BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
+#endif
 
 namespace {
 struct PIMutex {
diff --git a/benchmarks/spawn/Android.bp b/benchmarks/spawn/Android.bp
index 89d22e3..61e7bf6 100644
--- a/benchmarks/spawn/Android.bp
+++ b/benchmarks/spawn/Android.bp
@@ -43,6 +43,9 @@
         linux_glibc_x86: {
             enabled: false,
         },
+        linux_musl_x86: {
+            enabled: false,
+        },
     },
 }
 
@@ -103,6 +106,11 @@
                 "-Wl,--rpath,${ORIGIN}/../../lib64",
             ],
         },
+        linux_musl_x86_64: {
+            ldflags: [
+                "-Wl,--rpath,${ORIGIN}/../../lib64",
+            ],
+        },
     },
 }
 
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
index b6ea58d..14b380a 100644
--- a/benchmarks/stdlib_benchmark.cpp
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -155,88 +155,71 @@
 BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_malloc_multiple_8192_allocs_decay1, "AT_SMALL_SIZES");
 #endif
 
-static void BM_stdlib_mbstowcs(benchmark::State& state) {
-  const size_t buf_alignment = state.range(0);
-  const size_t widebuf_alignment = state.range(1);
-
-  std::vector<char> buf;
-  std::vector<wchar_t> widebuf;
-
-  setlocale(LC_CTYPE, "C.UTF-8")
-  || setlocale(LC_CTYPE, "en_US.UTF-8")
-  || setlocale(LC_CTYPE, "en_GB.UTF-8")
-  || setlocale(LC_CTYPE, "en.UTF-8")
-  || setlocale(LC_CTYPE, "de_DE-8")
-  || setlocale(LC_CTYPE, "fr_FR-8");
-  if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
-    errx(1, "ERROR: unable to set locale in BM_stdlib_mbstowcs");
-  }
-
-  char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
-  wchar_t* widebuf_aligned = GetAlignedPtr(&widebuf, widebuf_alignment, 500000);
-  size_t i, j, k, l;
-  l = 0;
-  for (i=0xc3; i<0xe0; i++)
-    for (j=0x80; j<0xc0; j++)
-      buf[l++] = i, buf[l++] = j;
-  for (i=0xe1; i<0xed; i++)
-    for (j=0x80; j<0xc0; j++)
-      for (k=0x80; k<0xc0; k++)
-        buf[l++] = i, buf[l++] = j, buf[l++] = k;
-  for (i=0xf1; i<0xf4; i++)
-    for (j=0x80; j<0xc0; j++)
-      for (k=0x80; k<0xc0; k++)
-        buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
-  buf[l++] = 0;
+static void BM_stdlib_mbstowcs_ascii(benchmark::State& state) {
+  // It doesn't really matter what ASCII character we pick.
+  // The flow through the fast path is the same regardless.
+  const size_t count = 500000;
+  std::vector<char> mbs(count, 'e');
+  std::vector<wchar_t> wcs(count);
 
   for (auto _ : state) {
-    benchmark::DoNotOptimize(mbstowcs(widebuf_aligned, buf_aligned, 500000));
+    benchmark::DoNotOptimize(mbstowcs(&wcs[0], &mbs[0], wcs.size()));
   }
 
-  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(wcs.size()));
 }
-BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbstowcs, "0 0");
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbstowcs_ascii, "");
 
-static void BM_stdlib_mbrtowc(benchmark::State& state) {
-  const size_t buf_alignment = state.range(0);
-
-  std::vector<char> buf;
-
-  setlocale(LC_CTYPE, "C.UTF-8")
-  || setlocale(LC_CTYPE, "en_US.UTF-8")
-  || setlocale(LC_CTYPE, "en_GB.UTF-8")
-  || setlocale(LC_CTYPE, "en.UTF-8")
-  || setlocale(LC_CTYPE, "de_DE-8")
-  || setlocale(LC_CTYPE, "fr_FR-8");
-  if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
-    errx(1, "ERROR: unable to set locale in BM_stdlib_mbrtowc");
+static void BM_stdlib_mbstowcs_wide(benchmark::State& state) {
+  // It doesn't matter much what wide character we pick.
+  // A three-byte character seems pretty representative, and all three byte
+  // characters are the same from the code's perspective.
+  const size_t count = 500000;
+  std::string mbs;
+  for (size_t i = 0; i < count; i++) {
+    mbs += "\xe5\xb1\xb1";
   }
+  std::vector<wchar_t> wcs(count);
 
-  char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
-  size_t i, j, k, l;
-  l = 0;
-  for (i=0xc3; i<0xe0; i++)
-    for (j=0x80; j<0xc0; j++)
-      buf[l++] = i, buf[l++] = j;
-  for (i=0xe1; i<0xed; i++)
-    for (j=0x80; j<0xc0; j++)
-      for (k=0x80; k<0xc0; k++)
-        buf[l++] = i, buf[l++] = j, buf[l++] = k;
-  for (i=0xf1; i<0xf4; i++)
-    for (j=0x80; j<0xc0; j++)
-      for (k=0x80; k<0xc0; k++)
-        buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
-  buf[l++] = 0;
-
-  wchar_t wc = 0;
   for (auto _ : state) {
-    for (j = 0; buf_aligned[j]; j+=mbrtowc(&wc, buf_aligned + j, 4, nullptr)) {
-    }
+    benchmark::DoNotOptimize(mbstowcs(&wcs[0], &mbs[0], wcs.size()));
   }
 
-  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
+  state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(wcs.size()));
 }
-BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc, "0");
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbstowcs_wide, "");
+
+static void BM_stdlib_mbrtowc_1(benchmark::State& state) {
+  wchar_t wc;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(mbrtowc(&wc, "e", 1, nullptr));
+  }
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc_1, "");
+
+static void BM_stdlib_mbrtowc_2(benchmark::State& state) {
+  wchar_t wc;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(mbrtowc(&wc, "\xc3\x9f", 3, nullptr));
+  }
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc_2, "");
+
+static void BM_stdlib_mbrtowc_3(benchmark::State& state) {
+  wchar_t wc;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(mbrtowc(&wc, "\xe5\xb1\xb1", 3, nullptr));
+  }
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc_3, "");
+
+static void BM_stdlib_mbrtowc_4(benchmark::State& state) {
+  wchar_t wc;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(mbrtowc(&wc, "\xf0\xa4\xad\xa2", 4, nullptr));
+  }
+}
+BIONIC_BENCHMARK_WITH_ARG(BM_stdlib_mbrtowc_4, "");
 
 BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_atoi, atoi(" -123"));
 BIONIC_TRIVIAL_BENCHMARK(BM_stdlib_atol, atol(" -123"));
diff --git a/benchmarks/time_benchmark.cpp b/benchmarks/time_benchmark.cpp
index 437dc78..70cc662 100644
--- a/benchmarks/time_benchmark.cpp
+++ b/benchmarks/time_benchmark.cpp
@@ -22,6 +22,21 @@
 #include <benchmark/benchmark.h>
 #include "util.h"
 
+// Musl doesn't define __NR_gettimeofday, __NR_clock_gettime32, __NR_gettimeofday_time32 or
+// __NR_clock_getres on 32-bit architectures.
+#if !defined(__NR_gettimeofday)
+#define __NR_gettimeofday __NR_gettimeofday_time32
+#endif
+#if !defined(__NR_clock_gettime)
+#define __NR_clock_gettime __NR_clock_gettime32
+#endif
+#if !defined(__NR_gettimeofday)
+#define __NR_gettimeofday __NR_gettimeofday_time32
+#endif
+#if !defined(__NR_clock_getres)
+#define __NR_clock_getres __NR_clock_getres_time32
+#endif
+
 static void BM_time_clock_gettime(benchmark::State& state) {
   // CLOCK_MONOTONIC is required supported in vdso
   timespec t;
@@ -187,3 +202,13 @@
   }
 }
 BIONIC_BENCHMARK(BM_time_localtime_r);
+
+void BM_time_strftime(benchmark::State& state) {
+  char buf[128];
+  time_t t = 0;
+  struct tm* tm = gmtime(&t);
+  while (state.KeepRunning()) {
+    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
+  }
+}
+BIONIC_BENCHMARK(BM_time_strftime);
diff --git a/docs/EINTR.md b/docs/EINTR.md
new file mode 100644
index 0000000..8d1ab52
--- /dev/null
+++ b/docs/EINTR.md
@@ -0,0 +1,91 @@
+# EINTR
+
+## The problem
+
+If your code is blocked in a system call when a signal needs to be delivered,
+the kernel needs to interrupt that system call. For something like a read(2)
+call where some data has already been read, the call can just return with
+what data it has. (This is one reason why read(2) sometimes returns less data
+than you asked for, even though more data is available. It also explains why
+such behavior is relatively rare, and a cause of bugs.)
+
+But what if read(2) hasn't read any data yet? Or what if you've made some other
+system call, for which there is no equivalent "partial" success, such as
+poll(2)? In poll(2)'s case, there's either something to report (in which
+case the system call would already have returned), or there isn't.
+
+The kernel's solution to this problem is to return failure (-1) and set
+errno to `EINTR`: "interrupted system call".
+
+### Can I just opt out?
+
+Technically, yes. In practice on Android, no. Technically if a signal's
+disposition is set to ignore, the kernel doesn't even have to deliver the
+signal, so your code can just stay blocked in the system call it was already
+making. In practice, though, you can't guarantee that all signals are either
+ignored or will kill your process... Unless you're a small single-threaded
+C program that doesn't use any libraries, you can't realistically make this
+guarantee. If any code has installed a signal handler, you need to cope with
+`EINTR`. And if you're an Android app, the zygote has already installed a whole
+host of signal handlers before your code even starts to run. (And, no, you
+can't ignore them instead, because some of them are critical to how ART works.
+For example: Java `NullPointerException`s are optimized by trapping `SIGSEGV`
+signals so that the code generated by the JIT doesn't have to insert explicit
+null pointer checks.)
+
+### Why don't I see this in Java code?
+
+You won't see this in Java because the decision was taken to hide this issue
+from Java programmers. Basically, all the libraries like `java.io.*` and
+`java.net.*` hide this from you. (The same should be true of `android.*` too,
+so it's worth filing bugs if you find any exceptions that aren't documented!)
+
+### Why doesn't libc do that too?
+
+For most people, things would be easier if libc hid this implementation
+detail. But there are legitimate use cases, and automatically retrying
+would hide those. For example, you might want to use signals and `EINTR`
+to interrupt another thread (in fact, that's how interruption of threads
+doing I/O works in Java behind the scenes!). As usual, C/C++ choose the more
+powerful but more error-prone option.
+
+## The fix
+
+### Easy cases
+
+In most cases, the fix is simple: wrap the system call with the
+`TEMP_FAILURE_RETRY` macro. This is basically a while loop that retries the
+system call as long as the result is -1 and errno is `EINTR`.
+
+So, for example:
+```
+  n = read(fd, buf, buf_size); // BAD!
+  n = TEMP_FAILURE_RETRY(read(fd, buf, buf_size)); // GOOD!
+```
+
+### close(2)
+
+TL;DR: *never* wrap close(2) calls with `TEMP_FAILURE_RETRY`.
+
+The case of close(2) is complicated. POSIX explicitly says that close(2)
+shouldn't close the file descriptor if it returns `EINTR`, but that's *not*
+true on Linux (and thus on Android). See
+[Returning EINTR from close()](https://lwn.net/Articles/576478/)
+for more discussion.
+
+Given that most Android code (and especially "all apps") are multithreaded,
+retrying close(2) is especially dangerous because the file descriptor might
+already have been reused by another thread, so the "retry" succeeds, but
+actually closes a *different* file descriptor belonging to a *different*
+thread.
+
+### Timeouts
+
+System calls with timeouts are the other interesting case where "just wrap
+everything with `TEMP_FAILURE_RETRY()`" doesn't work. Because some amount of
+time will have elapsed, you'll want to recalculate the timeout. Otherwise you
+can end up with your 1 minute timeout being indefinite if you're receiving
+signals at least once per minute, say. In this case you'll want to do
+something like adding an explicit loop around your system call, calculating
+the timeout _inside_ the loop, and using `continue` each time the system call
+fails with `EINTR`.
diff --git a/docs/fdsan.md b/docs/fdsan.md
index e0cf80a..6630299 100644
--- a/docs/fdsan.md
+++ b/docs/fdsan.md
@@ -3,6 +3,8 @@
 [TOC]
 
 fdsan is a file descriptor sanitizer added to Android in API level 29.
+In API level 29, fdsan warns when it finds a bug.
+In API level 30, fdsan aborts when it finds a bug.
 
 ### Background
 *What problem is fdsan trying to solve? Why should I care?*
diff --git a/docs/status.md b/docs/status.md
index 9d3ad88..bf246a6 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -50,6 +50,21 @@
 
 Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
 
+New libc functions in T (API level 33):
+  * `backtrace`, `backtrace_symbols`, `backtrace_symbols_fd` (`<execinfo.h>`).
+  * New system call wrappers: `preadv2`, `preadv64v2`, `pwritev2`,
+    `pwritev64v2`.
+
+New libc functions in S (API level 31):
+  * New hooks for sanitizers for TLS access: `__libc_get_static_tls_bounds`,
+    `__libc_register_thread_exit_callback`, `__libc_iterate_dynamic_tls`,
+    `__libc_register_dynamic_tls_listeners`.
+  * New helper to allow the zygote to give each zygote child its own stack
+    cookie (currently unused): `android_reset_stack_guards`.
+  * Non-inline symbols for `ffsl`, `ffsll`.
+  * New system call wrappers: `pidfd_getfd`, `pidfd_open`, `pidfd_send_signal`,
+    `process_madvise`.
+
 New libc functions in R (API level 30):
   * Full C11 `<threads.h>` (available as inlines for older API levels).
   * `memfd_create` and `mlock2` (Linux-specific GNU extensions).
diff --git a/libc/Android.bp b/libc/Android.bp
index 2c0656f..97146aa 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -24,11 +24,11 @@
     "bionic/ether_aton.c",
     "bionic/ether_ntoa.c",
     "bionic/exit.cpp",
-    "bionic/fts.c",
     "bionic/initgroups.c",
     "bionic/isatty.c",
     "bionic/sched_cpualloc.c",
     "bionic/sched_cpucount.c",
+    "bionic/sysprop_helpers.cpp",
     "stdio/fmemopen.cpp",
     "stdio/parsefloat.c",
     "stdio/refill.c",
@@ -68,6 +68,13 @@
 
     // GWP-ASan requires platform TLS.
     "-fno-emulated-tls",
+
+    // We know clang does a lot of harm by rewriting what we've said, and sadly
+    // never see any good it does, so let's just ask it to do what we say...
+    // (The specific motivating example was clang turning a loop that would only
+    // ever touch 0, 1, or 2 bytes into a call to memset, which was never going
+    // to amortize.)
+    "-fno-builtin",
 ]
 
 // Define some common cflags
@@ -123,6 +130,10 @@
             cflags: ["-DUSE_SCUDO"],
         },
     },
+
+    lto: {
+        never: true,
+    },
 }
 
 libc_scudo_product_variables = {
@@ -565,6 +576,10 @@
         "upstream-openbsd/lib/libc/string/strxfrm.c",
         "upstream-openbsd/lib/libc/string/wcslcpy.c",
         "upstream-openbsd/lib/libc/string/wcswidth.c",
+
+        // This file is originally from OpenBSD, and benefits from
+        // being compiled with openbsd-compat.h.
+        "bionic/fts.c",
     ],
 
     cflags: [
@@ -1051,6 +1066,7 @@
         "bionic/error.cpp",
         "bionic/eventfd.cpp",
         "bionic/exec.cpp",
+        "bionic/execinfo.cpp",
         "bionic/faccessat.cpp",
         "bionic/fchmod.cpp",
         "bionic/fchmodat.cpp",
@@ -1118,6 +1134,7 @@
         "bionic/posix_fallocate.cpp",
         "bionic/posix_madvise.cpp",
         "bionic/posix_timers.cpp",
+        "bionic/preadv_pwritev.cpp",
         "bionic/ptrace.cpp",
         "bionic/pty.cpp",
         "bionic/raise.cpp",
@@ -1708,7 +1725,7 @@
                 // special for arm
                 cflags: ["-DCRT_LEGACY_WORKAROUND"],
                 // For backwards-compatibility, some arm32 builtins are exported from libc.so.
-                static_libs: ["libclang_rt.builtins-arm-android-exported"],
+                static_libs: ["libclang_rt.builtins-exported"],
             },
 
             // Arm 32 bit does not produce complete exidx unwind information
@@ -1738,7 +1755,7 @@
 
             shared: {
                 // For backwards-compatibility, some x86 builtins are exported from libc.so.
-                static_libs: ["libclang_rt.builtins-i686-android-exported"],
+                static_libs: ["libclang_rt.builtins-exported"],
             },
 
             // Leave the symbols in the shared library so that stack unwinders can produce
@@ -1777,12 +1794,12 @@
         "com.android.runtime",
     ],
 
-    // Sorting bss symbols by size usually results in less dirty pages at run
-    // time, because small symbols are grouped together.
-    sort_bss_symbols_by_size: true,
-
-    lto: {
-        never: true,
+    target: {
+        native_bridge: {
+            shared: {
+                installable: false,
+            },
+        },
     },
 }
 
@@ -1863,7 +1880,9 @@
 
 cc_library_headers {
     name: "libc_llndk_headers",
-    visibility: ["//visibility:private"],
+    visibility: [
+        "//external/musl",
+    ],
     llndk: {
         llndk_headers: true,
     },
@@ -1943,11 +1962,6 @@
         "//external/scudo",
         "//system/core/property_service/libpropertyinfoparser",
         "//system/extras/toolchain-extras",
-        // TODO(b/153662223): Clean up these users that needed visibility when
-        // the implicit addition of system Bionic paths was removed.
-        "//art/tools/cpp-define-generator",
-        "//external/boringssl",
-        "//external/minijail",
     ],
 
     stl: "none",
@@ -1988,8 +2002,12 @@
     static: {
         system_shared_libs: [],
     },
-    shared: {
-        system_shared_libs: ["libc"],
+    target: {
+        bionic: {
+            shared: {
+                system_shared_libs: ["libc"],
+            },
+        },
     },
 
     //TODO (dimitry): This is to work around b/24465209. Remove after root cause is fixed
@@ -2051,7 +2069,7 @@
 // ========================================================
 
 cc_defaults {
-    name: "crt_defaults",
+    name: "crt_and_memtag_defaults",
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
     product_available: true,
@@ -2078,6 +2096,12 @@
 }
 
 cc_defaults {
+    name: "crt_defaults",
+    defaults: ["crt_and_memtag_defaults"],
+    system_shared_libs: [],
+}
+
+cc_defaults {
     name: "crt_so_defaults",
     defaults: ["crt_defaults"],
 
@@ -2204,7 +2228,7 @@
     },
     sdk_version: "minimum",
 
-    defaults: ["crt_defaults"],
+    defaults: ["crt_and_memtag_defaults"],
 }
 
 cc_library_static {
@@ -2216,7 +2240,7 @@
     },
     sdk_version: "minimum",
 
-    defaults: ["crt_defaults"],
+    defaults: ["crt_and_memtag_defaults"],
 }
 
 // ========================================================
@@ -2301,6 +2325,8 @@
     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,
 }
 
 ndk_library {
@@ -2528,6 +2554,154 @@
     },
 }
 
-subdirs = [
-    "bionic/scudo",
-]
+cc_library_host_static {
+    name: "libfts",
+    srcs: [
+        "bionic/fts.c",
+        "upstream-openbsd/lib/libc/stdlib/recallocarray.c",
+    ],
+    export_include_dirs: ["fts/include"],
+    local_include_dirs: [
+        "private",
+        "upstream-openbsd/android/include",
+    ],
+    cflags: [
+        "-include openbsd-compat.h",
+        "-Wno-unused-parameter",
+    ],
+    enabled: false,
+    target: {
+        musl: {
+            enabled: true,
+        },
+    },
+    stl: "none",
+}
+
+cc_library_host_static {
+    name: "libexecinfo",
+    visibility: ["//external/musl"],
+    srcs: ["bionic/execinfo.cpp"],
+    export_include_dirs: ["execinfo/include"],
+    local_include_dirs: ["private"],
+    enabled: false,
+    target: {
+        musl: {
+            enabled: true,
+            system_shared_libs: [],
+            header_libs: ["libc_musl_headers"],
+        },
+    },
+    stl: "none",
+}
+
+cc_library_host_static {
+    name: "libb64",
+    visibility: ["//external/musl"],
+    srcs: ["upstream-openbsd/lib/libc/net/base64.c"],
+    export_include_dirs: ["b64/include"],
+    local_include_dirs: [
+        "private",
+        "upstream-openbsd/android/include",
+    ],
+    cflags: [
+        "-include openbsd-compat.h",
+    ],
+    enabled: false,
+    target: {
+        musl: {
+            enabled: true,
+            system_shared_libs: [],
+            header_libs: ["libc_musl_headers"],
+        },
+    },
+    stl: "none",
+}
+
+// Export kernel uapi headers to be used in the musl sysroot.
+// Also include the execinfo headers for the libexecinfo and the
+// b64 headers for libb64 embedded in musl libc.
+cc_genrule {
+    name: "libc_musl_sysroot_bionic_headers",
+    visibility: ["//external/musl"],
+    host_supported: true,
+    device_supported: false,
+    enabled: false,
+    target: {
+        musl: {
+            enabled: true,
+        },
+    },
+    srcs: [
+        "kernel/uapi/**/*.h",
+        "kernel/android/**/*.h",
+        "execinfo/include/**/*.h",
+        "b64/include/**/*.h",
+
+        "NOTICE",
+
+        ":libc_musl_sysroot_bionic_arch_headers",
+    ],
+    out: ["libc_musl_sysroot_bionic_headers.zip"],
+    tools: [
+        "soong_zip",
+        "merge_zips",
+        "zip2zip",
+    ],
+    cmd: "BIONIC_LIBC_DIR=$$(dirname $(location NOTICE)) && " +
+        "$(location soong_zip) -o $(genDir)/sysroot.zip -symlinks=false" +
+        // NOTICE
+        " -j -f $(location NOTICE) " +
+        // headers
+        " -P include " +
+        "  -C $${BIONIC_LIBC_DIR}/kernel/uapi " +
+        "  -D $${BIONIC_LIBC_DIR}/kernel/uapi " +
+        "  -C $${BIONIC_LIBC_DIR}/kernel/android/scsi " +
+        "  -D $${BIONIC_LIBC_DIR}/kernel/android/scsi " +
+        "  -C $${BIONIC_LIBC_DIR}/kernel/android/uapi " +
+        "  -D $${BIONIC_LIBC_DIR}/kernel/android/uapi " +
+        "  -C $${BIONIC_LIBC_DIR}/execinfo/include " +
+        "  -D $${BIONIC_LIBC_DIR}/execinfo/include " +
+        "  -C $${BIONIC_LIBC_DIR}/b64/include " +
+        "  -D $${BIONIC_LIBC_DIR}/b64/include " +
+        " && " +
+        "$(location zip2zip) -i $(genDir)/sysroot.zip -o $(genDir)/sysroot-renamed.zip " +
+        " include/**/*:include/ " +
+        " NOTICE:NOTICE.bionic " +
+        " && " +
+        "$(location merge_zips) $(out) $(location :libc_musl_sysroot_bionic_arch_headers) $(genDir)/sysroot-renamed.zip",
+}
+
+// The architecture-specific bits have to be handled separately because the label varies based
+// on architecture, which prevents using $(locations) to find them and requires using $(in)
+// instead, which would mix in all the other files if this were part of the main libc_musl_sysroot
+// genrule.
+cc_genrule {
+    name: "libc_musl_sysroot_bionic_arch_headers",
+    visibility: ["//visibility:private"],
+    host_supported: true,
+    device_supported: false,
+    enabled: false,
+    target: {
+        musl: {
+            enabled: true,
+        },
+    },
+    arch: {
+        arm: {
+            srcs: ["kernel/uapi/asm-arm/**/*.h"],
+        },
+        arm64: {
+            srcs: ["kernel/uapi/asm-arm64/**/*.h"],
+        },
+        x86: {
+            srcs: ["kernel/uapi/asm-x86/**/*.h"],
+        },
+        x86_64: {
+            srcs: ["kernel/uapi/asm-x86/**/*.h"],
+        },
+    },
+    out: ["libc_musl_sysroot_bionic_arch_headers.zip"],
+    tools: ["soong_zip"],
+    cmd: "includes=($(in)) && $(location soong_zip) -o $(out) -P include/asm -j -D $$(dirname $${includes[0]})",
+}
diff --git a/libc/NOTICE b/libc/NOTICE
index 26fef05..9cbbde2 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -855,22 +855,6 @@
 -------------------------------------------------------------------
 
 Copyright (C) 2020 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
--------------------------------------------------------------------
-
-Copyright (C) 2020 The Android Open Source Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -926,6 +910,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2022 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1980, 1983, 1988, 1993
    The Regents of the University of California.  All rights reserved.
 
diff --git a/libc/SECCOMP_ALLOWLIST_COMMON.TXT b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
index 6650d7e..0366fdf 100644
--- a/libc/SECCOMP_ALLOWLIST_COMMON.TXT
+++ b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
@@ -31,6 +31,8 @@
 int open:open(const char*, int, ...)  arm,x86,x86_64
 int stat64:stat64(const char*, struct stat64*)  arm,x86
 ssize_t readlink:readlink(const char*, char*, size_t)  arm,x86,x86_64
+# Needed by ubsan in T? (http://b/229989971)
+int stat(const char*, struct stat*)  arm,x86,x86_64
 
 #
 # Useful new syscalls which we don't yet use in bionic.
@@ -74,3 +76,5 @@
 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.9, used by POSIX_SPAWN_CLOEXEC_DEFAULT
+int close_range(unsigned int, unsigned int, int) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 391e7af..a09c614 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -97,13 +97,14 @@
 ssize_t     pwrite64|pwrite(int, void*, size_t, off_t) lp64
 
 # On LP32, preadv/pwritev don't use off64_t --- they use pairs of 32-bit
-# arguments to avoid problems on architectures like ARM where 64-bit arguments
+# arguments to avoid problems on architectures like arm32 where 64-bit arguments
 # must be in a register pair starting with an even-numbered register.
 # See linux/fs/read_write.c and https://lwn.net/Articles/311630/.
-ssize_t     __preadv64:preadv(int, const struct iovec*, int, long, long) lp32
-ssize_t     preadv|preadv64(int, const struct iovec*, int, off_t) lp64
-ssize_t     __pwritev64:pwritev(int, const struct iovec*, int, long, long) lp32
-ssize_t     pwritev|pwritev64(int, const struct iovec*, int, off_t) lp64
+# Note that there's an unused always-0 second long even on LP64!
+ssize_t     __preadv64:preadv(int, const struct iovec*, int, long, long) all
+ssize_t     __pwritev64:pwritev(int, const struct iovec*, int, long, long) all
+ssize_t     __preadv64v2:preadv2(int, const struct iovec*, int, long, long, int) all
+ssize_t     __pwritev64v2:pwritev2(int, const struct iovec*, int, long, long, int) all
 
 int         __close:close(int)  all
 pid_t       __getpid:getpid()  all
@@ -148,7 +149,7 @@
 int __fchmodat:fchmodat(int, const char*, mode_t)  all
 int fchownat(int, const char*, uid_t, gid_t, int)  all
 int fstatat64|fstatat:fstatat64(int, const char*, struct stat*, int)   lp32
-int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)  arm64,x86_64
+int fstatat64|fstatat:newfstatat(int, const char*, struct stat*, int)  lp64
 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
@@ -192,8 +193,8 @@
 int __statfs64:statfs64(const char*, size_t, struct statfs*)  lp32
 int __statfs:statfs(const char*, struct statfs*)  lp64
 
-int     fstat64|fstat:fstat64(int, struct stat*)    lp32
-int     fstat64|fstat:fstat(int, struct stat*)    arm64,x86_64
+int fstat64|fstat:fstat64(int, struct stat*) lp32
+int fstat64|fstat:fstat(int, struct stat*) lp64
 
 # file system
 int     chdir(const char*)              all
@@ -305,6 +306,8 @@
 int     sysinfo(struct sysinfo*)  all
 int     personality(unsigned long)  all
 
+int     bpf(int, union bpf_attr *, unsigned int) all
+
 ssize_t tee(int, int, size_t, unsigned int)  all
 ssize_t splice(int, off64_t*, int, off64_t*, size_t, unsigned int)  all
 ssize_t vmsplice(int, const struct iovec*, size_t, unsigned int)  all
@@ -338,7 +341,7 @@
 int setdomainname(const char*, size_t)  all
 int sethostname(const char*, size_t)  all
 
-int __sync_file_range:sync_file_range(int, off64_t, off64_t, unsigned int) arm64,x86,x86_64
+int __sync_file_range:sync_file_range(int, off64_t, off64_t, unsigned int) x86,lp64
 int __sync_file_range2:sync_file_range2(int, unsigned int, off64_t, off64_t) arm
 
 pid_t wait4(pid_t, int*, int, struct rusage*)  all
diff --git a/libc/arch-arm/bionic/kuser_helper_on.S b/libc/arch-arm/bionic/kuser_helper_on.S
index 2a1d86d..08291f7 100644
--- a/libc/arch-arm/bionic/kuser_helper_on.S
+++ b/libc/arch-arm/bionic/kuser_helper_on.S
@@ -32,10 +32,10 @@
   .balign 4
   .type kuser_helper_on, %object
 kuser_helper_on:
-  .long 2f-1f         // int32_t namesz
-  .long 3f-2f         // int32_t descsz
-  .long NT_TYPE_KUSER // int32_t type
-1:.ascii "Android\0"  // char name[]
-2:.long 1             // int32_t on
+  .long 2f-1f                 // int32_t namesz
+  .long 3f-2f                 // int32_t descsz
+  .long NT_ANDROID_TYPE_KUSER // int32_t type
+1:.ascii "Android\0"          // char name[]
+2:.long 1                     // int32_t on
 3:
   .size kuser_helper_on, .-kuser_helper_on
diff --git a/libc/arch-arm64/bionic/note_memtag_heap_async.S b/libc/arch-arm64/bionic/note_memtag_heap_async.S
index 208115c..931f40b 100644
--- a/libc/arch-arm64/bionic/note_memtag_heap_async.S
+++ b/libc/arch-arm64/bionic/note_memtag_heap_async.S
@@ -33,11 +33,11 @@
 
   .section ".note.android.memtag", "a", %note
   .p2align 2
-  .long 1f - 0f         // int32_t namesz
-  .long 3f - 2f         // int32_t descsz
-  .long NT_TYPE_MEMTAG  // int32_t type
+  .long 1f - 0f                 // int32_t namesz
+  .long 3f - 2f                 // int32_t descsz
+  .long NT_ANDROID_TYPE_MEMTAG  // int32_t type
 0:
-  .asciz "Android"      // char name[]
+  .asciz "Android"              // char name[]
 1:
   .p2align 2
 2:
diff --git a/libc/arch-arm64/bionic/note_memtag_heap_sync.S b/libc/arch-arm64/bionic/note_memtag_heap_sync.S
index d71ad02..77ab03a 100644
--- a/libc/arch-arm64/bionic/note_memtag_heap_sync.S
+++ b/libc/arch-arm64/bionic/note_memtag_heap_sync.S
@@ -33,11 +33,11 @@
 
   .section ".note.android.memtag", "a", %note
   .p2align 2
-  .long 1f - 0f         // int32_t namesz
-  .long 3f - 2f         // int32_t descsz
-  .long NT_TYPE_MEMTAG  // int32_t type
+  .long 1f - 0f                 // int32_t namesz
+  .long 3f - 2f                 // int32_t descsz
+  .long NT_ANDROID_TYPE_MEMTAG  // int32_t type
 0:
-  .asciz "Android"      // char name[]
+  .asciz "Android"              // char name[]
 1:
   .p2align 2
 2:
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index 5f681c5..9b8ad4e 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -55,7 +55,7 @@
 #elif defined(__i386__)
 __asm__(PRE
         "xorl %ebp,%ebp; movl %esp,%eax; andl $~0xf,%esp; subl $12,%esp; pushl %eax;"
-        "calll _start_main" POST);
+        "call _start_main" POST);
 #elif defined(__x86_64__)
 __asm__(PRE "xorl %ebp, %ebp; movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST);
 #else
diff --git a/libc/arch-common/bionic/crtbrand.S b/libc/arch-common/bionic/crtbrand.S
index 307ef2e..b7540e9 100644
--- a/libc/arch-common/bionic/crtbrand.S
+++ b/libc/arch-common/bionic/crtbrand.S
@@ -40,7 +40,7 @@
 abitag:
   .long 2f-1f                 // int32_t namesz
   .long 3f-2f                 // int32_t descsz
-  .long NT_TYPE_IDENT         // int32_t type
+  .long NT_ANDROID_TYPE_IDENT // int32_t type
 #ifdef __ANDROID__
 1:.ascii "Android\0"          // char name[]
 2:.long PLATFORM_SDK_VERSION  // int32_t android_api
diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp
index e4a5837..531317d 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -36,6 +36,7 @@
         "com.android.art.debug",
         "com.android.media",
         "com.android.media.swcodec",
+        "com.android.virt",
     ],
     min_sdk_version: "apex_inherit",
 }
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 8b2a32b..2380e68 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -251,6 +251,7 @@
     char sign = '\0';
     int width = -1;
     int prec = -1;
+    bool alternate = false;
     size_t bytelen = sizeof(int);
     int slen;
     char buffer[32]; /* temporary buffer used to format numbers */
@@ -293,6 +294,9 @@
       } else if (c == ' ' || c == '+') {
         sign = c;
         continue;
+      } else if (c == '#') {
+        alternate = true;
+        continue;
       }
       break;
     }
@@ -344,9 +348,6 @@
     if (c == 's') {
       /* string */
       str = va_arg(args, const char*);
-      if (str == nullptr) {
-        str = "(null)";
-      }
     } else if (c == 'c') {
       /* character */
       /* NOTE: char is promoted to int when passed through the stack */
@@ -357,6 +358,9 @@
       buffer[0] = '0';
       buffer[1] = 'x';
       format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
+    } else if (c == 'm') {
+      char buf[256];
+      str = strerror_r(errno, buf, sizeof(buf));
     } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
       /* integers - first read value from stack */
       uint64_t value;
@@ -388,8 +392,19 @@
         value = static_cast<uint64_t>((static_cast<int64_t>(value << shift)) >> shift);
       }
 
-      /* format the number properly into our buffer */
-      format_integer(buffer, sizeof(buffer), value, c);
+      if (alternate && value != 0 && (c == 'x' || c == 'o')) {
+        if (c == 'x') {
+          buffer[0] = '0';
+          buffer[1] = 'x';
+          format_integer(buffer + 2, sizeof(buffer) - 2, value, c);
+        } else {
+          buffer[0] = '0';
+          format_integer(buffer + 1, sizeof(buffer) - 1, value, c);
+        }
+      } else {
+        /* format the number properly into our buffer */
+        format_integer(buffer, sizeof(buffer), value, c);
+      }
     } else if (c == '%') {
       buffer[0] = '%';
       buffer[1] = '\0';
@@ -397,6 +412,10 @@
       __assert(__FILE__, __LINE__, "conversion specifier unsupported");
     }
 
+    if (str == nullptr) {
+      str = "(null)";
+    }
+
     /* if we are here, 'str' points to the content that must be
      * outputted. handle padding and alignment now */
 
diff --git a/libc/b64/include/bionic/b64.h b/libc/b64/include/bionic/b64.h
new file mode 100644
index 0000000..f365bae
--- /dev/null
+++ b/libc/b64/include/bionic/b64.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+int b64_ntop(unsigned char const* __src, size_t __src_size, char* __dst, size_t __dst_size);
+int b64_pton(char const* __src, u_char* __dst, size_t __dst_size);
+
+__END_DECLS
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 9d92a6d..3460a6d 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -33,6 +33,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <string.h>
+#include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -68,8 +69,6 @@
   // does not get loaded for a) non-apps, b) non-profilable apps on user. The default signal
   // disposition is to crash. We do not want the target to crash if we accidentally target a
   // non-app or non-profilable process.
-  //
-  // This does *not* get run for processes that statically link libc, and those will still crash.
   signal(BIONIC_SIGNAL_ART_PROFILER, SIG_IGN);
 }
 
@@ -139,13 +138,25 @@
     return;
   }
 
+  // If the process is undumpable, /proc/self/mem will be owned by root:root, and therefore
+  // inaccessible to the process itself (see man 5 proc). We temporarily mark the process as
+  // dumpable to allow for the open. Note: prctl is not async signal safe per posix, but bionic's
+  // implementation is. Error checking on prctls is omitted due to them being trivial.
+  int orig_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+  if (!orig_dumpable) {
+    prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+  }
   ScopedFd maps_fd{ open("/proc/self/maps", O_RDONLY | O_CLOEXEC) };
+  ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) };
+  if (!orig_dumpable) {
+    prctl(PR_SET_DUMPABLE, orig_dumpable, 0, 0, 0);
+  }
+
   if (maps_fd.get() == -1) {
     async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %s",
                           strerror(errno));
     return;
   }
-  ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) };
   if (mem_fd.get() == -1) {
     async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %s",
                           strerror(errno));
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 2ea12ee..d5f8cb9 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -77,6 +77,10 @@
     return;
   }
 
+  if (msg == nullptr) {
+    msg = "(null)";
+  }
+
   size_t size = sizeof(magic_abort_msg_t) + strlen(msg) + 1;
   void* map = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
   if (map == MAP_FAILED) {
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index fd97712..227cb84 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -20,8 +20,10 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "bionic/pthread_internal.h"
 #include "private/bionic_lock.h"
 #include "private/bionic_systrace.h"
+#include "private/bionic_tls.h"
 #include "private/CachedProperty.h"
 
 #include <async_safe/log.h>
@@ -55,7 +57,7 @@
   return g_trace_marker_fd;
 }
 
-void bionic_trace_begin(const char* message) {
+static void trace_begin_internal(const char* message) {
   if (!should_trace()) {
     return;
   }
@@ -76,7 +78,22 @@
   TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len));
 }
 
-void bionic_trace_end() {
+void bionic_trace_begin(const char* message) {
+  // Some functions called by trace_begin_internal() can call
+  // bionic_trace_begin(). Prevent infinite recursion and non-recursive mutex
+  // deadlock by using a flag in the thread local storage.
+  bionic_tls& tls = __get_bionic_tls();
+  if (tls.bionic_systrace_disabled) {
+    return;
+  }
+  tls.bionic_systrace_disabled = true;
+
+  trace_begin_internal(message);
+
+  tls.bionic_systrace_disabled = false;
+}
+
+static void trace_end_internal() {
   if (!should_trace()) {
     return;
   }
@@ -86,7 +103,36 @@
     return;
   }
 
-  TEMP_FAILURE_RETRY(write(trace_marker_fd, "E|", 2));
+  // This code is intentionally "sub-optimal"; do not optimize this by inlining
+  // the E| string into the write.
+  //
+  // This is because if the const char* string passed to write(trace_marker) is not
+  // in resident memory (e.g. the page of the .rodata section that contains it has
+  // been paged out, or the anonymous page that contained a heap-based string is
+  // swapped in zram), the ftrace code will NOT page it in and instead report
+  // <faulted>.
+  //
+  // We "fix" this by putting the string on the stack, which is more unlikely
+  // to be paged out and pass the pointer to that instead.
+  //
+  // See b/197620214 for more context on this.
+  volatile char buf[2]{'E', '|'};
+  TEMP_FAILURE_RETRY(write(trace_marker_fd, const_cast<const char*>(buf), 2));
+}
+
+void bionic_trace_end() {
+  // Some functions called by trace_end_internal() can call
+  // bionic_trace_begin(). Prevent infinite recursion and non-recursive mutex
+  // deadlock by using a flag in the thread local storage.
+  bionic_tls& tls = __get_bionic_tls();
+  if (tls.bionic_systrace_disabled) {
+    return;
+  }
+  tls.bionic_systrace_disabled = true;
+
+  trace_end_internal();
+
+  tls.bionic_systrace_disabled = false;
 }
 
 ScopedTrace::ScopedTrace(const char* message) : called_end_(false) {
diff --git a/libc/bionic/c16rtomb.cpp b/libc/bionic/c16rtomb.cpp
index 2d6ae93..e052d04 100644
--- a/libc/bionic/c16rtomb.cpp
+++ b/libc/bionic/c16rtomb.cpp
@@ -43,7 +43,7 @@
 size_t c16rtomb(char* s, char16_t c16, mbstate_t* ps) {
   static mbstate_t __private_state;
   mbstate_t* state = (ps == nullptr) ? &__private_state : ps;
-  if (mbsinit(state)) {
+  if (mbstate_is_initial(state)) {
     if (is_high_surrogate(c16)) {
       char32_t c32 = (c16 & ~0xd800) << 10;
       mbstate_set_byte(state, 3, (c32 & 0xff0000) >> 16);
diff --git a/libc/bionic/c32rtomb.cpp b/libc/bionic/c32rtomb.cpp
index 2909d8b..4fa76ff 100644
--- a/libc/bionic/c32rtomb.cpp
+++ b/libc/bionic/c32rtomb.cpp
@@ -50,7 +50,7 @@
     return mbstate_reset_and_return(1, state);
   }
 
-  if (!mbsinit(state)) {
+  if (!mbstate_is_initial(state)) {
     return mbstate_reset_and_return_illegal(EILSEQ, state);
   }
 
@@ -66,10 +66,8 @@
   // about the sequence length.
   uint8_t lead;
   size_t length;
-  if ((c32 & ~0x7f) == 0) {
-    lead = 0;
-    length = 1;
-  } else if ((c32 & ~0x7ff) == 0) {
+  // We already handled the 1-byte case above, so we go straight to 2-bytes...
+  if ((c32 & ~0x7ff) == 0) {
     lead = 0xc0;
     length = 2;
   } else if ((c32 & ~0xffff) == 0) {
diff --git a/libc/bionic/execinfo.cpp b/libc/bionic/execinfo.cpp
new file mode 100644
index 0000000..d129f7c
--- /dev/null
+++ b/libc/bionic/execinfo.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012 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 <dlfcn.h>
+#include <execinfo.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <unwind.h>
+
+#include "private/ScopedFd.h"
+
+struct StackState {
+  void** frames;
+  int frame_count;
+  int cur_frame = 0;
+
+  StackState(void** frames, int frame_count) : frames(frames), frame_count(frame_count) {}
+};
+
+static _Unwind_Reason_Code TraceFunction(_Unwind_Context* context, void* arg) {
+  // The instruction pointer is pointing at the instruction after the return
+  // call on all architectures.
+  // Modify the pc to point at the real function.
+  uintptr_t ip = _Unwind_GetIP(context);
+  if (ip != 0) {
+#if defined(__arm__)
+    // If the ip is suspiciously low, do nothing to avoid a segfault trying
+    // to access this memory.
+    if (ip >= 4096) {
+      // Check bits [15:11] of the first halfword assuming the instruction
+      // is 32 bits long. If the bits are any of these values, then our
+      // assumption was correct:
+      //  b11101
+      //  b11110
+      //  b11111
+      // Otherwise, this is a 16 bit instruction.
+      uint16_t value = (*reinterpret_cast<uint16_t*>(ip - 2)) >> 11;
+      if (value == 0x1f || value == 0x1e || value == 0x1d) {
+        ip -= 4;
+      } else {
+        ip -= 2;
+      }
+    }
+#elif defined(__aarch64__)
+    // All instructions are 4 bytes long, skip back one instruction.
+    ip -= 4;
+#elif defined(__i386__) || defined(__x86_64__)
+    // It's difficult to decode exactly where the previous instruction is,
+    // so subtract 1 to estimate where the instruction lives.
+    ip--;
+#endif
+  }
+
+  StackState* state = static_cast<StackState*>(arg);
+  state->frames[state->cur_frame++] = reinterpret_cast<void*>(ip);
+  return (state->cur_frame >= state->frame_count) ? _URC_END_OF_STACK : _URC_NO_REASON;
+}
+
+int backtrace(void** buffer, int size) {
+  if (size <= 0) {
+    return 0;
+  }
+
+  StackState state(buffer, size);
+  _Unwind_Backtrace(TraceFunction, &state);
+  return state.cur_frame;
+}
+
+char** backtrace_symbols(void* const* buffer, int size) {
+  if (size <= 0) {
+    return nullptr;
+  }
+  // Do this calculation first in case the user passes in a bad value.
+  size_t ptr_size;
+  if (__builtin_mul_overflow(sizeof(char*), size, &ptr_size)) {
+    return nullptr;
+  }
+
+  ScopedFd fd(memfd_create("backtrace_symbols_fd", MFD_CLOEXEC));
+  if (fd.get() == -1) {
+    return nullptr;
+  }
+  backtrace_symbols_fd(buffer, size, fd.get());
+
+  // Get the size of the file.
+  off_t file_size = lseek(fd.get(), 0, SEEK_END);
+  if (file_size <= 0) {
+    return nullptr;
+  }
+
+  // The interface for backtrace_symbols indicates that only the single
+  // returned pointer must be freed by the caller. Therefore, allocate a
+  // buffer that includes the memory for the strings and all of the pointers.
+  // Add one byte at the end just in case the file didn't end with a '\n'.
+  size_t symbol_data_size;
+  if (__builtin_add_overflow(ptr_size, file_size, &symbol_data_size) ||
+      __builtin_add_overflow(symbol_data_size, 1, &symbol_data_size)) {
+    return nullptr;
+  }
+
+  uint8_t* symbol_data = reinterpret_cast<uint8_t*>(malloc(symbol_data_size));
+  if (symbol_data == nullptr) {
+    return nullptr;
+  }
+
+  // Copy the string data into the buffer.
+  char* cur_string = reinterpret_cast<char*>(&symbol_data[ptr_size]);
+  // If this fails, the read won't read back the correct number of bytes.
+  lseek(fd.get(), 0, SEEK_SET);
+  ssize_t num_read = read(fd.get(), cur_string, file_size);
+  fd.reset(-1);
+  if (num_read != file_size) {
+    free(symbol_data);
+    return nullptr;
+  }
+
+  // Make sure the last character in the file is '\n'.
+  if (cur_string[file_size] != '\n') {
+    cur_string[file_size++] = '\n';
+  }
+
+  for (int i = 0; i < size; i++) {
+    (reinterpret_cast<char**>(symbol_data))[i] = cur_string;
+    cur_string = strchr(cur_string, '\n');
+    if (cur_string == nullptr) {
+      free(symbol_data);
+      return nullptr;
+    }
+    cur_string[0] = '\0';
+    cur_string++;
+  }
+  return reinterpret_cast<char**>(symbol_data);
+}
+
+// This function should do no allocations if possible.
+void backtrace_symbols_fd(void* const* buffer, int size, int fd) {
+  if (size <= 0 || fd < 0) {
+    return;
+  }
+
+  for (int frame_num = 0; frame_num < size; frame_num++) {
+    void* address = buffer[frame_num];
+    Dl_info info;
+    if (dladdr(address, &info) != 0) {
+      if (info.dli_fname != nullptr) {
+        write(fd, info.dli_fname, strlen(info.dli_fname));
+      }
+      if (info.dli_sname != nullptr) {
+        dprintf(fd, "(%s+0x%" PRIxPTR ") ", info.dli_sname,
+                reinterpret_cast<uintptr_t>(address) - reinterpret_cast<uintptr_t>(info.dli_saddr));
+      } else {
+        dprintf(fd, "(+%p) ", info.dli_saddr);
+      }
+    }
+
+    dprintf(fd, "[%p]\n", address);
+  }
+}
diff --git a/libc/bionic/faccessat.cpp b/libc/bionic/faccessat.cpp
index bfaec51..1f38107 100644
--- a/libc/bionic/faccessat.cpp
+++ b/libc/bionic/faccessat.cpp
@@ -48,10 +48,10 @@
     // More details at http://permalink.gmane.org/gmane.linux.lib.musl.general/6952
     //
     // AT_EACCESS isn't supported either. Android doesn't have setuid
-    // programs, and never runs code with euid!=uid. It could be
-    // implemented in an expensive way, following the model at
-    // https://gitlab.com/bminor/musl/commit/0a05eace163cee9b08571d2ff9d90f5e82d9c228
-    // but not worth it.
+    // programs, and never runs code with euid!=uid.
+    //
+    // We could use faccessat2(2) from Linux 5.8, but since we don't want the
+    // first feature and don't need the second, we just reject such requests.
     errno = EINVAL;
     return -1;
   }
diff --git a/libc/bionic/fts.c b/libc/bionic/fts.c
index 77b4117..1287267 100644
--- a/libc/bionic/fts.c
+++ b/libc/bionic/fts.c
@@ -54,11 +54,6 @@
 static u_short	 fts_stat(FTS *, FTSENT *, int, int);
 static int	 fts_safe_changedir(FTS *, FTSENT *, int, const char *);
 
-/* Android: OpenBSD source compatibility workarounds. */
-#include "private/bsd_sys_param.h"
-#define DEF_WEAK(s) /* nothing */
-void* recallocarray(void*, size_t, size_t, size_t);
-
 #define	ISDOT(a)	(a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
 
 #define	CLR(opt)	(sp->fts_options &= ~(opt))
@@ -452,7 +447,7 @@
  * reasons.
  */
 int
-fts_set(FTS *sp __unused, FTSENT *p, int instr)
+fts_set(FTS *sp, FTSENT *p, int instr)
 {
 	if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
 	    instr != FTS_NOINSTR && instr != FTS_SKIP) {
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index 6eb1749..7e19b31 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -26,21 +26,27 @@
  * SUCH DAMAGE.
  */
 
-#include <platform/bionic/android_unsafe_frame_pointer_chase.h>
-#include <platform/bionic/malloc.h>
-#include <private/bionic_arc4random.h>
-#include <private/bionic_globals.h>
-#include <private/bionic_malloc_dispatch.h>
+#include <alloca.h>
+#include <assert.h>
+#include <ctype.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 
-#include "bionic/gwp_asan_wrappers.h"
 #include "gwp_asan/guarded_pool_allocator.h"
 #include "gwp_asan/options.h"
+#include "gwp_asan_wrappers.h"
 #include "malloc_common.h"
+#include "platform/bionic/android_unsafe_frame_pointer_chase.h"
+#include "platform/bionic/malloc.h"
+#include "private/bionic_arc4random.h"
+#include "private/bionic_globals.h"
+#include "private/bionic_malloc_dispatch.h"
+#include "sys/system_properties.h"
+#include "sysprop_helpers.h"
 
 #ifndef LIBC_STATIC
 #include "bionic/malloc_common_dynamic.h"
@@ -49,59 +55,14 @@
 static gwp_asan::GuardedPoolAllocator GuardedAlloc;
 static const MallocDispatch* prev_dispatch;
 
+using Action = android_mallopt_gwp_asan_options_t::Action;
 using Options = gwp_asan::options::Options;
 
-// ============================================================================
-// Implementation of gFunctions.
-// ============================================================================
+// basename() is a mess, see the manpage. Let's be explicit what handling we
+// want (don't touch my string!).
+extern "C" const char* __gnu_basename(const char* path);
 
-// This function handles initialisation as asked for by MallocInitImpl. This
-// should always be called in a single-threaded context.
-bool gwp_asan_initialize(const MallocDispatch* dispatch, bool*, const char*) {
-  prev_dispatch = dispatch;
-
-  Options Opts;
-  Opts.Enabled = true;
-  Opts.MaxSimultaneousAllocations = 32;
-  Opts.SampleRate = 2500;
-  Opts.InstallSignalHandlers = false;
-  Opts.InstallForkHandlers = true;
-  Opts.Backtrace = android_unsafe_frame_pointer_chase;
-
-  GuardedAlloc.init(Opts);
-  // TODO(b/149790891): The log line below causes ART tests to fail as they're
-  // not expecting any output. Disable the output for now.
-  // info_log("GWP-ASan has been enabled.");
-
-  __libc_shared_globals()->gwp_asan_state = GuardedAlloc.getAllocatorState();
-  __libc_shared_globals()->gwp_asan_metadata = GuardedAlloc.getMetadataRegion();
-  return true;
-}
-
-void gwp_asan_finalize() {
-}
-
-void gwp_asan_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*) {
-}
-
-void gwp_asan_free_malloc_leak_info(uint8_t*) {
-}
-
-ssize_t gwp_asan_malloc_backtrace(void*, uintptr_t*, size_t) {
-  // TODO(mitchp): GWP-ASan might be able to return the backtrace for the
-  // provided address.
-  return -1;
-}
-
-bool gwp_asan_write_malloc_leak_info(FILE*) {
-  return false;
-}
-
-void* gwp_asan_gfunctions[] = {
-  (void*)gwp_asan_initialize,           (void*)gwp_asan_finalize,
-  (void*)gwp_asan_get_malloc_leak_info, (void*)gwp_asan_free_malloc_leak_info,
-  (void*)gwp_asan_malloc_backtrace,     (void*)gwp_asan_write_malloc_leak_info,
-};
+namespace {
 
 // ============================================================================
 // Implementation of GWP-ASan malloc wrappers.
@@ -144,10 +105,21 @@
 }
 
 void* gwp_asan_realloc(void* old_mem, size_t bytes) {
+  // GPA::pointerIsMine(p) always returns false where `p == nullptr` (and thus
+  // malloc(bytes) is requested). We always fall back to the backing allocator,
+  // technically missing some coverage, but reducing an extra conditional
+  // branch.
   if (__predict_false(GuardedAlloc.pointerIsMine(old_mem))) {
-    size_t old_size = GuardedAlloc.getSize(old_mem);
+    if (__predict_false(bytes == 0)) {
+      GuardedAlloc.deallocate(old_mem);
+      return nullptr;
+    }
     void* new_ptr = gwp_asan_malloc(bytes);
-    if (new_ptr) memcpy(new_ptr, old_mem, (bytes < old_size) ? bytes : old_size);
+    // If malloc() fails, then don't destroy the old memory.
+    if (__predict_false(new_ptr == nullptr)) return nullptr;
+
+    size_t old_size = GuardedAlloc.getSize(old_mem);
+    memcpy(new_ptr, old_mem, (bytes < old_size) ? bytes : old_size);
     GuardedAlloc.deallocate(old_mem);
     return new_ptr;
   }
@@ -175,66 +147,202 @@
   prev_dispatch->malloc_enable();
 }
 
-static const MallocDispatch gwp_asan_dispatch __attribute__((unused)) = {
-  gwp_asan_calloc,
-  gwp_asan_free,
-  Malloc(mallinfo),
-  gwp_asan_malloc,
-  gwp_asan_malloc_usable_size,
-  Malloc(memalign),
-  Malloc(posix_memalign),
+const MallocDispatch gwp_asan_dispatch __attribute__((unused)) = {
+    gwp_asan_calloc,
+    gwp_asan_free,
+    Malloc(mallinfo),
+    gwp_asan_malloc,
+    gwp_asan_malloc_usable_size,
+    Malloc(memalign),
+    Malloc(posix_memalign),
 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  Malloc(pvalloc),
+    Malloc(pvalloc),
 #endif
-  gwp_asan_realloc,
+    gwp_asan_realloc,
 #if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-  Malloc(valloc),
+    Malloc(valloc),
 #endif
-  gwp_asan_malloc_iterate,
-  gwp_asan_malloc_disable,
-  gwp_asan_malloc_enable,
-  Malloc(mallopt),
-  Malloc(aligned_alloc),
-  Malloc(malloc_info),
+    gwp_asan_malloc_iterate,
+    gwp_asan_malloc_disable,
+    gwp_asan_malloc_enable,
+    Malloc(mallopt),
+    Malloc(aligned_alloc),
+    Malloc(malloc_info),
 };
 
-// The probability (1 / kProcessSampleRate) that a process will be ranodmly
-// selected for sampling. kProcessSampleRate should always be a power of two to
-// avoid modulo bias.
-static constexpr uint8_t kProcessSampleRate = 128;
+bool isPowerOfTwo(uint64_t x) {
+  assert(x != 0);
+  return (x & (x - 1)) == 0;
+}
 
-bool ShouldGwpAsanSampleProcess() {
+bool ShouldGwpAsanSampleProcess(unsigned sample_rate) {
+  if (!isPowerOfTwo(sample_rate)) {
+    warning_log(
+        "GWP-ASan process sampling rate of %u is not a power-of-two, and so modulo bias occurs.",
+        sample_rate);
+  }
+
   uint8_t random_number;
   __libc_safe_arc4random_buf(&random_number, sizeof(random_number));
-  return random_number % kProcessSampleRate == 0;
+  return random_number % sample_rate == 0;
 }
 
-bool MaybeInitGwpAsanFromLibc(libc_globals* globals) {
-  // Never initialize the Zygote here. A Zygote chosen for sampling would also
-  // have all of its children sampled. Instead, the Zygote child will choose
-  // whether it samples or not just after the Zygote forks. For
-  // libc_scudo-preloaded executables (like mediaswcodec), the program name
-  // might not be available yet. The zygote never uses dynamic libc_scudo.
-  const char* progname = getprogname();
-  if (progname && strncmp(progname, "app_process", 11) == 0) {
+bool GwpAsanInitialized = false;
+
+// The probability (1 / SampleRate) that an allocation gets chosen to be put
+// into the special GWP-ASan pool.
+using SampleRate_t = typeof(gwp_asan::options::Options::SampleRate);
+constexpr SampleRate_t kDefaultSampleRate = 2500;
+static const char* kSampleRateSystemSysprop = "libc.debug.gwp_asan.sample_rate.system_default";
+static const char* kSampleRateAppSysprop = "libc.debug.gwp_asan.sample_rate.app_default";
+static const char* kSampleRateTargetedSyspropPrefix = "libc.debug.gwp_asan.sample_rate.";
+static const char* kSampleRateEnvVar = "GWP_ASAN_SAMPLE_RATE";
+
+// The probability (1 / ProcessSampling) that a process will be randomly
+// selected for sampling, for system apps and system processes. The process
+// sampling rate should always be a power of two to avoid modulo bias.
+constexpr unsigned kDefaultProcessSampling = 128;
+static const char* kProcessSamplingSystemSysprop =
+    "libc.debug.gwp_asan.process_sampling.system_default";
+static const char* kProcessSamplingAppSysprop = "libc.debug.gwp_asan.process_sampling.app_default";
+static const char* kProcessSamplingTargetedSyspropPrefix = "libc.debug.gwp_asan.process_sampling.";
+static const char* kProcessSamplingEnvVar = "GWP_ASAN_PROCESS_SAMPLING";
+
+// The upper limit of simultaneous allocations supported by GWP-ASan. Any
+// allocations in excess of this limit will be passed to the backing allocator
+// and can't be sampled. This value, if unspecified, will be automatically
+// calculated to keep the same ratio as the default (2500 sampling : 32 allocs).
+// So, if you specify GWP_ASAN_SAMPLE_RATE=1250 (i.e. twice as frequent), we'll
+// automatically calculate that we need double the slots (64).
+using SimultaneousAllocations_t = typeof(gwp_asan::options::Options::MaxSimultaneousAllocations);
+constexpr SimultaneousAllocations_t kDefaultMaxAllocs = 32;
+static const char* kMaxAllocsSystemSysprop = "libc.debug.gwp_asan.max_allocs.system_default";
+static const char* kMaxAllocsAppSysprop = "libc.debug.gwp_asan.max_allocs.app_default";
+static const char* kMaxAllocsTargetedSyspropPrefix = "libc.debug.gwp_asan.max_allocs.";
+static const char* kMaxAllocsEnvVar = "GWP_ASAN_MAX_ALLOCS";
+
+void SetDefaultGwpAsanOptions(Options* options, unsigned* process_sample_rate,
+                              const android_mallopt_gwp_asan_options_t& mallopt_options) {
+  options->Enabled = true;
+  options->InstallSignalHandlers = false;
+  options->InstallForkHandlers = true;
+  options->Backtrace = android_unsafe_frame_pointer_chase;
+  options->SampleRate = kDefaultSampleRate;
+  options->MaxSimultaneousAllocations = kDefaultMaxAllocs;
+
+  *process_sample_rate = 1;
+  if (mallopt_options.desire == Action::TURN_ON_WITH_SAMPLING) {
+    *process_sample_rate = kDefaultProcessSampling;
+  }
+}
+
+bool GetGwpAsanOption(unsigned long long* result,
+                      const android_mallopt_gwp_asan_options_t& mallopt_options,
+                      const char* system_sysprop, const char* app_sysprop,
+                      const char* targeted_sysprop_prefix, const char* env_var,
+                      const char* descriptive_name) {
+  const char* basename = "";
+  if (mallopt_options.program_name) basename = __gnu_basename(mallopt_options.program_name);
+
+  size_t program_specific_sysprop_size = strlen(targeted_sysprop_prefix) + strlen(basename) + 1;
+  char* program_specific_sysprop_name = static_cast<char*>(alloca(program_specific_sysprop_size));
+  async_safe_format_buffer(program_specific_sysprop_name, program_specific_sysprop_size, "%s%s",
+                           targeted_sysprop_prefix, basename);
+
+  const char* sysprop_names[2] = {nullptr, nullptr};
+  // Tests use a blank program name to specify that system properties should not
+  // be used. Tests still continue to use the environment variable though.
+  if (*basename != '\0') {
+    sysprop_names[0] = program_specific_sysprop_name;
+    if (mallopt_options.desire == Action::TURN_ON_FOR_APP) {
+      sysprop_names[1] = app_sysprop;
+    } else {
+      sysprop_names[1] = system_sysprop;
+    }
+  }
+
+  char settings_buf[PROP_VALUE_MAX];
+  if (!get_config_from_env_or_sysprops(env_var, sysprop_names,
+                                       /* sys_prop_names_size */ 2, settings_buf, PROP_VALUE_MAX)) {
     return false;
   }
-  return MaybeInitGwpAsan(globals);
+
+  char* end;
+  unsigned long long value = strtoull(settings_buf, &end, 10);
+  if (value == ULLONG_MAX || *end != '\0') {
+    warning_log("Invalid GWP-ASan %s: \"%s\". Using default value instead.", descriptive_name,
+                settings_buf);
+    return false;
+  }
+
+  *result = value;
+  return true;
 }
 
-static bool GwpAsanInitialized = false;
+// Initialize the GWP-ASan options structure in *options, taking into account whether someone has
+// asked for specific GWP-ASan settings. The order of priority is:
+//  1. Environment variables.
+//  2. Process-specific system properties.
+//  3. Global system properties.
+// If any of these overrides are found, we return true. Otherwise, use the default values, and
+// return false.
+bool GetGwpAsanOptions(Options* options, unsigned* process_sample_rate,
+                       const android_mallopt_gwp_asan_options_t& mallopt_options) {
+  SetDefaultGwpAsanOptions(options, process_sample_rate, mallopt_options);
 
-// Maybe initializes GWP-ASan. Called by android_mallopt() and libc's
-// initialisation. This should always be called in a single-threaded context.
-bool MaybeInitGwpAsan(libc_globals* globals, bool force_init) {
+  bool had_overrides = false;
+
+  unsigned long long buf;
+  if (GetGwpAsanOption(&buf, mallopt_options, kSampleRateSystemSysprop, kSampleRateAppSysprop,
+                       kSampleRateTargetedSyspropPrefix, kSampleRateEnvVar, "sample rate")) {
+    options->SampleRate = buf;
+    had_overrides = true;
+  }
+
+  if (GetGwpAsanOption(&buf, mallopt_options, kProcessSamplingSystemSysprop,
+                       kProcessSamplingAppSysprop, kProcessSamplingTargetedSyspropPrefix,
+                       kProcessSamplingEnvVar, "process sampling rate")) {
+    *process_sample_rate = buf;
+    had_overrides = true;
+  }
+
+  if (GetGwpAsanOption(&buf, mallopt_options, kMaxAllocsSystemSysprop, kMaxAllocsAppSysprop,
+                       kMaxAllocsTargetedSyspropPrefix, kMaxAllocsEnvVar,
+                       "maximum simultaneous allocations")) {
+    options->MaxSimultaneousAllocations = buf;
+    had_overrides = true;
+  } else if (had_overrides) {
+    // Multiply the number of slots available, such that the ratio between
+    // sampling rate and slots is kept the same as the default. For example, a
+    // sampling rate of 1000 is 2.5x more frequent than default, and so
+    // requires 80 slots (32 * 2.5).
+    float frequency_multiplier = static_cast<float>(options->SampleRate) / kDefaultSampleRate;
+    options->MaxSimultaneousAllocations =
+        /* default */ kDefaultMaxAllocs / frequency_multiplier;
+  }
+  return had_overrides;
+}
+
+bool MaybeInitGwpAsan(libc_globals* globals,
+                      const android_mallopt_gwp_asan_options_t& mallopt_options) {
   if (GwpAsanInitialized) {
     error_log("GWP-ASan was already initialized for this process.");
     return false;
   }
 
-  // If the caller hasn't forced GWP-ASan on, check whether we should sample
-  // this process.
-  if (!force_init && !ShouldGwpAsanSampleProcess()) {
+  Options options;
+  unsigned process_sample_rate = kDefaultProcessSampling;
+  if (!GetGwpAsanOptions(&options, &process_sample_rate, mallopt_options) &&
+      mallopt_options.desire == Action::DONT_TURN_ON_UNLESS_OVERRIDDEN) {
+    return false;
+  }
+
+  if (options.SampleRate == 0 || process_sample_rate == 0 ||
+      options.MaxSimultaneousAllocations == 0) {
+    return false;
+  }
+
+  if (!ShouldGwpAsanSampleProcess(process_sample_rate)) {
     return false;
   }
 
@@ -263,17 +371,48 @@
     atomic_store(&globals->current_dispatch_table, &gwp_asan_dispatch);
   }
 
-#ifndef LIBC_STATIC
-  SetGlobalFunctions(gwp_asan_gfunctions);
-#endif  // LIBC_STATIC
-
   GwpAsanInitialized = true;
 
-  gwp_asan_initialize(NativeAllocatorDispatch(), nullptr, nullptr);
+  prev_dispatch = NativeAllocatorDispatch();
+
+  GuardedAlloc.init(options);
+
+  __libc_shared_globals()->gwp_asan_state = GuardedAlloc.getAllocatorState();
+  __libc_shared_globals()->gwp_asan_metadata = GuardedAlloc.getMetadataRegion();
 
   return true;
 }
+};  // anonymous namespace
+
+bool MaybeInitGwpAsanFromLibc(libc_globals* globals) {
+  // Never initialize the Zygote here. A Zygote chosen for sampling would also
+  // have all of its children sampled. Instead, the Zygote child will choose
+  // whether it samples or not just after the Zygote forks. Note that the Zygote
+  // changes its name after it's started, at this point it's still called
+  // "app_process" or "app_process64".
+  static const char kAppProcessNamePrefix[] = "app_process";
+  const char* progname = getprogname();
+  if (strncmp(progname, kAppProcessNamePrefix, sizeof(kAppProcessNamePrefix) - 1) == 0)
+    return false;
+
+  android_mallopt_gwp_asan_options_t mallopt_options;
+  mallopt_options.program_name = progname;
+  mallopt_options.desire = Action::TURN_ON_WITH_SAMPLING;
+
+  return MaybeInitGwpAsan(globals, mallopt_options);
+}
 
 bool DispatchIsGwpAsan(const MallocDispatch* dispatch) {
   return dispatch == &gwp_asan_dispatch;
 }
+
+bool EnableGwpAsan(const android_mallopt_gwp_asan_options_t& options) {
+  if (GwpAsanInitialized) {
+    return true;
+  }
+
+  bool ret_value;
+  __libc_globals.mutate(
+      [&](libc_globals* globals) { ret_value = MaybeInitGwpAsan(globals, options); });
+  return ret_value;
+}
diff --git a/libc/bionic/gwp_asan_wrappers.h b/libc/bionic/gwp_asan_wrappers.h
index a39d50b..219da9f 100644
--- a/libc/bionic/gwp_asan_wrappers.h
+++ b/libc/bionic/gwp_asan_wrappers.h
@@ -28,16 +28,20 @@
 
 #pragma once
 
-#include <private/bionic_globals.h>
-#include <private/bionic_malloc_dispatch.h>
 #include <stddef.h>
 
+#include "gwp_asan/options.h"
+#include "platform/bionic/malloc.h"
+#include "private/bionic_globals.h"
+#include "private/bionic_malloc_dispatch.h"
+
+// Enable GWP-ASan, used by android_mallopt. Should always be called in a
+// single-threaded context.
+bool EnableGwpAsan(const android_mallopt_gwp_asan_options_t& options);
+
 // Hooks for libc to possibly install GWP-ASan.
 bool MaybeInitGwpAsanFromLibc(libc_globals* globals);
 
-// Maybe initialize GWP-ASan. Set force_init to true to bypass process sampling.
-bool MaybeInitGwpAsan(libc_globals* globals, bool force_init = false);
-
 // Returns whether GWP-ASan is the provided dispatch table pointer. Used in
 // heapprofd's signal-initialization sequence to determine the intermediate
 // dispatch pointer to use when initing.
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
index 1536333..0c80f4e 100644
--- a/libc/bionic/ifaddrs.cpp
+++ b/libc/bionic/ifaddrs.cpp
@@ -306,12 +306,9 @@
 
   // Open the netlink socket and ask for all the links and addresses.
   NetlinkConnection nc;
-  // SELinux policy only allows RTM_GETLINK messages to be sent by:
-  // - System apps
-  // - Apps with a target SDK version lower than R
+  // SELinux policy only allows RTM_GETLINK messages to be sent by system apps.
   bool getlink_success = false;
-  if (getuid() < FIRST_APPLICATION_UID ||
-      android_get_application_target_sdk_version() < __ANDROID_API_R__) {
+  if (getuid() < FIRST_APPLICATION_UID) {
     getlink_success = nc.SendRequest(RTM_GETLINK) && nc.ReadResponses(__getifaddrs_callback, out);
   }
   bool getaddr_success =
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index f08e582..41108e6 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -45,8 +45,6 @@
 
 // System calls we need.
 extern "C" int __llseek(int, unsigned long, unsigned long, off64_t*, int);
-extern "C" int __preadv64(int, const struct iovec*, int, long, long);
-extern "C" int __pwritev64(int, const struct iovec*, int, long, long);
 
 // For lseek64 we need to use the llseek system call which splits the off64_t in two and
 // returns the off64_t result via a pointer because 32-bit kernels can't return 64-bit results.
@@ -70,23 +68,6 @@
   return pwrite64(fd, buf, byte_count, static_cast<off64_t>(offset));
 }
 
-// On LP32, there is no off_t preadv/pwritev, and even the 64-bit preadv/pwritev
-// don't use off64_t (see SYSCALLS.TXT for more). Here, this means that we need
-// to implement all four functions because the two system calls don't match any
-// of the userspace functions. Unlike llseek, the pair is split lo-hi, not hi-lo.
-ssize_t preadv(int fd, const struct iovec* ios, int count, off_t offset) {
-  return preadv64(fd, ios, count, offset);
-}
-ssize_t preadv64(int fd, const struct iovec* ios, int count, off64_t offset) {
-  return __preadv64(fd, ios, count, offset, offset >> 32);
-}
-ssize_t pwritev(int fd, const struct iovec* ios, int count, off_t offset) {
-  return pwritev64(fd, ios, count, offset);
-}
-ssize_t pwritev64(int fd, const struct iovec* ios, int count, off64_t offset) {
-  return __pwritev64(fd, ios, count, offset, offset >> 32);
-}
-
 // There is no fallocate for 32-bit off_t, so we need to widen and call fallocate64.
 int fallocate(int fd, int mode, off_t offset, off_t length) {
   return fallocate64(fd, mode, static_cast<off64_t>(offset), static_cast<off64_t>(length));
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index dd623a5..8084e73 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -149,50 +149,25 @@
   _exit(EXIT_FAILURE);
 }
 
-// Force any of the closed stdin, stdout and stderr to be associated with /dev/null.
+// Force any of the stdin/stdout/stderr file descriptors that aren't
+// open to be associated with /dev/null.
 static void __nullify_closed_stdio() {
-  int dev_null = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
-  if (dev_null == -1) {
-    // init won't have /dev/null available, but SELinux provides an equivalent.
-    dev_null = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR));
-  }
-  if (dev_null == -1) {
-    __early_abort(__LINE__);
-  }
-
-  // If any of the stdio file descriptors is valid and not associated
-  // with /dev/null, dup /dev/null to it.
   for (int i = 0; i < 3; i++) {
-    // If it is /dev/null already, we are done.
-    if (i == dev_null) {
-      continue;
-    }
+    if (TEMP_FAILURE_RETRY(fcntl(i, F_GETFL)) == -1) {
+      // The only error we allow is that the file descriptor does not exist.
+      if (errno != EBADF) __early_abort(__LINE__);
 
-    // Is this fd already open?
-    int status = TEMP_FAILURE_RETRY(fcntl(i, F_GETFL));
-    if (status != -1) {
-      continue;
-    }
-
-    // The only error we allow is that the file descriptor does not
-    // exist, in which case we dup /dev/null to it.
-    if (errno == EBADF) {
-      // Try dupping /dev/null to this stdio file descriptor and
-      // repeat if there is a signal. Note that any errors in closing
-      // the stdio descriptor are lost.
-      status = TEMP_FAILURE_RETRY(dup2(dev_null, i));
-      if (status == -1) {
+      // This file descriptor wasn't open, so open /dev/null.
+      // init won't have /dev/null available, but SELinux provides an equivalent.
+      // This takes advantage of the fact that open() will take the lowest free
+      // file descriptor, and we're iterating in order from 0, but we'll
+      // double-check we got the right fd anyway...
+      int fd;
+      if (((fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR))) == -1 &&
+           (fd = TEMP_FAILURE_RETRY(open("/sys/fs/selinux/null", O_RDWR))) == -1) ||
+          fd != i) {
         __early_abort(__LINE__);
       }
-    } else {
-      __early_abort(__LINE__);
-    }
-  }
-
-  // If /dev/null is not one of the stdio file descriptors, close it.
-  if (dev_null > 2) {
-    if (close(dev_null) == -1) {
-      __early_abort(__LINE__);
     }
   }
 }
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 4625fa1..24efbf5 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -93,6 +93,15 @@
   __libc_init_common();
   __libc_init_scudo();
 
+#if __has_feature(hwaddress_sanitizer)
+  // Notify the HWASan runtime library whenever a library is loaded or unloaded
+  // so that it can update its shadow memory.
+  // This has to happen before _libc_init_malloc which might dlopen to load
+  // profiler libraries.
+  __libc_shared_globals()->load_hook = __hwasan_library_loaded;
+  __libc_shared_globals()->unload_hook = __hwasan_library_unloaded;
+#endif
+
   // Hooks for various libraries to let them know that we're starting up.
   __libc_globals.mutate(__libc_init_malloc);
 
@@ -101,13 +110,6 @@
 
   __libc_init_fork_handler();
 
-#if __has_feature(hwaddress_sanitizer)
-  // Notify the HWASan runtime library whenever a library is loaded or unloaded
-  // so that it can update its shadow memory.
-  __libc_shared_globals()->load_hook = __hwasan_library_loaded;
-  __libc_shared_globals()->unload_hook = __hwasan_library_unloaded;
-#endif
-
   __libc_shared_globals()->set_target_sdk_version_hook = __libc_set_target_sdk_version;
 
   netdClientInit();
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 3a8513f..575da62 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -38,10 +38,12 @@
 
 #include "libc_init_common.h"
 #include "pthread_internal.h"
+#include "sysprop_helpers.h"
 
 #include "platform/bionic/macros.h"
 #include "platform/bionic/mte.h"
 #include "platform/bionic/page.h"
+#include "platform/bionic/reserved_signals.h"
 #include "private/KernelArgumentBlock.h"
 #include "private/bionic_asm.h"
 #include "private/bionic_asm_note.h"
@@ -163,41 +165,20 @@
   layout.finish_layout();
 }
 
-// Get the presiding config string, in the following order of priority:
-//   1. Environment variables.
-//   2. System properties, in the order they're specified in sys_prop_names.
-// If neither of these options are specified, this function returns false.
-// Otherwise, it returns true, and the presiding options string is written to
-// the `options` buffer of size `size`. If this function returns true, `options`
-// is guaranteed to be null-terminated. `options_size` should be at least
-// PROP_VALUE_MAX.
-bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const* sys_prop_names,
-                                     size_t sys_prop_names_size, char* options,
-                                     size_t options_size) {
-  const char* env = getenv(env_var_name);
-  if (env && *env != '\0') {
-    strncpy(options, env, options_size);
-    options[options_size - 1] = '\0'; // Ensure null-termination.
-    return true;
-  }
-
-  for (size_t i = 0; i < sys_prop_names_size; ++i) {
-    if (__system_property_get(sys_prop_names[i], options) && *options != '\0') return true;
-  }
-  return false;
-}
-
 #ifdef __aarch64__
 static bool __read_memtag_note(const ElfW(Nhdr)* note, const char* name, const char* desc,
                                unsigned* result) {
+  if (note->n_type != NT_ANDROID_TYPE_MEMTAG) {
+    return false;
+  }
   if (note->n_namesz != 8 || strncmp(name, "Android", 8) != 0) {
     return false;
   }
-  if (note->n_type != NT_TYPE_MEMTAG) {
-    return false;
-  }
-  if (note->n_descsz != 4) {
-    async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected 4", note->n_descsz);
+  // Previously (in Android 12), if the note was != 4 bytes, we check-failed
+  // here. Let's be more permissive to allow future expansion.
+  if (note->n_descsz < 4) {
+    async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected >= 4",
+                     note->n_descsz);
   }
   *result = *reinterpret_cast<const ElfW(Word)*>(desc);
   return true;
@@ -236,6 +217,7 @@
 // level into *level.
 static bool get_environment_memtag_setting(HeapTaggingLevel* level) {
   static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process.";
+  static const char kMemtagGlobalSysprop[] = "persist.arm64.memtag.default";
 
   const char* progname = __libc_shared_globals()->init_progname;
   if (progname == nullptr) return false;
@@ -249,9 +231,10 @@
 
   async_safe_format_buffer(sysprop_name, sysprop_size, "%s%s", kMemtagPrognameSyspropPrefix,
                            basename);
+  const char* sys_prop_names[] = {sysprop_name, kMemtagGlobalSysprop};
 
-  if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", &sysprop_name,
-                                       /* sys_prop_names_size */ 1, options_str, kOptionsSize)) {
+  if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", sys_prop_names, arraysize(sys_prop_names),
+                                       options_str, kOptionsSize)) {
     return false;
   }
 
@@ -282,21 +265,29 @@
 
   unsigned note_val =
       __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
-  if (note_val & ~(NT_MEMTAG_LEVEL_MASK | NT_MEMTAG_HEAP)) {
-    async_safe_fatal("unrecognized android.memtag note: desc = %d", note_val);
-  }
 
+  // Note, previously (in Android 12), any value outside of bits [0..3] resulted
+  // in a check-fail. In order to be permissive of further extensions, we
+  // relaxed this restriction. For now, we still only support MTE heap.
   if (!(note_val & NT_MEMTAG_HEAP)) return M_HEAP_TAGGING_LEVEL_TBI;
 
-  unsigned memtag_level = note_val & NT_MEMTAG_LEVEL_MASK;
-  switch (memtag_level) {
+  unsigned mode = note_val & NT_MEMTAG_LEVEL_MASK;
+  switch (mode) {
+    case NT_MEMTAG_LEVEL_NONE:
+      // Note, previously (in Android 12), NT_MEMTAG_LEVEL_NONE was
+      // NT_MEMTAG_LEVEL_DEFAULT, which implied SYNC mode. This was never used
+      // by anyone, but we note it (heh) here for posterity, in case the zero
+      // level becomes meaningful, and binaries with this note can be executed
+      // on Android 12 devices.
+      return M_HEAP_TAGGING_LEVEL_TBI;
     case NT_MEMTAG_LEVEL_ASYNC:
       return M_HEAP_TAGGING_LEVEL_ASYNC;
-    case NT_MEMTAG_LEVEL_DEFAULT:
     case NT_MEMTAG_LEVEL_SYNC:
-      return M_HEAP_TAGGING_LEVEL_SYNC;
     default:
-      async_safe_fatal("unrecognized android.memtag note: level = %d", memtag_level);
+      // We allow future extensions to specify mode 3 (currently unused), with
+      // the idea that it might be used for ASYMM mode or something else. On
+      // this version of Android, it falls back to SYNC mode.
+      return M_HEAP_TAGGING_LEVEL_SYNC;
   }
 }
 
@@ -331,6 +322,15 @@
 void __libc_init_mte(const void*, size_t, uintptr_t) {}
 #endif  // __aarch64__
 
+void __libc_init_profiling_handlers() {
+  // The dynamic variant of this function is more interesting, but this
+  // at least ensures that static binaries aren't killed by the kernel's
+  // default disposition for these two real-time signals that would have
+  // handlers installed if this was a dynamic binary.
+  signal(BIONIC_SIGNAL_PROFILER, SIG_IGN);
+  signal(BIONIC_SIGNAL_ART_PROFILER, SIG_IGN);
+}
+
 __noreturn static void __real_libc_init(void *raw_args,
                                         void (*onexit)(void) __unused,
                                         int (*slingshot)(int, char**, char**),
@@ -351,6 +351,7 @@
   __libc_init_mte(reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR)), getauxval(AT_PHNUM),
                   /*load_bias = */ 0);
   __libc_init_scudo();
+  __libc_init_profiling_handlers();
   __libc_init_fork_handler();
 
   call_ifunc_resolvers();
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index c91efa0..9744968 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -326,13 +326,12 @@
     return LimitEnable(arg, arg_size);
   }
   if (opcode == M_INITIALIZE_GWP_ASAN) {
-    if (arg == nullptr || arg_size != sizeof(bool)) {
+    if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) {
       errno = EINVAL;
       return false;
     }
-    __libc_globals.mutate([&](libc_globals* globals) {
-      return MaybeInitGwpAsan(globals, *reinterpret_cast<bool*>(arg));
-    });
+
+    return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
   }
   errno = ENOTSUP;
   return false;
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 31d1e69..6c2f4d9 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -526,13 +526,12 @@
     return FreeMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg));
   }
   if (opcode == M_INITIALIZE_GWP_ASAN) {
-    if (arg == nullptr || arg_size != sizeof(bool)) {
+    if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) {
       errno = EINVAL;
       return false;
     }
-    __libc_globals.mutate([&](libc_globals* globals) {
-      return MaybeInitGwpAsan(globals, *reinterpret_cast<bool*>(arg));
-    });
+
+    return EnableGwpAsan(*reinterpret_cast<android_mallopt_gwp_asan_options_t*>(arg));
   }
   // Try heapprofd's mallopt, as it handles options not covered here.
   return HeapprofdMallopt(opcode, arg, arg_size);
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index 741b45e..f017ff5 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -237,8 +237,6 @@
     // heapprofd client initialization.
     MallocHeapprofdState expected2 = kHookInstalled;
     if (atomic_compare_exchange_strong(&gHeapprofdState, &expected,
-          kInstallingEphemeralHook) ||
-        atomic_compare_exchange_strong(&gHeapprofdState, &expected2,
           kInstallingEphemeralHook)) {
       const MallocDispatch* default_dispatch = GetDefaultDispatchTable();
 
@@ -248,14 +246,8 @@
       // initialized, allocations may need to be serviced. There are three
       // possible configurations:
 
-      if (default_dispatch == nullptr) {
-        //  1. No malloc hooking has been done (heapprofd, GWP-ASan, etc.). In
-        //  this case, everything but malloc() should come from the system
-        //  allocator.
-        atomic_store(&gPreviousDefaultDispatchTable, nullptr);
-        gEphemeralDispatch = *NativeAllocatorDispatch();
-      } else if (DispatchIsGwpAsan(default_dispatch)) {
-        //  2. GWP-ASan was installed. We should use GWP-ASan for everything but
+      if (DispatchIsGwpAsan(default_dispatch)) {
+        //  1. GWP-ASan was installed. We should use GWP-ASan for everything but
         //  malloc() in the interim period before heapprofd is properly
         //  installed. After heapprofd is finished installing, we will use
         //  GWP-ASan as heapprofd's backing allocator to allow heapprofd and
@@ -263,8 +255,16 @@
         atomic_store(&gPreviousDefaultDispatchTable, default_dispatch);
         gEphemeralDispatch = *default_dispatch;
       } else {
+        // Either,
+        // 2. No malloc hooking has been done (heapprofd, GWP-ASan, etc.). In
+        // this case, everything but malloc() should come from the system
+        // allocator.
+        //
+        // or,
+        //
         // 3. It may be possible at this point in time that heapprofd is
-        // *already* the default dispatch, and as such we don't want to use
+        // *already* the default dispatch, and when it was initialized there
+        // was no default dispatch installed. As such we don't want to use
         // heapprofd as the backing store for itself (otherwise infinite
         // recursion occurs). We will use the system allocator functions. Note:
         // We've checked that no other malloc interceptors are being used by
@@ -273,23 +273,46 @@
         atomic_store(&gPreviousDefaultDispatchTable, nullptr);
         gEphemeralDispatch = *NativeAllocatorDispatch();
       }
-
-      // Now, replace the malloc function so that the next call to malloc() will
-      // initialize heapprofd.
-      gEphemeralDispatch.malloc = MallocInitHeapprofdHook;
-
-      // And finally, install these new malloc-family interceptors.
-      __libc_globals.mutate([](libc_globals* globals) {
-        atomic_store(&globals->default_dispatch_table, &gEphemeralDispatch);
-        if (!MallocLimitInstalled()) {
-          atomic_store(&globals->current_dispatch_table, &gEphemeralDispatch);
-        }
-      });
-      atomic_store(&gHeapprofdState, kEphemeralHookInstalled);
+    } else if (expected == kEphemeralHookInstalled) {
+      // Nothing to do here. The ephemeral hook was installed, but
+      // MallocInitHeapprofdHook() was never called. Since the ephemeral hook
+      // is already there, no need to reinstall it.
+      return;
+    } else if (atomic_compare_exchange_strong(&gHeapprofdState, &expected2,
+                                              kInstallingEphemeralHook)) {
+      // if we still have hook installed, we can reuse the previous
+      // decision. THIS IS REQUIRED FOR CORRECTNESS, because otherwise the
+      // following can happen
+      // 1. Assume DispatchIsGwpAsan(default_dispatch)
+      // 2. This function is ran, sets gPreviousDefaultDispatchTable to
+      //    GWP ASan.
+      // 3. The sessions ends, DispatchReset FAILS due to a race. Now
+      //    heapprofd hooks are default dispatch.
+      // 4. We re-enter this function later. If we did NOT look at the
+      //    previously recorded gPreviousDefaultDispatchTable, we would
+      //    incorrectly reach case 3. below.
+      // 5. The session ends, DispatchReset now resets the hooks to the
+      //    system allocator. This is incorrect.
+      const MallocDispatch* prev_dispatch =
+        atomic_load(&gPreviousDefaultDispatchTable);
+      gEphemeralDispatch = prev_dispatch ? *prev_dispatch : *NativeAllocatorDispatch();
     } else {
       error_log("%s: heapprofd: failed to transition kInitialState -> kInstallingEphemeralHook. "
           "current state (possible race): %d", getprogname(), expected2);
+      return;
     }
+    // Now, replace the malloc function so that the next call to malloc() will
+    // initialize heapprofd.
+    gEphemeralDispatch.malloc = MallocInitHeapprofdHook;
+
+    // And finally, install these new malloc-family interceptors.
+    __libc_globals.mutate([](libc_globals* globals) {
+      atomic_store(&globals->default_dispatch_table, &gEphemeralDispatch);
+      if (!MallocLimitInstalled()) {
+        atomic_store(&globals->current_dispatch_table, &gEphemeralDispatch);
+      }
+    });
+    atomic_store(&gHeapprofdState, kEphemeralHookInstalled);
   });
   // Otherwise, we're racing against malloc_limit's enable logic (at most once
   // per process, and a niche feature). This is highly unlikely, so simply give
@@ -335,16 +358,15 @@
     return;
   }
 
+  FinishInstallHooks(globals, nullptr, kHeapprofdPrefix);
+}
+
+void HeapprofdInstallHooksAtInit(libc_globals *globals) {
   // Before we set the new default_dispatch_table in FinishInstallHooks, save
   // the previous dispatch table. If DispatchReset() gets called later, we want
   // to be able to restore the dispatch. We're still under
   // MaybeModifyGlobals locks at this point.
   atomic_store(&gPreviousDefaultDispatchTable, GetDefaultDispatchTable());
-
-  FinishInstallHooks(globals, nullptr, kHeapprofdPrefix);
-}
-
-void HeapprofdInstallHooksAtInit(libc_globals* globals) {
   MaybeModifyGlobals(kWithoutLock, [globals] {
     MallocHeapprofdState expected = kInitialState;
     if (atomic_compare_exchange_strong(&gHeapprofdState, &expected, kInstallingHook)) {
diff --git a/libc/bionic/mbrtoc16.cpp b/libc/bionic/mbrtoc16.cpp
index acea426..154b8a3 100644
--- a/libc/bionic/mbrtoc16.cpp
+++ b/libc/bionic/mbrtoc16.cpp
@@ -77,12 +77,15 @@
     return nconv;
   } else if (nconv == 0) {
     return mbstate_reset_and_return(nconv, state);
-  } else if (c32 > 0x10ffff) {
-    // Input cannot be encoded as UTF-16.
-    return mbstate_reset_and_return_illegal(EILSEQ, state);
   } else if (c32 < 0x10000) {
     *pc16 = static_cast<char16_t>(c32);
     return mbstate_reset_and_return(nconv, state);
+  } else if (c32 > 0x10ffff) {
+    // This case is currently handled by mbrtoc32() returning an error, but
+    // if that function is extended to cover 5-byte sequences (which are
+    // illegal at the moment), we'd need to explicitly handle the case of
+    // codepoints that can't be represented as a surrogate pair here.
+    return mbstate_reset_and_return_illegal(EILSEQ, state);
   } else {
     return begin_surrogate(c32, pc16, nconv, state);
   }
diff --git a/libc/bionic/mbrtoc32.cpp b/libc/bionic/mbrtoc32.cpp
index 644e542..d37ca66 100644
--- a/libc/bionic/mbrtoc32.cpp
+++ b/libc/bionic/mbrtoc32.cpp
@@ -55,7 +55,7 @@
   }
 
   uint8_t ch;
-  if (mbsinit(state) && (((ch = static_cast<uint8_t>(*s)) & ~0x7f) == 0)) {
+  if (mbstate_is_initial(state) && (((ch = static_cast<uint8_t>(*s)) & ~0x7f) == 0)) {
     // Fast path for plain ASCII characters.
     if (pc32 != nullptr) {
       *pc32 = ch;
@@ -80,11 +80,8 @@
   // The first byte in the state (if any) tells the length.
   size_t bytes_so_far = mbstate_bytes_so_far(state);
   ch = bytes_so_far > 0 ? mbstate_get_byte(state, 0) : static_cast<uint8_t>(*s);
-  if ((ch & 0x80) == 0) {
-    mask = 0x7f;
-    length = 1;
-    lower_bound = 0;
-  } else if ((ch & 0xe0) == 0xc0) {
+  // We already handled the 1-byte case above, so we go straight to 2-bytes...
+  if ((ch & 0xe0) == 0xc0) {
     mask = 0x1f;
     length = 2;
     lower_bound = 0x80;
@@ -105,7 +102,7 @@
   size_t bytes_wanted = length - bytes_so_far;
   size_t i;
   for (i = 0; i < MIN(bytes_wanted, n); i++) {
-    if (!mbsinit(state) && ((*s & 0xc0) != 0x80)) {
+    if (!mbstate_is_initial(state) && ((*s & 0xc0) != 0x80)) {
       // Malformed input; bad characters in the middle of a character.
       return mbstate_reset_and_return_illegal(EILSEQ, state);
     }
diff --git a/libc/bionic/preadv_pwritev.cpp b/libc/bionic/preadv_pwritev.cpp
new file mode 100644
index 0000000..e44d3a6
--- /dev/null
+++ b/libc/bionic/preadv_pwritev.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 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 <sys/uio.h>
+
+// System calls we need.
+extern "C" int __preadv64(int, const struct iovec*, int, long, long);
+extern "C" int __preadv64v2(int, const struct iovec*, int, long, long, int);
+extern "C" int __pwritev64(int, const struct iovec*, int, long, long);
+extern "C" int __pwritev64v2(int, const struct iovec*, int, long, long, int);
+
+// There is no 32-bit off_t preadv/pwritev (even on LP32).
+// To avoid 32-bit ABI issues about which register pairs you're allowed
+// to pass 64-bit values in, the kernel just takes two `long` arguments --
+// which are int32_t for LP32, remember -- and stitches them together.
+// It even does this for LP64, taking a second unused always-zero `long`.
+// (The first long was int64_t, which is the same as off64_t.)
+// The pair is split lo-hi (not hi-lo, as llseek is).
+
+ssize_t preadv(int fd, const struct iovec* ios, int count, off_t offset) {
+  return preadv64(fd, ios, count, offset);
+}
+
+ssize_t preadv64(int fd, const struct iovec* ios, int count, off64_t offset) {
+#if defined(__LP64__)
+  return __preadv64(fd, ios, count, offset, 0);
+#else
+  return __preadv64(fd, ios, count, offset, offset >> 32);
+#endif
+}
+
+ssize_t pwritev(int fd, const struct iovec* ios, int count, off_t offset) {
+  return pwritev64(fd, ios, count, offset);
+}
+
+ssize_t pwritev64(int fd, const struct iovec* ios, int count, off64_t offset) {
+#if defined(__LP64__)
+  return __pwritev64(fd, ios, count, offset, 0);
+#else
+  return __pwritev64(fd, ios, count, offset, offset >> 32);
+#endif
+}
+
+ssize_t preadv2(int fd, const struct iovec* ios, int count, off_t offset, int flags) {
+  return preadv64v2(fd, ios, count, offset, flags);
+}
+
+ssize_t preadv64v2(int fd, const struct iovec* ios, int count, off64_t offset, int flags) {
+#if defined(__LP64__)
+  return __preadv64v2(fd, ios, count, offset, 0, flags);
+#else
+  return __preadv64v2(fd, ios, count, offset, offset >> 32, flags);
+#endif
+}
+
+ssize_t pwritev2(int fd, const struct iovec* ios, int count, off_t offset, int flags) {
+  return pwritev64v2(fd, ios, count, offset, flags);
+}
+
+ssize_t pwritev64v2(int fd, const struct iovec* ios, int count, off64_t offset, int flags) {
+#if defined(__LP64__)
+  return __pwritev64v2(fd, ios, count, offset, 0, flags);
+#else
+  return __pwritev64v2(fd, ios, count, offset, offset >> 32, flags);
+#endif
+}
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index e73828f..59f7631 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -30,9 +30,12 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/close_range.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
 #include <unistd.h>
 
 #include <android/fdsan.h>
@@ -40,6 +43,28 @@
 #include "private/ScopedSignalBlocker.h"
 #include "private/SigSetConverter.h"
 
+static int set_cloexec(int i) {
+  int v = fcntl(i, F_GETFD);
+  if (v == -1) return -1;  // almost certainly: errno == EBADF
+  return fcntl(i, F_SETFD, v | FD_CLOEXEC);
+}
+
+// mark all open fds except stdin/out/err as close-on-exec
+static int cloexec_except_stdioe() {
+  // requires 5.11+ or ACK 5.10-T kernel, otherwise returns ENOSYS or EINVAL
+  if (!syscall(SYS_close_range, 3, ~0U, CLOSE_RANGE_CLOEXEC)) return 0;
+
+  // unfortunately getrlimit can lie:
+  // - both soft and hard limits can be lowered to 0, with fds still open, so it can underestimate
+  // - in practice it usually is some really large value (like 32K or more)
+  //   even though only a handful of small fds are actually open (ie. < 500),
+  //   this results in poor performance when trying to act on all possibly open fds
+  struct rlimit m;
+  int max = getrlimit(RLIMIT_NOFILE, &m) ? 1000000 : m.rlim_max;
+  for (int i = 3; i < max; ++i) set_cloexec(i);
+  return 0;
+}
+
 enum Action {
   kOpen,
   kClose,
@@ -69,7 +94,17 @@
       // Failure to close is ignored.
       close(fd);
     } else {
-      if (dup2(fd, new_fd) == -1) _exit(127);
+      // It's a dup2.
+      if (fd == new_fd) {
+        // dup2(2) is a no-op if fd == new_fd, but POSIX suggests that we should
+        // manually remove the O_CLOEXEC flag in that case (because otherwise
+        // what use is the dup?).
+        // See https://www.austingroupbugs.net/view.php?id=411 for details.
+        int flags = fcntl(fd, F_GETFD, 0);
+        if (flags == -1 || fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) == -1) _exit(127);
+      } else {
+        if (dup2(fd, new_fd) == -1) _exit(127);
+      }
     }
   }
 };
@@ -131,6 +166,10 @@
   if ((flags & POSIX_SPAWN_SETSIGMASK) != 0) {
     if (sigprocmask64(SIG_SETMASK, &(*attr)->sigmask.sigset64, nullptr)) _exit(127);
   }
+
+  if ((flags & POSIX_SPAWN_CLOEXEC_DEFAULT) != 0) {
+    if (cloexec_except_stdioe()) _exit(127);
+  }
 }
 
 static int posix_spawn(pid_t* pid_ptr,
@@ -189,7 +228,7 @@
 int posix_spawnattr_setflags(posix_spawnattr_t* attr, short flags) {
   if ((flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF |
                  POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER |
-                 POSIX_SPAWN_USEVFORK | POSIX_SPAWN_SETSID)) != 0) {
+                 POSIX_SPAWN_USEVFORK | POSIX_SPAWN_SETSID | POSIX_SPAWN_CLOEXEC_DEFAULT)) != 0) {
     return EINVAL;
   }
   (*attr)->flags = flags;
diff --git a/libc/bionic/strerror.cpp b/libc/bionic/strerror.cpp
index 5733567..0deb200 100644
--- a/libc/bionic/strerror.cpp
+++ b/libc/bionic/strerror.cpp
@@ -196,8 +196,7 @@
     length = async_safe_format_buffer(buf, buf_len, "Unknown error %d", error_number);
   }
   if (length >= buf_len) {
-    errno_restorer.override(ERANGE);
-    return -1;
+    return ERANGE;
   }
 
   return 0;
diff --git a/libc/bionic/sysprop_helpers.cpp b/libc/bionic/sysprop_helpers.cpp
new file mode 100644
index 0000000..edae6cc
--- /dev/null
+++ b/libc/bionic/sysprop_helpers.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 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 "sysprop_helpers.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "sys/system_properties.h"
+
+static bool get_property_value(const char* property_name, char* dest, size_t dest_size) {
+  assert(property_name && dest && dest_size != 0);
+  const prop_info* prop = __system_property_find(property_name);
+  if (!prop) return false;
+
+  struct PropCbCookie {
+    char* dest;
+    size_t size;
+  };
+  *dest = '\0';
+  PropCbCookie cb_cookie = {dest, dest_size};
+
+  __system_property_read_callback(
+      prop,
+      [](void* cookie, const char* /* name */, const char* value, uint32_t /* serial */) {
+        auto* cb_cookie = reinterpret_cast<PropCbCookie*>(cookie);
+        strncpy(cb_cookie->dest, value, cb_cookie->size);
+      },
+      &cb_cookie);
+  if (*dest != '\0' && *dest != '0') return true;
+
+  return false;
+}
+
+bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const* sys_prop_names,
+                                     size_t sys_prop_names_size, char* options,
+                                     size_t options_size) {
+  const char* env = getenv(env_var_name);
+  if (env && *env != '\0') {
+    strncpy(options, env, options_size);
+    options[options_size - 1] = '\0';  // Ensure null-termination.
+    return true;
+  }
+
+  for (size_t i = 0; i < sys_prop_names_size; ++i) {
+    if (sys_prop_names[i] == nullptr) continue;
+    if (get_property_value(sys_prop_names[i], options, options_size)) return true;
+  }
+  return false;
+}
diff --git a/libc/bionic/sysprop_helpers.h b/libc/bionic/sysprop_helpers.h
new file mode 100644
index 0000000..a02c2dc
--- /dev/null
+++ b/libc/bionic/sysprop_helpers.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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 <stdint.h>
+#include <sys/cdefs.h>
+
+// Get the presiding config string, in the following order of priority:
+//   1. Environment variables.
+//   2. System properties, in the order they're specified in sys_prop_names.
+// If neither of these options are specified (or they're both an empty string),
+// this function returns false. Otherwise, it returns true, and the presiding
+// options string is written to the `options` buffer of size `size`. If this
+// function returns true, `options` is guaranteed to be null-terminated.
+// `options_size` should be at least PROP_VALUE_MAX.
+__LIBC_HIDDEN__ bool get_config_from_env_or_sysprops(const char* env_var_name,
+                                                     const char* const* sys_prop_names,
+                                                     size_t sys_prop_names_size, char* options,
+                                                     size_t options_size);
diff --git a/libc/bionic/system.cpp b/libc/bionic/system.cpp
index 950f05c..93d7497 100644
--- a/libc/bionic/system.cpp
+++ b/libc/bionic/system.cpp
@@ -56,7 +56,7 @@
   if ((errno = posix_spawnattr_setsigmask64(&attributes, &sigchld_blocker.old_set_))) return -1;
   if ((errno = posix_spawnattr_setflags(&attributes, flags))) return -1;
 
-  const char* argv[] = { "sh", "-c", command, nullptr };
+  const char* argv[] = {"sh", "-c", "--", command, nullptr};
   pid_t child;
   if ((errno = posix_spawn(&child, __bionic_get_shell_path(), nullptr, &attributes,
                            const_cast<char**>(argv), environ)) != 0) {
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index dabe824..bd9a45e 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -54,7 +54,7 @@
 //
 
 int mbsinit(const mbstate_t* ps) {
-  return (ps == nullptr || (*(reinterpret_cast<const uint32_t*>(ps->__seq)) == 0));
+  return ps == nullptr || mbstate_is_initial(ps);
 }
 
 size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps) {
@@ -148,7 +148,7 @@
   static mbstate_t __private_state;
   mbstate_t* state = (ps == nullptr) ? &__private_state : ps;
 
-  if (!mbsinit(state)) {
+  if (!mbstate_is_initial(state)) {
     return mbstate_reset_and_return_illegal(EILSEQ, state);
   }
 
diff --git a/libc/execinfo/include/bionic/execinfo.h b/libc/execinfo/include/bionic/execinfo.h
new file mode 120000
index 0000000..0068019
--- /dev/null
+++ b/libc/execinfo/include/bionic/execinfo.h
@@ -0,0 +1 @@
+../../../include/execinfo.h
\ No newline at end of file
diff --git a/libc/execinfo/include/execinfo.h b/libc/execinfo/include/execinfo.h
new file mode 100644
index 0000000..e092c00
--- /dev/null
+++ b/libc/execinfo/include/execinfo.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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
+
+/*
+ * This file is exported as part of libexecinfo for use with musl, which doesn't
+ * define __INTRODUCED_IN.  Stub it out.
+ */
+#define __INTRODUCED_IN(x)
+#include <bionic/execinfo.h>
+#undef __INTRODUCED_IN
diff --git a/libc/fts/include/bionic/fts.h b/libc/fts/include/bionic/fts.h
new file mode 120000
index 0000000..92e44cf
--- /dev/null
+++ b/libc/fts/include/bionic/fts.h
@@ -0,0 +1 @@
+../../../include/fts.h
\ No newline at end of file
diff --git a/libc/fts/include/fts.h b/libc/fts/include/fts.h
new file mode 100644
index 0000000..d252e86
--- /dev/null
+++ b/libc/fts/include/fts.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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
+
+/*
+ * This file is exported as part of libfts for use with musl, which doesn't
+ * define __INTRODUCED_IN.  Stub it out.
+ */
+#define __INTRODUCED_IN(x)
+#include <bionic/fts.h>
+#undef __INTRODUCED_IN
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 40846fb..ecf318d 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -151,6 +151,9 @@
 /** Names the "S" API level (31), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_S__ 31
 
+/** Names the "T" API level (33), for comparison against `__ANDROID_API__`. */
+#define __ANDROID_API_T__ 33
+
 /* This file is included in <features.h>, and might be used from .S files. */
 #if !defined(__ASSEMBLY__)
 
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 95c2320..f2bdcf6 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -89,7 +89,7 @@
     errno = EINVAL;
     return -1;
   }
-  return (int)((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
+  return (int)((local_set[bit / (8 * sizeof(long))] >> (bit % (8 * sizeof(long)))) & 1);
 }
 
 static __inline int sigaddset(sigset_t *set, int signum) {
@@ -100,7 +100,7 @@
     errno = EINVAL;
     return -1;
   }
-  local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
+  local_set[bit / (8 * sizeof(long))] |= 1UL << (bit % (8 * sizeof(long)));
   return 0;
 }
 
@@ -112,7 +112,7 @@
     errno = EINVAL;
     return -1;
   }
-  local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
+  local_set[bit / (8 * sizeof(long))] &= ~(1UL << (bit % (8 * sizeof(long))));
   return 0;
 }
 
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 214acf2..efe4354 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -51,7 +51,7 @@
 // those APIs will still cause a link error.
 #if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
 #define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,__what)))
-#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
+#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN(api_level)
 #define __INTRODUCED_IN_X86_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN_X86(api_level)
 #else
 #define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,strict,__what)))
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 42698dd..77bdbb4 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -40,6 +40,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE __printflike(3, 0)
 int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
+        __diagnose_as_builtin(__builtin_vsnprintf, 1, 2, 3, 4)
         __overloadable {
     return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
 }
@@ -70,6 +71,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
 int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+        __diagnose_as_builtin(__builtin_snprintf, 1, 2, 3)
         __overloadable {
     va_list va;
     va_start(va, format);
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
index beb5ff5..08bce2d 100644
--- a/libc/include/bits/fortify/string.h
+++ b/libc/include/bits/fortify/string.h
@@ -44,13 +44,16 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+        __diagnose_as_builtin(__builtin_memcpy, 1, 2, 3)
         __overloadable {
     return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
 }
 
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
-void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) __overloadable {
+void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
+        __diagnose_as_builtin(__builtin_memmove, 1, 2, 3)
+        __overloadable {
     return __builtin___memmove_chk(dst, src, len, __bos0(dst));
 }
 #endif
@@ -59,6 +62,7 @@
 #if __ANDROID_API__ >= 30
 __BIONIC_FORTIFY_INLINE
 void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
+        __diagnose_as_builtin(__builtin_mempcpy, 1, 2, 3)
         __overloadable
         __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
                          "'mempcpy' called with size bigger than buffer") {
@@ -87,6 +91,7 @@
 
 __BIONIC_FORTIFY_INLINE
 char* strcpy(char* const dst __pass_object_size, const char* src)
+        __diagnose_as_builtin(__builtin_strcpy, 1, 2)
         __overloadable
         __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
                          "'strcpy' called with string bigger than buffer") {
@@ -112,7 +117,9 @@
 #if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
-char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
+char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
+       __diagnose_as_builtin(__builtin_strncat, 1, 2, 3)
+       __overloadable {
     return __builtin___strncat_chk(dst, src, n, __bos(dst));
 }
 #endif
@@ -120,6 +127,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
+        __diagnose_as_builtin(__builtin_memset, 1, 2, 3)
         /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
         __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
 #if __ANDROID_API__ >= 17 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
@@ -157,6 +165,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+        __diagnose_as_builtin(__builtin_stpncpy, 1, 2, 3)
         __overloadable {
     size_t bos_dst = __bos(dst);
     size_t bos_src = __bos(src);
@@ -172,6 +181,7 @@
 /* No diag -- clang diagnoses misuses of this on its own.  */
 __BIONIC_FORTIFY_INLINE
 char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
+        __diagnose_as_builtin(__builtin_strncpy, 1, 2, 3)
         __overloadable {
     size_t bos_dst = __bos(dst);
     size_t bos_src = __bos(src);
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index fbda7fe..c144919 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -303,6 +303,9 @@
 #if defined(__NR_futex_time64)
   #define SYS_futex_time64 __NR_futex_time64
 #endif
+#if defined(__NR_futex_waitv)
+  #define SYS_futex_waitv __NR_futex_waitv
+#endif
 #if defined(__NR_futimesat)
   #define SYS_futimesat __NR_futimesat
 #endif
@@ -507,6 +510,15 @@
 #if defined(__NR_kill)
   #define SYS_kill __NR_kill
 #endif
+#if defined(__NR_landlock_add_rule)
+  #define SYS_landlock_add_rule __NR_landlock_add_rule
+#endif
+#if defined(__NR_landlock_create_ruleset)
+  #define SYS_landlock_create_ruleset __NR_landlock_create_ruleset
+#endif
+#if defined(__NR_landlock_restrict_self)
+  #define SYS_landlock_restrict_self __NR_landlock_restrict_self
+#endif
 #if defined(__NR_lchown)
   #define SYS_lchown __NR_lchown
 #endif
@@ -567,6 +579,9 @@
 #if defined(__NR_memfd_create)
   #define SYS_memfd_create __NR_memfd_create
 #endif
+#if defined(__NR_memfd_secret)
+  #define SYS_memfd_secret __NR_memfd_secret
+#endif
 #if defined(__NR_migrate_pages)
   #define SYS_migrate_pages __NR_migrate_pages
 #endif
@@ -789,6 +804,9 @@
 #if defined(__NR_process_madvise)
   #define SYS_process_madvise __NR_process_madvise
 #endif
+#if defined(__NR_process_mrelease)
+  #define SYS_process_mrelease __NR_process_mrelease
+#endif
 #if defined(__NR_process_vm_readv)
   #define SYS_process_vm_readv __NR_process_vm_readv
 #endif
@@ -828,6 +846,9 @@
 #if defined(__NR_quotactl)
   #define SYS_quotactl __NR_quotactl
 #endif
+#if defined(__NR_quotactl_fd)
+  #define SYS_quotactl_fd __NR_quotactl_fd
+#endif
 #if defined(__NR_read)
   #define SYS_read __NR_read
 #endif
@@ -1002,6 +1023,9 @@
 #if defined(__NR_set_mempolicy)
   #define SYS_set_mempolicy __NR_set_mempolicy
 #endif
+#if defined(__NR_set_mempolicy_home_node)
+  #define SYS_set_mempolicy_home_node __NR_set_mempolicy_home_node
+#endif
 #if defined(__NR_set_robust_list)
   #define SYS_set_robust_list __NR_set_robust_list
 #endif
diff --git a/libc/include/bits/signal_types.h b/libc/include/bits/signal_types.h
index e1a155f..699e257 100644
--- a/libc/include/bits/signal_types.h
+++ b/libc/include/bits/signal_types.h
@@ -61,7 +61,7 @@
 #if defined(__LP64__)
 typedef sigset_t sigset64_t;
 #else
-typedef struct { unsigned long __bits[_KERNEL__NSIG/LONG_BIT]; } sigset64_t;
+typedef struct { unsigned long __bits[_KERNEL__NSIG/(8*sizeof(long))]; } sigset64_t;
 #endif
 
 #if defined(__LP64__)
diff --git a/libc/include/execinfo.h b/libc/include/execinfo.h
new file mode 100644
index 0000000..347ae92
--- /dev/null
+++ b/libc/include/execinfo.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 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>
+
+/**
+ * @file execinfo.h
+ * @brief Functions to do in process backtracing.
+ */
+
+__BEGIN_DECLS
+
+/**
+ * [backtrace(3)](https://man7.org/linux/man-pages/man3/backtrace.3.html)
+ * Saves a backtrace for the current call in the array pointed to by buffer.
+ * "size" indicates the maximum number of void* pointers that can be set.
+ *
+ * Returns the number of addresses stored in "buffer", which is not greater
+ * than "size". If the return value is equal to "size" then the number of
+ * addresses may have been truncated.
+ *
+ * Available since API level 33.
+ */
+int backtrace(void** buffer, int size) __INTRODUCED_IN(33);
+
+/**
+ * [backtrace_symbols(3)](https://man7.org/linux/man-pages/man3/backtrace_symbols.3.html)
+ * Given an array of void* pointers, translate the addresses into an array
+ * of strings that represent the backtrace.
+ *
+ * Returns a pointer to allocated memory, on error NULL is returned. It is
+ * the responsibility of the caller to free the returned memory.
+ *
+ * Available since API level 33.
+ */
+char** backtrace_symbols(void* const* buffer, int size) __INTRODUCED_IN(33);
+
+/**
+ * [backtrace_symbols_fd(3)](https://man7.org/linux/man-pages/man3/backtrace_symbols_fd.3.html)
+ * Given an array of void* pointers, translate the addresses into an array
+ * of strings that represent the backtrace and write to the file represented
+ * by "fd". The file is written such that one line equals one void* address.
+ *
+ * Available since API level 33.
+ */
+void backtrace_symbols_fd(void* const* buffer, int size, int fd) __INTRODUCED_IN(33);
+
+__END_DECLS
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index f7beb2c..40786fa 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -97,30 +97,31 @@
  */
 size_t malloc_usable_size(const void* __ptr) __INTRODUCED_IN(17);
 
+#define __MALLINFO_BODY \
+  /** Total number of non-mmapped bytes currently allocated from OS. */ \
+  size_t arena; \
+  /** Number of free chunks. */ \
+  size_t ordblks; \
+  /** (Unused.) */ \
+  size_t smblks; \
+  /** (Unused.) */ \
+  size_t hblks; \
+  /** Total number of bytes in mmapped regions. */ \
+  size_t hblkhd; \
+  /** Maximum total allocated space; greater than total if trimming has occurred. */ \
+  size_t usmblks; \
+  /** (Unused.) */ \
+  size_t fsmblks; \
+  /** Total allocated space (normal or mmapped.) */ \
+  size_t uordblks; \
+  /** Total free space. */ \
+  size_t fordblks; \
+  /** Upper bound on number of bytes releasable by a trim operation. */ \
+  size_t keepcost;
+
 #ifndef STRUCT_MALLINFO_DECLARED
 #define STRUCT_MALLINFO_DECLARED 1
-struct mallinfo {
-  /** Total number of non-mmapped bytes currently allocated from OS. */
-  size_t arena;
-  /** Number of free chunks. */
-  size_t ordblks;
-  /** (Unused.) */
-  size_t smblks;
-  /** (Unused.) */
-  size_t hblks;
-  /** Total number of bytes in mmapped regions. */
-  size_t hblkhd;
-  /** Maximum total allocated space; greater than total if trimming has occurred. */
-  size_t usmblks;
-  /** (Unused.) */
-  size_t fsmblks;
-  /** Total allocated space (normal or mmapped.) */
-  size_t uordblks;
-  /** Total free space. */
-  size_t fordblks;
-  /** Upper bound on number of bytes releasable by a trim operation. */
-  size_t keepcost;
-};
+struct mallinfo { __MALLINFO_BODY };
 #endif
 
 /**
@@ -131,6 +132,18 @@
 struct mallinfo mallinfo(void);
 
 /**
+ * On Android the struct mallinfo and struct mallinfo2 are the same.
+ */
+struct mallinfo2 { __MALLINFO_BODY };
+
+/**
+ * [mallinfo2(3)](http://man7.org/linux/man-pages/man3/mallinfo2.3.html) returns
+ * information about the current state of the heap. Note that mallinfo2() is
+ * inherently unreliable and consider using malloc_info() instead.
+ */
+struct mallinfo2 mallinfo2(void) __RENAME(mallinfo);
+
+/**
  * [malloc_info(3)](http://man7.org/linux/man-pages/man3/malloc_info.3.html)
  * writes information about the current state of the heap to the given stream.
  *
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index 7f00a7a..46e3543 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -33,7 +33,18 @@
 #include <sys/cdefs.h>
 #include <sys/socket.h>
 
+// Include linux/socket.h first to trigger the header guard without
+// the__kernel_sockaddr_storage define, so its definition uses the
+// kernel name.
+#include <linux/socket.h>
+
+// Redefine __kernel_sockaddr_storage to sockaddr_storage so that
+// the structs defined in linux/in.h use the sockaddr_storage defined
+// in sys/sockets.h.
+#define __kernel_sockaddr_storage sockaddr_storage
 #include <linux/in.h>
+#undef __kernel_sockaddr_storage
+
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 
diff --git a/libc/include/sched.h b/libc/include/sched.h
index 3260231..364ca10 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -26,8 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SCHED_H_
-#define _SCHED_H_
+#pragma once
+
+/**
+ * @file sched.h
+ * @brief Thread execution scheduling.
+ */
 
 #include <bits/timespec.h>
 #include <linux/sched.h>
@@ -35,29 +39,170 @@
 
 __BEGIN_DECLS
 
-/* This name is used by glibc, but not by the kernel. */
+/*
+ * @def SCHED_NORMAL
+ * The standard (as opposed to real-time) round-robin scheduling policy.
+ *
+ * (Linux's name for POSIX's SCHED_OTHER.)
+ *
+ * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ */
+
+/*
+ * @def SCHED_FIFO
+ * The real-time first-in/first-out scheduling policy.
+ *
+ * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ */
+
+/*
+ * @def SCHED_RR
+ * The real-time round-robin policy. (See also SCHED_NORMAL/SCHED_OTHER.)
+ *
+ * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ */
+
+/*
+ * @def SCHED_BATCH
+ * The batch scheduling policy.
+ *
+ * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ */
+
+/*
+ * @def SCHED_IDLE
+ * The low priority "only when otherwise idle" scheduling priority.
+ *
+ * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ */
+
+/*
+ * @def SCHED_DEADLINE
+ * The deadline scheduling policy.
+ *
+ * See [sched(7)](http://man7.org/linux/man-pages/man7/sched.7.html)
+ */
+
+/*
+ * The standard (as opposed to real-time) round-robin scheduling policy.
+ *
+ * (POSIX's name for Linux's SCHED_NORMAL.)
+ */
 #define SCHED_OTHER SCHED_NORMAL
 
+/**
+ * See sched_getparam()/sched_setparam() and
+ * sched_getscheduler()/sched_setscheduler().
+ */
 struct sched_param {
   int sched_priority;
 };
 
+/**
+ * [sched_setscheduler(2)](http://man7.org/linux/man-pages/man2/sched_getcpu.2.html)
+ * sets the scheduling policy and associated parameters for the given thread.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* __param);
+
+/**
+ * [sched_getscheduler(2)](http://man7.org/linux/man-pages/man2/sched_getcpu.2.html)
+ * gets the scheduling policy for the given thread.
+ *
+ * Returns a non-negative thread policy on success and returns -1 and sets
+ * `errno` on failure.
+ */
 int sched_getscheduler(pid_t __pid);
+
+/**
+ * [sched_yield(2)](http://man7.org/linux/man-pages/man2/sched_yield.2.html)
+ * voluntarily gives up using the CPU so that another thread can run.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_yield(void);
+
+/**
+ * [sched_get_priority_max(2)](http://man7.org/linux/man-pages/man2/sched_get_priority_max.2.html)
+ * gets the maximum priority value allowed for the given scheduling policy.
+ *
+ * Returns a priority on success and returns -1 and sets `errno` on failure.
+ */
 int sched_get_priority_max(int __policy);
+
+/**
+ * [sched_get_priority_min(2)](http://man7.org/linux/man-pages/man2/sched_get_priority_min.2.html)
+ * gets the minimum priority value allowed for the given scheduling policy.
+ *
+ * Returns a priority on success and returns -1 and sets `errno` on failure.
+ */
 int sched_get_priority_min(int __policy);
+
+/**
+ * [sched_setparam(2)](http://man7.org/linux/man-pages/man2/sched_setparam.2.html)
+ * sets the scheduling parameters for the given thread.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_setparam(pid_t __pid, const struct sched_param* __param);
+
+/**
+ * [sched_getparam(2)](http://man7.org/linux/man-pages/man2/sched_getparam.2.html)
+ * gets the scheduling parameters for the given thread.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_getparam(pid_t __pid, struct sched_param* __param);
+
+/**
+ * [sched_rr_get_interval(2)](http://man7.org/linux/man-pages/man2/sched_rr_get_interval.2.html)
+ * queries the round-robin time quantum for the given thread.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_rr_get_interval(pid_t __pid, struct timespec* __quantum);
 
 #if defined(__USE_GNU)
 
+/**
+ * [clone(2)](http://man7.org/linux/man-pages/man2/clone.2.html)
+ * creates a new child process.
+ *
+ * Returns the pid of the child to the caller on success and
+ * returns -1 and sets `errno` on failure.
+ */
 int clone(int (*__fn)(void*), void* __child_stack, int __flags, void* __arg, ...) __INTRODUCED_IN_ARM(9) __INTRODUCED_IN_X86(17);
+
+/**
+ * [unshare(2)](http://man7.org/linux/man-pages/man2/unshare.2.html)
+ * disassociates part of the caller's execution context.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 17.
+ */
 int unshare(int __flags) __INTRODUCED_IN(17);
-int sched_getcpu(void);
+
+/**
+ * [setns(2)](http://man7.org/linux/man-pages/man2/setns.2.html)
+ * reassociates a thread with a different namespace.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 21.
+ */
 int setns(int __fd, int __ns_type) __INTRODUCED_IN(21);
 
+/**
+ * [sched_getcpu(3)](http://man7.org/linux/man-pages/man3/sched_getcpu.3.html)
+ * reports which CPU the caller is running on.
+ *
+ * Returns a non-negative CPU number on success and returns -1 and sets
+ * `errno` on failure.
+ */
+int sched_getcpu(void);
+
 #ifdef __LP64__
 #define CPU_SETSIZE 1024
 #else
@@ -69,39 +214,50 @@
 #define __CPU_ELT(x)   ((x) / __CPU_BITS)
 #define __CPU_MASK(x)  ((__CPU_BITTYPE)1 << ((x) & (__CPU_BITS - 1)))
 
+/**
+ * [cpu_set_t](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) is a
+ * statically-sized CPU set. See `CPU_ALLOC` for dynamically-sized CPU sets.
+ */
 typedef struct {
   __CPU_BITTYPE  __bits[ CPU_SETSIZE / __CPU_BITS ];
 } cpu_set_t;
 
+/**
+ * [sched_setaffinity(2)](http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html)
+ * sets the CPU affinity mask for the given thread.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* __set);
+
+/**
+ * [sched_getaffinity(2)](http://man7.org/linux/man-pages/man2/sched_getaffinity.2.html)
+ * gets the CPU affinity mask for the given thread.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int sched_getaffinity(pid_t __pid, size_t __set_size, cpu_set_t* __set);
 
+/**
+ * [CPU_ZERO](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
+ * bits in a static CPU set.
+ */
 #define CPU_ZERO(set)          CPU_ZERO_S(sizeof(cpu_set_t), set)
-#define CPU_SET(cpu, set)      CPU_SET_S(cpu, sizeof(cpu_set_t), set)
-#define CPU_CLR(cpu, set)      CPU_CLR_S(cpu, sizeof(cpu_set_t), set)
-#define CPU_ISSET(cpu, set)    CPU_ISSET_S(cpu, sizeof(cpu_set_t), set)
-#define CPU_COUNT(set)         CPU_COUNT_S(sizeof(cpu_set_t), set)
-#define CPU_EQUAL(set1, set2)  CPU_EQUAL_S(sizeof(cpu_set_t), set1, set2)
-
-#define CPU_AND(dst, set1, set2)  __CPU_OP(dst, set1, set2, &)
-#define CPU_OR(dst, set1, set2)   __CPU_OP(dst, set1, set2, |)
-#define CPU_XOR(dst, set1, set2)  __CPU_OP(dst, set1, set2, ^)
-
-#define __CPU_OP(dst, set1, set2, op)  __CPU_OP_S(sizeof(cpu_set_t), dst, set1, set2, op)
-
-/* Support for dynamically-allocated cpu_set_t */
-
-#define CPU_ALLOC_SIZE(count) \
-  __CPU_ELT((count) + (__CPU_BITS - 1)) * sizeof(__CPU_BITTYPE)
-
-#define CPU_ALLOC(count)  __sched_cpualloc((count))
-#define CPU_FREE(set)     __sched_cpufree((set))
-
-cpu_set_t* __sched_cpualloc(size_t __count);
-void __sched_cpufree(cpu_set_t* __set);
-
+/**
+ * [CPU_ZERO_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears all
+ * bits in a dynamic CPU set allocated by `CPU_ALLOC`.
+ */
 #define CPU_ZERO_S(setsize, set)  __builtin_memset(set, 0, setsize)
 
+/**
+ * [CPU_SET](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) sets one
+ * bit in a static CPU set.
+ */
+#define CPU_SET(cpu, set)      CPU_SET_S(cpu, sizeof(cpu_set_t), set)
+/**
+ * [CPU_SET_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) sets one
+ * bit in a dynamic CPU set allocated by `CPU_ALLOC`.
+ */
 #define CPU_SET_S(cpu, setsize, set) \
   do { \
     size_t __cpu = (cpu); \
@@ -109,6 +265,15 @@
       (set)->__bits[__CPU_ELT(__cpu)] |= __CPU_MASK(__cpu); \
   } while (0)
 
+/**
+ * [CPU_CLR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears one
+ * bit in a static CPU set.
+ */
+#define CPU_CLR(cpu, set)      CPU_CLR_S(cpu, sizeof(cpu_set_t), set)
+/**
+ * [CPU_CLR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) clears one
+ * bit in a dynamic CPU set allocated by `CPU_ALLOC`.
+ */
 #define CPU_CLR_S(cpu, setsize, set) \
   do { \
     size_t __cpu = (cpu); \
@@ -116,6 +281,15 @@
       (set)->__bits[__CPU_ELT(__cpu)] &= ~__CPU_MASK(__cpu); \
   } while (0)
 
+/**
+ * [CPU_ISSET](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * whether the given bit is set in a static CPU set.
+ */
+#define CPU_ISSET(cpu, set)    CPU_ISSET_S(cpu, sizeof(cpu_set_t), set)
+/**
+ * [CPU_ISSET_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * whether the given bit is set in a dynamic CPU set allocated by `CPU_ALLOC`.
+ */
 #define CPU_ISSET_S(cpu, setsize, set) \
   (__extension__ ({ \
     size_t __cpu = (cpu); \
@@ -124,12 +298,65 @@
       : 0; \
   }))
 
+/**
+ * [CPU_COUNT](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) counts
+ * how many bits are set in a static CPU set.
+ */
+#define CPU_COUNT(set)         CPU_COUNT_S(sizeof(cpu_set_t), set)
+/**
+ * [CPU_COUNT_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) counts
+ * how many bits are set in a dynamic CPU set allocated by `CPU_ALLOC`.
+ */
+#define CPU_COUNT_S(setsize, set)  __sched_cpucount((setsize), (set))
+int __sched_cpucount(size_t __set_size, const cpu_set_t* __set);
+
+/**
+ * [CPU_EQUAL](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * whether two static CPU sets have the same bits set and cleared as each other.
+ */
+#define CPU_EQUAL(set1, set2)  CPU_EQUAL_S(sizeof(cpu_set_t), set1, set2)
+/**
+ * [CPU_EQUAL_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) tests
+ * whether two dynamic CPU sets allocated by `CPU_ALLOC` have the same bits
+ * set and cleared as each other.
+ */
 #define CPU_EQUAL_S(setsize, set1, set2)  (__builtin_memcmp(set1, set2, setsize) == 0)
 
+/**
+ * [CPU_AND](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ands two
+ * static CPU sets.
+ */
+#define CPU_AND(dst, set1, set2)  __CPU_OP(dst, set1, set2, &)
+/**
+ * [CPU_AND_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ands two
+ * dynamic CPU sets allocated by `CPU_ALLOC`.
+ */
 #define CPU_AND_S(setsize, dst, set1, set2)  __CPU_OP_S(setsize, dst, set1, set2, &)
+
+/**
+ * [CPU_OR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ors two
+ * static CPU sets.
+ */
+#define CPU_OR(dst, set1, set2)   __CPU_OP(dst, set1, set2, |)
+/**
+ * [CPU_OR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html) ors two
+ * dynamic CPU sets allocated by `CPU_ALLOC`.
+ */
 #define CPU_OR_S(setsize, dst, set1, set2)   __CPU_OP_S(setsize, dst, set1, set2, |)
+
+/**
+ * [CPU_XOR](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * exclusive-ors two static CPU sets.
+ */
+#define CPU_XOR(dst, set1, set2)  __CPU_OP(dst, set1, set2, ^)
+/**
+ * [CPU_XOR_S](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * exclusive-ors two dynamic CPU sets allocated by `CPU_ALLOC`.
+ */
 #define CPU_XOR_S(setsize, dst, set1, set2)  __CPU_OP_S(setsize, dst, set1, set2, ^)
 
+#define __CPU_OP(dst, set1, set2, op)  __CPU_OP_S(sizeof(cpu_set_t), dst, set1, set2, op)
+
 #define __CPU_OP_S(setsize, dstset, srcset1, srcset2, op) \
   do { \
     cpu_set_t* __dst = (dstset); \
@@ -140,12 +367,27 @@
       (__dst)->__bits[__nn] = __src1[__nn] op __src2[__nn]; \
   } while (0)
 
-#define CPU_COUNT_S(setsize, set)  __sched_cpucount((setsize), (set))
+/**
+ * [CPU_ALLOC_SIZE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * returns the size of a CPU set large enough for CPUs in the range 0..count-1.
+ */
+#define CPU_ALLOC_SIZE(count) \
+  __CPU_ELT((count) + (__CPU_BITS - 1)) * sizeof(__CPU_BITTYPE)
 
-int __sched_cpucount(size_t __set_size, const cpu_set_t* __set);
+/**
+ * [CPU_ALLOC](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * allocates a CPU set large enough for CPUs in the range 0..count-1.
+ */
+#define CPU_ALLOC(count)  __sched_cpualloc((count))
+cpu_set_t* __sched_cpualloc(size_t __count);
+
+/**
+ * [CPU_FREE](https://man7.org/linux/man-pages/man3/CPU_SET.3.html)
+ * deallocates a CPU set allocated by `CPU_ALLOC`.
+ */
+#define CPU_FREE(set)     __sched_cpufree((set))
+void __sched_cpufree(cpu_set_t* __set);
 
 #endif /* __USE_GNU */
 
 __END_DECLS
-
-#endif /* _SCHED_H_ */
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index 2e239bf..e445453 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -46,6 +46,8 @@
 #define POSIX_SPAWN_USEVFORK 64
 #define POSIX_SPAWN_SETSID 128
 #endif
+// mark all fds (except stdin/out/err) as close-on-exec prior to executing registered file actions
+#define POSIX_SPAWN_CLOEXEC_DEFAULT 256
 
 typedef struct __posix_spawnattr* posix_spawnattr_t;
 typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t;
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index d7fdb4a..4aa27f9 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -41,7 +41,7 @@
 #define EXIT_FAILURE 1
 #define EXIT_SUCCESS 0
 
-__noreturn void abort(void);
+__noreturn void abort(void) __attribute__((__nomerge__));
 __noreturn void exit(int __status);
 #if __ANDROID_API__ >= 21
 __noreturn void _Exit(int __status) __INTRODUCED_IN(21);
@@ -161,11 +161,11 @@
 void setprogname(const char* __name) __INTRODUCED_IN(21);
 
 int mblen(const char* __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26);
-size_t mbstowcs(wchar_t* __dst, const char* __src, size_t __n);
+size_t mbstowcs(wchar_t* __dst, const char* __src, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
 int mbtowc(wchar_t* __wc_ptr, const char* __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
 int wctomb(char* __dst, wchar_t __wc) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
 
-size_t wcstombs(char* __dst, const wchar_t* __src, size_t __n);
+size_t wcstombs(char* __dst, const wchar_t* __src, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(21);
 
 #if __ANDROID_API__ >= 21
 size_t __ctype_get_mb_cur_max(void) __INTRODUCED_IN(21);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 2556d11..5b9d99b 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -327,6 +327,8 @@
 
 #define __overloadable __attribute__((overloadable))
 
+#define __diagnose_as_builtin(...) __attribute__((diagnose_as_builtin(__VA_ARGS__)))
+
 /* Used to tag non-static symbols that are private and never exposed by the shared library. */
 #define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
 
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index 79fc28d..65571eb 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -101,31 +101,37 @@
 
 /**
  * [select(2)](http://man7.org/linux/man-pages/man2/select.2.html) waits on a
- * set of file descriptors. Use poll() instead.
+ * set of file descriptors.
+ *
+ * Use poll() instead.
  *
  * Returns the number of ready file descriptors on success, 0 for timeout,
  * and returns -1 and sets `errno` on failure.
  */
-int select(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout);
+int select(int __max_fd_plus_one, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout);
 
 /**
  * [pselect(2)](http://man7.org/linux/man-pages/man2/select.2.html) waits on a
- * set of file descriptors. Use ppoll() instead.
+ * set of file descriptors.
+ *
+ * Use ppoll() instead.
  *
  * Returns the number of ready file descriptors on success, 0 for timeout,
  * and returns -1 and sets `errno` on failure.
  */
-int pselect(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset_t* __mask);
+int pselect(int __max_fd_plus_one, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset_t* __mask);
 
 /**
  * [pselect64(2)](http://man7.org/linux/man-pages/man2/select.2.html) waits on a
- * set of file descriptors. Use ppoll64() instead.
+ * set of file descriptors.
+ *
+ * Use ppoll64() instead.
  *
  * Returns the number of ready file descriptors on success, 0 for timeout,
  * and returns -1 and sets `errno` on failure.
  *
  * Available since API level 28.
  */
-int pselect64(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset64_t* __mask) __INTRODUCED_IN(28);
+int pselect64(int __max_fd_plus_one, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset64_t* __mask) __INTRODUCED_IN(28);
 
 __END_DECLS
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 3ecbcce..f33f112 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -31,7 +31,6 @@
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
-#include <linux/socket.h>
 
 #include <asm/fcntl.h>
 #include <asm/socket.h>
@@ -71,6 +70,16 @@
   char sa_data[14];
 };
 
+struct sockaddr_storage {
+  union {
+    struct {
+      sa_family_t ss_family;
+      char __data[128 - sizeof(sa_family_t)];
+    };
+    void* __align;
+  };
+};
+
 struct linger {
   int l_onoff;
   int l_linger;
diff --git a/libc/include/sys/uio.h b/libc/include/sys/uio.h
index 37961e3..583cfc6 100644
--- a/libc/include/sys/uio.h
+++ b/libc/include/sys/uio.h
@@ -26,8 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_UIO_H_
-#define _SYS_UIO_H_
+#pragma once
+
+/**
+ * @file sys/uio.h
+ * @brief Multi-buffer ("vector") I/O operations using `struct iovec`.
+ */
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
@@ -35,21 +39,124 @@
 
 __BEGIN_DECLS
 
+/**
+ * [readv(2)](http://man7.org/linux/man-pages/man2/readv.2.html) reads
+ * from an fd into the `__count` buffers described by `__iov`.
+ *
+ * Returns the number of bytes read on success,
+ * and returns -1 and sets `errno` on failure.
+ */
 ssize_t readv(int __fd, const struct iovec* __iov, int __count);
+
+/**
+ * [writev(2)](http://man7.org/linux/man-pages/man2/writev.2.html) writes
+ * to an fd from the `__count` buffers described by `__iov`.
+ *
+ * Returns the number of bytes written on success,
+ * and returns -1 and sets `errno` on failure.
+ */
 ssize_t writev(int __fd, const struct iovec* __iov, int __count);
 
 #if defined(__USE_GNU)
-ssize_t preadv(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
-ssize_t pwritev(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
-ssize_t preadv64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
-ssize_t pwritev64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
-#endif
 
-#if defined(__USE_GNU)
+/**
+ * [preadv(2)](http://man7.org/linux/man-pages/man2/preadv.2.html) reads
+ * from an fd into the `__count` buffers described by `__iov`, starting at
+ * offset `__offset` into the file.
+ *
+ * Returns the number of bytes read on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 24.
+ */
+ssize_t preadv(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(preadv64) __INTRODUCED_IN(24);
+
+/**
+ * [pwritev(2)](http://man7.org/linux/man-pages/man2/pwritev.2.html) writes
+ * to an fd from the `__count` buffers described by `__iov`, starting at offset
+ * `__offset` into the file.
+ *
+ * Returns the number of bytes written on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 24.
+ */
+ssize_t pwritev(int __fd, const struct iovec* __iov, int __count, off_t __offset) __RENAME_IF_FILE_OFFSET64(pwritev64) __INTRODUCED_IN(24);
+
+/**
+ * Like preadv() but with a 64-bit offset even in a 32-bit process.
+ *
+ * Available since API level 24.
+ */
+ssize_t preadv64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+
+/**
+ * Like pwritev() but with a 64-bit offset even in a 32-bit process.
+ *
+ * Available since API level 24.
+ */
+ssize_t pwritev64(int __fd, const struct iovec* __iov, int __count, off64_t __offset) __INTRODUCED_IN(24);
+
+/**
+ * [preadv2(2)](http://man7.org/linux/man-pages/man2/preadv2.2.html) reads
+ * from an fd into the `__count` buffers described by `__iov`, starting at
+ * offset `__offset` into the file, with the given flags.
+ *
+ * Returns the number of bytes read on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 33.
+ */
+ssize_t preadv2(int __fd, const struct iovec* __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(preadv64v2) __INTRODUCED_IN(33);
+
+/**
+ * [pwritev2(2)](http://man7.org/linux/man-pages/man2/pwritev2.2.html) writes
+ * to an fd from the `__count` buffers described by `__iov`, starting at offset
+ * `__offset` into the file, with the given flags.
+ *
+ * Returns the number of bytes written on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 33.
+ */
+ssize_t pwritev2(int __fd, const struct iovec* __iov, int __count, off_t __offset, int __flags) __RENAME_IF_FILE_OFFSET64(pwritev64v2) __INTRODUCED_IN(33);
+
+/**
+ * Like preadv2() but with a 64-bit offset even in a 32-bit process.
+ *
+ * Available since API level 33.
+ */
+ssize_t preadv64v2(int __fd, const struct iovec* __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+
+/**
+ * Like pwritev2() but with a 64-bit offset even in a 32-bit process.
+ *
+ * Available since API level 33.
+ */
+ssize_t pwritev64v2(int __fd, const struct iovec* __iov, int __count, off64_t __offset, int __flags) __INTRODUCED_IN(33);
+
+/**
+ * [process_vm_readv(2)](http://man7.org/linux/man-pages/man2/process_vm_readv.2.html)
+ * reads from the address space of another process.
+ *
+ * Returns the number of bytes read on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 23.
+ */
 ssize_t process_vm_readv(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+
+/**
+ * [process_vm_writev(2)](http://man7.org/linux/man-pages/man2/process_vm_writev.2.html)
+ * writes to the address space of another process.
+ *
+ * Returns the number of bytes read on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 23.
+ */
 ssize_t process_vm_writev(pid_t __pid, const struct iovec* __local_iov, unsigned long __local_iov_count, const struct iovec* __remote_iov, unsigned long __remote_iov_count, unsigned long __flags) __INTRODUCED_IN(23);
+
 #endif
 
 __END_DECLS
-
-#endif
diff --git a/libc/kernel/android/scsi/scsi/scsi.h b/libc/kernel/android/scsi/scsi/scsi.h
index 2ea16a3..6d89fa9 100644
--- a/libc/kernel/android/scsi/scsi/scsi.h
+++ b/libc/kernel/android/scsi/scsi/scsi.h
@@ -20,6 +20,7 @@
 #define _SCSI_SCSI_H
 #include <linux/types.h>
 #include <scsi/scsi_proto.h>
+#include <scsi/scsi_status.h>
 struct ccs_modesel_head {
   __u8 _r1;
   __u8 medium;
@@ -34,40 +35,12 @@
   __u8 block_length_med;
   __u8 block_length_lo;
 };
-#define COMMAND_COMPLETE 0x00
-#define EXTENDED_MESSAGE 0x01
 #define EXTENDED_MODIFY_DATA_POINTER 0x00
 #define EXTENDED_SDTR 0x01
 #define EXTENDED_EXTENDED_IDENTIFY 0x02
 #define EXTENDED_WDTR 0x03
 #define EXTENDED_PPR 0x04
 #define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05
-#define SAVE_POINTERS 0x02
-#define RESTORE_POINTERS 0x03
-#define DISCONNECT 0x04
-#define INITIATOR_ERROR 0x05
-#define ABORT_TASK_SET 0x06
-#define MESSAGE_REJECT 0x07
-#define NOP 0x08
-#define MSG_PARITY_ERROR 0x09
-#define LINKED_CMD_COMPLETE 0x0a
-#define LINKED_FLG_CMD_COMPLETE 0x0b
-#define TARGET_RESET 0x0c
-#define ABORT_TASK 0x0d
-#define CLEAR_TASK_SET 0x0e
-#define INITIATE_RECOVERY 0x0f
-#define RELEASE_RECOVERY 0x10
-#define TERMINATE_IO_PROC 0x11
-#define CLEAR_ACA 0x16
-#define LOGICAL_UNIT_RESET 0x17
-#define SIMPLE_QUEUE_TAG 0x20
-#define HEAD_OF_QUEUE_TAG 0x21
-#define ORDERED_QUEUE_TAG 0x22
-#define IGNORE_WIDE_RESIDUE 0x23
-#define ACA 0x24
-#define QAS_REQUEST 0x55
-#define BUS_DEVICE_RESET TARGET_RESET
-#define ABORT ABORT_TASK_SET
 #define SCSI_IOCTL_GET_IDLUN 0x5382
 #define SCSI_IOCTL_PROBE_HOST 0x5385
 #define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
diff --git a/libc/kernel/android/scsi/scsi/scsi_proto.h b/libc/kernel/android/scsi/scsi/scsi_proto.h
index a77eded..eea87a0 100644
--- a/libc/kernel/android/scsi/scsi/scsi_proto.h
+++ b/libc/kernel/android/scsi/scsi/scsi_proto.h
@@ -124,17 +124,6 @@
 #define SERVICE_ACTION_BIDIRECTIONAL 0x9d
 #define SERVICE_ACTION_IN_16 0x9e
 #define SERVICE_ACTION_OUT_16 0x9f
-#define GOOD 0x00
-#define CHECK_CONDITION 0x01
-#define CONDITION_GOOD 0x02
-#define BUSY 0x04
-#define INTERMEDIATE_GOOD 0x08
-#define INTERMEDIATE_C_GOOD 0x0a
-#define RESERVATION_CONFLICT 0x0c
-#define COMMAND_TERMINATED 0x11
-#define QUEUE_FULL 0x14
-#define ACA_ACTIVE 0x18
-#define TASK_ABORTED 0x20
 #define STATUS_MASK 0xfe
 #define NO_SENSE 0x00
 #define RECOVERED_ERROR 0x01
@@ -205,4 +194,14 @@
   ZBC_ZONE_COND_FULL = 0xe,
   ZBC_ZONE_COND_OFFLINE = 0xf,
 };
+enum scsi_version_descriptor {
+  SCSI_VERSION_DESCRIPTOR_FCP4 = 0x0a40,
+  SCSI_VERSION_DESCRIPTOR_ISCSI = 0x0960,
+  SCSI_VERSION_DESCRIPTOR_SAM5 = 0x00a0,
+  SCSI_VERSION_DESCRIPTOR_SAS3 = 0x0c60,
+  SCSI_VERSION_DESCRIPTOR_SBC3 = 0x04c0,
+  SCSI_VERSION_DESCRIPTOR_SBP3 = 0x0980,
+  SCSI_VERSION_DESCRIPTOR_SPC4 = 0x0460,
+  SCSI_VERSION_DESCRIPTOR_SRP = 0x0940
+};
 #endif
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/android/scsi/scsi/scsi_status.h
similarity index 82%
rename from libc/kernel/uapi/linux/raw.h
rename to libc/kernel/android/scsi/scsi/scsi_status.h
index bb45c3d..6a7fc10 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/android/scsi/scsi/scsi_status.h
@@ -16,14 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
+#ifndef _SCSI_SCSI_STATUS_H
+#define _SCSI_SCSI_STATUS_H
 #include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
-};
+#include <scsi/scsi_proto.h>
 #endif
diff --git a/libc/kernel/android/scsi/scsi/sg.h b/libc/kernel/android/scsi/scsi/sg.h
index 828b2c6..a7a1944 100644
--- a/libc/kernel/android/scsi/scsi/sg.h
+++ b/libc/kernel/android/scsi/scsi/sg.h
@@ -66,6 +66,20 @@
 #define SG_INFO_INDIRECT_IO 0x0
 #define SG_INFO_DIRECT_IO 0x2
 #define SG_INFO_MIXED_IO 0x4
+#define DRIVER_SENSE 0x08
+#define driver_byte(result) (((result) >> 24) & 0xff)
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+#define ACA_ACTIVE 0x18
+#define TASK_ABORTED 0x20
+#define status_byte(result) (((result) >> 1) & 0x7f)
 typedef struct sg_scsi_id {
   int host_no;
   int channel;
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 5488641..26121ca 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1417,9 +1417,14 @@
                         if struct_name in kernel_struct_replacements:
                             extra_includes.append("<bits/%s.h>" % struct_name)
                             end = i + 2
-                            while end < len(b.tokens) and b.tokens[end].id != '}':
+                            depth = 1
+                            while end < len(b.tokens) and depth > 0:
+                                if b.tokens[end].id == '}':
+                                    depth -= 1
+                                elif b.tokens[end].id == '{':
+                                    depth += 1
                                 end += 1
-                            end += 1 # Swallow '}'
+                            end += 1 # Swallow last '}'
                             while end < len(b.tokens) and b.tokens[end].id != ';':
                                 end += 1
                             end += 1 # Swallow ';'
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 04eb5f1..2089285 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -89,8 +89,6 @@
     "udphdr": "__kernel_udphdr",
     # This causes problems when trying to export the headers for the ndk.
     "__attribute_const__": "__attribute__((__const__))",
-    # In this case the kernel tries to keep out of our way, but we're happy to use its definition.
-    "__kernel_sockaddr_storage": "sockaddr_storage",
     # The kernel started using struct __kernel_old_timeval in some places,
     # which is the exact same as struct timeval. Replace that name with
     # timeval so that kernel structures all use the same named structure.
diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py
index 6206248..f2e78da 100755
--- a/libc/kernel/tools/update_all.py
+++ b/libc/kernel/tools/update_all.py
@@ -84,7 +84,6 @@
     pattern = re.compile(r'^\s*#\s*define\s*__NR_([a-z_]\S+)')
     for unistd_h in ['kernel/uapi/asm-generic/unistd.h',
                      'kernel/uapi/asm-arm/asm/unistd.h',
-                     'kernel/uapi/asm-arm/asm/unistd-common.h',
                      'kernel/uapi/asm-arm/asm/unistd-eabi.h',
                      'kernel/uapi/asm-arm/asm/unistd-oabi.h',
                      'kernel/uapi/asm-x86/asm/unistd_32.h',
diff --git a/libc/kernel/uapi/asm-arm/asm/setup.h b/libc/kernel/uapi/asm-arm/asm/setup.h
index b4da2d1..672a72a 100644
--- a/libc/kernel/uapi/asm-arm/asm/setup.h
+++ b/libc/kernel/uapi/asm-arm/asm/setup.h
@@ -19,7 +19,7 @@
 #ifndef _UAPI__ASMARM_SETUP_H
 #define _UAPI__ASMARM_SETUP_H
 #include <linux/types.h>
-#define COMMAND_LINE_SIZE 2048
+#define COMMAND_LINE_SIZE 1024
 #define ATAG_NONE 0x00000000
 struct tag_header {
   __u32 size;
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-common.h b/libc/kernel/uapi/asm-arm/asm/unistd-common.h
deleted file mode 100644
index 070c77b..0000000
--- a/libc/kernel/uapi/asm-arm/asm/unistd-common.h
+++ /dev/null
@@ -1,417 +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_ASM_ARM_UNISTD_COMMON_H
-#define _UAPI_ASM_ARM_UNISTD_COMMON_H 1
-#define __NR_restart_syscall (__NR_SYSCALL_BASE + 0)
-#define __NR_exit (__NR_SYSCALL_BASE + 1)
-#define __NR_fork (__NR_SYSCALL_BASE + 2)
-#define __NR_read (__NR_SYSCALL_BASE + 3)
-#define __NR_write (__NR_SYSCALL_BASE + 4)
-#define __NR_open (__NR_SYSCALL_BASE + 5)
-#define __NR_close (__NR_SYSCALL_BASE + 6)
-#define __NR_creat (__NR_SYSCALL_BASE + 8)
-#define __NR_link (__NR_SYSCALL_BASE + 9)
-#define __NR_unlink (__NR_SYSCALL_BASE + 10)
-#define __NR_execve (__NR_SYSCALL_BASE + 11)
-#define __NR_chdir (__NR_SYSCALL_BASE + 12)
-#define __NR_mknod (__NR_SYSCALL_BASE + 14)
-#define __NR_chmod (__NR_SYSCALL_BASE + 15)
-#define __NR_lchown (__NR_SYSCALL_BASE + 16)
-#define __NR_lseek (__NR_SYSCALL_BASE + 19)
-#define __NR_getpid (__NR_SYSCALL_BASE + 20)
-#define __NR_mount (__NR_SYSCALL_BASE + 21)
-#define __NR_setuid (__NR_SYSCALL_BASE + 23)
-#define __NR_getuid (__NR_SYSCALL_BASE + 24)
-#define __NR_ptrace (__NR_SYSCALL_BASE + 26)
-#define __NR_pause (__NR_SYSCALL_BASE + 29)
-#define __NR_access (__NR_SYSCALL_BASE + 33)
-#define __NR_nice (__NR_SYSCALL_BASE + 34)
-#define __NR_sync (__NR_SYSCALL_BASE + 36)
-#define __NR_kill (__NR_SYSCALL_BASE + 37)
-#define __NR_rename (__NR_SYSCALL_BASE + 38)
-#define __NR_mkdir (__NR_SYSCALL_BASE + 39)
-#define __NR_rmdir (__NR_SYSCALL_BASE + 40)
-#define __NR_dup (__NR_SYSCALL_BASE + 41)
-#define __NR_pipe (__NR_SYSCALL_BASE + 42)
-#define __NR_times (__NR_SYSCALL_BASE + 43)
-#define __NR_brk (__NR_SYSCALL_BASE + 45)
-#define __NR_setgid (__NR_SYSCALL_BASE + 46)
-#define __NR_getgid (__NR_SYSCALL_BASE + 47)
-#define __NR_geteuid (__NR_SYSCALL_BASE + 49)
-#define __NR_getegid (__NR_SYSCALL_BASE + 50)
-#define __NR_acct (__NR_SYSCALL_BASE + 51)
-#define __NR_umount2 (__NR_SYSCALL_BASE + 52)
-#define __NR_ioctl (__NR_SYSCALL_BASE + 54)
-#define __NR_fcntl (__NR_SYSCALL_BASE + 55)
-#define __NR_setpgid (__NR_SYSCALL_BASE + 57)
-#define __NR_umask (__NR_SYSCALL_BASE + 60)
-#define __NR_chroot (__NR_SYSCALL_BASE + 61)
-#define __NR_ustat (__NR_SYSCALL_BASE + 62)
-#define __NR_dup2 (__NR_SYSCALL_BASE + 63)
-#define __NR_getppid (__NR_SYSCALL_BASE + 64)
-#define __NR_getpgrp (__NR_SYSCALL_BASE + 65)
-#define __NR_setsid (__NR_SYSCALL_BASE + 66)
-#define __NR_sigaction (__NR_SYSCALL_BASE + 67)
-#define __NR_setreuid (__NR_SYSCALL_BASE + 70)
-#define __NR_setregid (__NR_SYSCALL_BASE + 71)
-#define __NR_sigsuspend (__NR_SYSCALL_BASE + 72)
-#define __NR_sigpending (__NR_SYSCALL_BASE + 73)
-#define __NR_sethostname (__NR_SYSCALL_BASE + 74)
-#define __NR_setrlimit (__NR_SYSCALL_BASE + 75)
-#define __NR_getrusage (__NR_SYSCALL_BASE + 77)
-#define __NR_gettimeofday (__NR_SYSCALL_BASE + 78)
-#define __NR_settimeofday (__NR_SYSCALL_BASE + 79)
-#define __NR_getgroups (__NR_SYSCALL_BASE + 80)
-#define __NR_setgroups (__NR_SYSCALL_BASE + 81)
-#define __NR_symlink (__NR_SYSCALL_BASE + 83)
-#define __NR_readlink (__NR_SYSCALL_BASE + 85)
-#define __NR_uselib (__NR_SYSCALL_BASE + 86)
-#define __NR_swapon (__NR_SYSCALL_BASE + 87)
-#define __NR_reboot (__NR_SYSCALL_BASE + 88)
-#define __NR_munmap (__NR_SYSCALL_BASE + 91)
-#define __NR_truncate (__NR_SYSCALL_BASE + 92)
-#define __NR_ftruncate (__NR_SYSCALL_BASE + 93)
-#define __NR_fchmod (__NR_SYSCALL_BASE + 94)
-#define __NR_fchown (__NR_SYSCALL_BASE + 95)
-#define __NR_getpriority (__NR_SYSCALL_BASE + 96)
-#define __NR_setpriority (__NR_SYSCALL_BASE + 97)
-#define __NR_statfs (__NR_SYSCALL_BASE + 99)
-#define __NR_fstatfs (__NR_SYSCALL_BASE + 100)
-#define __NR_syslog (__NR_SYSCALL_BASE + 103)
-#define __NR_setitimer (__NR_SYSCALL_BASE + 104)
-#define __NR_getitimer (__NR_SYSCALL_BASE + 105)
-#define __NR_stat (__NR_SYSCALL_BASE + 106)
-#define __NR_lstat (__NR_SYSCALL_BASE + 107)
-#define __NR_fstat (__NR_SYSCALL_BASE + 108)
-#define __NR_vhangup (__NR_SYSCALL_BASE + 111)
-#define __NR_wait4 (__NR_SYSCALL_BASE + 114)
-#define __NR_swapoff (__NR_SYSCALL_BASE + 115)
-#define __NR_sysinfo (__NR_SYSCALL_BASE + 116)
-#define __NR_fsync (__NR_SYSCALL_BASE + 118)
-#define __NR_sigreturn (__NR_SYSCALL_BASE + 119)
-#define __NR_clone (__NR_SYSCALL_BASE + 120)
-#define __NR_setdomainname (__NR_SYSCALL_BASE + 121)
-#define __NR_uname (__NR_SYSCALL_BASE + 122)
-#define __NR_adjtimex (__NR_SYSCALL_BASE + 124)
-#define __NR_mprotect (__NR_SYSCALL_BASE + 125)
-#define __NR_sigprocmask (__NR_SYSCALL_BASE + 126)
-#define __NR_init_module (__NR_SYSCALL_BASE + 128)
-#define __NR_delete_module (__NR_SYSCALL_BASE + 129)
-#define __NR_quotactl (__NR_SYSCALL_BASE + 131)
-#define __NR_getpgid (__NR_SYSCALL_BASE + 132)
-#define __NR_fchdir (__NR_SYSCALL_BASE + 133)
-#define __NR_bdflush (__NR_SYSCALL_BASE + 134)
-#define __NR_sysfs (__NR_SYSCALL_BASE + 135)
-#define __NR_personality (__NR_SYSCALL_BASE + 136)
-#define __NR_setfsuid (__NR_SYSCALL_BASE + 138)
-#define __NR_setfsgid (__NR_SYSCALL_BASE + 139)
-#define __NR__llseek (__NR_SYSCALL_BASE + 140)
-#define __NR_getdents (__NR_SYSCALL_BASE + 141)
-#define __NR__newselect (__NR_SYSCALL_BASE + 142)
-#define __NR_flock (__NR_SYSCALL_BASE + 143)
-#define __NR_msync (__NR_SYSCALL_BASE + 144)
-#define __NR_readv (__NR_SYSCALL_BASE + 145)
-#define __NR_writev (__NR_SYSCALL_BASE + 146)
-#define __NR_getsid (__NR_SYSCALL_BASE + 147)
-#define __NR_fdatasync (__NR_SYSCALL_BASE + 148)
-#define __NR__sysctl (__NR_SYSCALL_BASE + 149)
-#define __NR_mlock (__NR_SYSCALL_BASE + 150)
-#define __NR_munlock (__NR_SYSCALL_BASE + 151)
-#define __NR_mlockall (__NR_SYSCALL_BASE + 152)
-#define __NR_munlockall (__NR_SYSCALL_BASE + 153)
-#define __NR_sched_setparam (__NR_SYSCALL_BASE + 154)
-#define __NR_sched_getparam (__NR_SYSCALL_BASE + 155)
-#define __NR_sched_setscheduler (__NR_SYSCALL_BASE + 156)
-#define __NR_sched_getscheduler (__NR_SYSCALL_BASE + 157)
-#define __NR_sched_yield (__NR_SYSCALL_BASE + 158)
-#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE + 159)
-#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE + 160)
-#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE + 161)
-#define __NR_nanosleep (__NR_SYSCALL_BASE + 162)
-#define __NR_mremap (__NR_SYSCALL_BASE + 163)
-#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
-#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
-#define __NR_poll (__NR_SYSCALL_BASE + 168)
-#define __NR_nfsservctl (__NR_SYSCALL_BASE + 169)
-#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
-#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
-#define __NR_prctl (__NR_SYSCALL_BASE + 172)
-#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
-#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
-#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
-#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
-#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE + 177)
-#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE + 178)
-#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
-#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
-#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
-#define __NR_chown (__NR_SYSCALL_BASE + 182)
-#define __NR_getcwd (__NR_SYSCALL_BASE + 183)
-#define __NR_capget (__NR_SYSCALL_BASE + 184)
-#define __NR_capset (__NR_SYSCALL_BASE + 185)
-#define __NR_sigaltstack (__NR_SYSCALL_BASE + 186)
-#define __NR_sendfile (__NR_SYSCALL_BASE + 187)
-#define __NR_vfork (__NR_SYSCALL_BASE + 190)
-#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
-#define __NR_mmap2 (__NR_SYSCALL_BASE + 192)
-#define __NR_truncate64 (__NR_SYSCALL_BASE + 193)
-#define __NR_ftruncate64 (__NR_SYSCALL_BASE + 194)
-#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
-#define __NR_lstat64 (__NR_SYSCALL_BASE + 196)
-#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
-#define __NR_lchown32 (__NR_SYSCALL_BASE + 198)
-#define __NR_getuid32 (__NR_SYSCALL_BASE + 199)
-#define __NR_getgid32 (__NR_SYSCALL_BASE + 200)
-#define __NR_geteuid32 (__NR_SYSCALL_BASE + 201)
-#define __NR_getegid32 (__NR_SYSCALL_BASE + 202)
-#define __NR_setreuid32 (__NR_SYSCALL_BASE + 203)
-#define __NR_setregid32 (__NR_SYSCALL_BASE + 204)
-#define __NR_getgroups32 (__NR_SYSCALL_BASE + 205)
-#define __NR_setgroups32 (__NR_SYSCALL_BASE + 206)
-#define __NR_fchown32 (__NR_SYSCALL_BASE + 207)
-#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
-#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
-#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
-#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
-#define __NR_chown32 (__NR_SYSCALL_BASE + 212)
-#define __NR_setuid32 (__NR_SYSCALL_BASE + 213)
-#define __NR_setgid32 (__NR_SYSCALL_BASE + 214)
-#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
-#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
-#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
-#define __NR_pivot_root (__NR_SYSCALL_BASE + 218)
-#define __NR_mincore (__NR_SYSCALL_BASE + 219)
-#define __NR_madvise (__NR_SYSCALL_BASE + 220)
-#define __NR_fcntl64 (__NR_SYSCALL_BASE + 221)
-#define __NR_gettid (__NR_SYSCALL_BASE + 224)
-#define __NR_readahead (__NR_SYSCALL_BASE + 225)
-#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
-#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
-#define __NR_fsetxattr (__NR_SYSCALL_BASE + 228)
-#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
-#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
-#define __NR_fgetxattr (__NR_SYSCALL_BASE + 231)
-#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
-#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
-#define __NR_flistxattr (__NR_SYSCALL_BASE + 234)
-#define __NR_removexattr (__NR_SYSCALL_BASE + 235)
-#define __NR_lremovexattr (__NR_SYSCALL_BASE + 236)
-#define __NR_fremovexattr (__NR_SYSCALL_BASE + 237)
-#define __NR_tkill (__NR_SYSCALL_BASE + 238)
-#define __NR_sendfile64 (__NR_SYSCALL_BASE + 239)
-#define __NR_futex (__NR_SYSCALL_BASE + 240)
-#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
-#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
-#define __NR_io_setup (__NR_SYSCALL_BASE + 243)
-#define __NR_io_destroy (__NR_SYSCALL_BASE + 244)
-#define __NR_io_getevents (__NR_SYSCALL_BASE + 245)
-#define __NR_io_submit (__NR_SYSCALL_BASE + 246)
-#define __NR_io_cancel (__NR_SYSCALL_BASE + 247)
-#define __NR_exit_group (__NR_SYSCALL_BASE + 248)
-#define __NR_lookup_dcookie (__NR_SYSCALL_BASE + 249)
-#define __NR_epoll_create (__NR_SYSCALL_BASE + 250)
-#define __NR_epoll_ctl (__NR_SYSCALL_BASE + 251)
-#define __NR_epoll_wait (__NR_SYSCALL_BASE + 252)
-#define __NR_remap_file_pages (__NR_SYSCALL_BASE + 253)
-#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
-#define __NR_timer_create (__NR_SYSCALL_BASE + 257)
-#define __NR_timer_settime (__NR_SYSCALL_BASE + 258)
-#define __NR_timer_gettime (__NR_SYSCALL_BASE + 259)
-#define __NR_timer_getoverrun (__NR_SYSCALL_BASE + 260)
-#define __NR_timer_delete (__NR_SYSCALL_BASE + 261)
-#define __NR_clock_settime (__NR_SYSCALL_BASE + 262)
-#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
-#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
-#define __NR_clock_nanosleep (__NR_SYSCALL_BASE + 265)
-#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
-#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
-#define __NR_tgkill (__NR_SYSCALL_BASE + 268)
-#define __NR_utimes (__NR_SYSCALL_BASE + 269)
-#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE + 270)
-#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE + 271)
-#define __NR_pciconfig_read (__NR_SYSCALL_BASE + 272)
-#define __NR_pciconfig_write (__NR_SYSCALL_BASE + 273)
-#define __NR_mq_open (__NR_SYSCALL_BASE + 274)
-#define __NR_mq_unlink (__NR_SYSCALL_BASE + 275)
-#define __NR_mq_timedsend (__NR_SYSCALL_BASE + 276)
-#define __NR_mq_timedreceive (__NR_SYSCALL_BASE + 277)
-#define __NR_mq_notify (__NR_SYSCALL_BASE + 278)
-#define __NR_mq_getsetattr (__NR_SYSCALL_BASE + 279)
-#define __NR_waitid (__NR_SYSCALL_BASE + 280)
-#define __NR_socket (__NR_SYSCALL_BASE + 281)
-#define __NR_bind (__NR_SYSCALL_BASE + 282)
-#define __NR_connect (__NR_SYSCALL_BASE + 283)
-#define __NR_listen (__NR_SYSCALL_BASE + 284)
-#define __NR_accept (__NR_SYSCALL_BASE + 285)
-#define __NR_getsockname (__NR_SYSCALL_BASE + 286)
-#define __NR_getpeername (__NR_SYSCALL_BASE + 287)
-#define __NR_socketpair (__NR_SYSCALL_BASE + 288)
-#define __NR_send (__NR_SYSCALL_BASE + 289)
-#define __NR_sendto (__NR_SYSCALL_BASE + 290)
-#define __NR_recv (__NR_SYSCALL_BASE + 291)
-#define __NR_recvfrom (__NR_SYSCALL_BASE + 292)
-#define __NR_shutdown (__NR_SYSCALL_BASE + 293)
-#define __NR_setsockopt (__NR_SYSCALL_BASE + 294)
-#define __NR_getsockopt (__NR_SYSCALL_BASE + 295)
-#define __NR_sendmsg (__NR_SYSCALL_BASE + 296)
-#define __NR_recvmsg (__NR_SYSCALL_BASE + 297)
-#define __NR_semop (__NR_SYSCALL_BASE + 298)
-#define __NR_semget (__NR_SYSCALL_BASE + 299)
-#define __NR_semctl (__NR_SYSCALL_BASE + 300)
-#define __NR_msgsnd (__NR_SYSCALL_BASE + 301)
-#define __NR_msgrcv (__NR_SYSCALL_BASE + 302)
-#define __NR_msgget (__NR_SYSCALL_BASE + 303)
-#define __NR_msgctl (__NR_SYSCALL_BASE + 304)
-#define __NR_shmat (__NR_SYSCALL_BASE + 305)
-#define __NR_shmdt (__NR_SYSCALL_BASE + 306)
-#define __NR_shmget (__NR_SYSCALL_BASE + 307)
-#define __NR_shmctl (__NR_SYSCALL_BASE + 308)
-#define __NR_add_key (__NR_SYSCALL_BASE + 309)
-#define __NR_request_key (__NR_SYSCALL_BASE + 310)
-#define __NR_keyctl (__NR_SYSCALL_BASE + 311)
-#define __NR_semtimedop (__NR_SYSCALL_BASE + 312)
-#define __NR_vserver (__NR_SYSCALL_BASE + 313)
-#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
-#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
-#define __NR_inotify_init (__NR_SYSCALL_BASE + 316)
-#define __NR_inotify_add_watch (__NR_SYSCALL_BASE + 317)
-#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE + 318)
-#define __NR_mbind (__NR_SYSCALL_BASE + 319)
-#define __NR_get_mempolicy (__NR_SYSCALL_BASE + 320)
-#define __NR_set_mempolicy (__NR_SYSCALL_BASE + 321)
-#define __NR_openat (__NR_SYSCALL_BASE + 322)
-#define __NR_mkdirat (__NR_SYSCALL_BASE + 323)
-#define __NR_mknodat (__NR_SYSCALL_BASE + 324)
-#define __NR_fchownat (__NR_SYSCALL_BASE + 325)
-#define __NR_futimesat (__NR_SYSCALL_BASE + 326)
-#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
-#define __NR_unlinkat (__NR_SYSCALL_BASE + 328)
-#define __NR_renameat (__NR_SYSCALL_BASE + 329)
-#define __NR_linkat (__NR_SYSCALL_BASE + 330)
-#define __NR_symlinkat (__NR_SYSCALL_BASE + 331)
-#define __NR_readlinkat (__NR_SYSCALL_BASE + 332)
-#define __NR_fchmodat (__NR_SYSCALL_BASE + 333)
-#define __NR_faccessat (__NR_SYSCALL_BASE + 334)
-#define __NR_pselect6 (__NR_SYSCALL_BASE + 335)
-#define __NR_ppoll (__NR_SYSCALL_BASE + 336)
-#define __NR_unshare (__NR_SYSCALL_BASE + 337)
-#define __NR_set_robust_list (__NR_SYSCALL_BASE + 338)
-#define __NR_get_robust_list (__NR_SYSCALL_BASE + 339)
-#define __NR_splice (__NR_SYSCALL_BASE + 340)
-#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE + 341)
-#define __NR_tee (__NR_SYSCALL_BASE + 342)
-#define __NR_vmsplice (__NR_SYSCALL_BASE + 343)
-#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
-#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
-#define __NR_epoll_pwait (__NR_SYSCALL_BASE + 346)
-#define __NR_kexec_load (__NR_SYSCALL_BASE + 347)
-#define __NR_utimensat (__NR_SYSCALL_BASE + 348)
-#define __NR_signalfd (__NR_SYSCALL_BASE + 349)
-#define __NR_timerfd_create (__NR_SYSCALL_BASE + 350)
-#define __NR_eventfd (__NR_SYSCALL_BASE + 351)
-#define __NR_fallocate (__NR_SYSCALL_BASE + 352)
-#define __NR_timerfd_settime (__NR_SYSCALL_BASE + 353)
-#define __NR_timerfd_gettime (__NR_SYSCALL_BASE + 354)
-#define __NR_signalfd4 (__NR_SYSCALL_BASE + 355)
-#define __NR_eventfd2 (__NR_SYSCALL_BASE + 356)
-#define __NR_epoll_create1 (__NR_SYSCALL_BASE + 357)
-#define __NR_dup3 (__NR_SYSCALL_BASE + 358)
-#define __NR_pipe2 (__NR_SYSCALL_BASE + 359)
-#define __NR_inotify_init1 (__NR_SYSCALL_BASE + 360)
-#define __NR_preadv (__NR_SYSCALL_BASE + 361)
-#define __NR_pwritev (__NR_SYSCALL_BASE + 362)
-#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE + 363)
-#define __NR_perf_event_open (__NR_SYSCALL_BASE + 364)
-#define __NR_recvmmsg (__NR_SYSCALL_BASE + 365)
-#define __NR_accept4 (__NR_SYSCALL_BASE + 366)
-#define __NR_fanotify_init (__NR_SYSCALL_BASE + 367)
-#define __NR_fanotify_mark (__NR_SYSCALL_BASE + 368)
-#define __NR_prlimit64 (__NR_SYSCALL_BASE + 369)
-#define __NR_name_to_handle_at (__NR_SYSCALL_BASE + 370)
-#define __NR_open_by_handle_at (__NR_SYSCALL_BASE + 371)
-#define __NR_clock_adjtime (__NR_SYSCALL_BASE + 372)
-#define __NR_syncfs (__NR_SYSCALL_BASE + 373)
-#define __NR_sendmmsg (__NR_SYSCALL_BASE + 374)
-#define __NR_setns (__NR_SYSCALL_BASE + 375)
-#define __NR_process_vm_readv (__NR_SYSCALL_BASE + 376)
-#define __NR_process_vm_writev (__NR_SYSCALL_BASE + 377)
-#define __NR_kcmp (__NR_SYSCALL_BASE + 378)
-#define __NR_finit_module (__NR_SYSCALL_BASE + 379)
-#define __NR_sched_setattr (__NR_SYSCALL_BASE + 380)
-#define __NR_sched_getattr (__NR_SYSCALL_BASE + 381)
-#define __NR_renameat2 (__NR_SYSCALL_BASE + 382)
-#define __NR_seccomp (__NR_SYSCALL_BASE + 383)
-#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
-#define __NR_memfd_create (__NR_SYSCALL_BASE + 385)
-#define __NR_bpf (__NR_SYSCALL_BASE + 386)
-#define __NR_execveat (__NR_SYSCALL_BASE + 387)
-#define __NR_userfaultfd (__NR_SYSCALL_BASE + 388)
-#define __NR_membarrier (__NR_SYSCALL_BASE + 389)
-#define __NR_mlock2 (__NR_SYSCALL_BASE + 390)
-#define __NR_copy_file_range (__NR_SYSCALL_BASE + 391)
-#define __NR_preadv2 (__NR_SYSCALL_BASE + 392)
-#define __NR_pwritev2 (__NR_SYSCALL_BASE + 393)
-#define __NR_pkey_mprotect (__NR_SYSCALL_BASE + 394)
-#define __NR_pkey_alloc (__NR_SYSCALL_BASE + 395)
-#define __NR_pkey_free (__NR_SYSCALL_BASE + 396)
-#define __NR_statx (__NR_SYSCALL_BASE + 397)
-#define __NR_rseq (__NR_SYSCALL_BASE + 398)
-#define __NR_io_pgetevents (__NR_SYSCALL_BASE + 399)
-#define __NR_migrate_pages (__NR_SYSCALL_BASE + 400)
-#define __NR_kexec_file_load (__NR_SYSCALL_BASE + 401)
-#define __NR_clock_gettime64 (__NR_SYSCALL_BASE + 403)
-#define __NR_clock_settime64 (__NR_SYSCALL_BASE + 404)
-#define __NR_clock_adjtime64 (__NR_SYSCALL_BASE + 405)
-#define __NR_clock_getres_time64 (__NR_SYSCALL_BASE + 406)
-#define __NR_clock_nanosleep_time64 (__NR_SYSCALL_BASE + 407)
-#define __NR_timer_gettime64 (__NR_SYSCALL_BASE + 408)
-#define __NR_timer_settime64 (__NR_SYSCALL_BASE + 409)
-#define __NR_timerfd_gettime64 (__NR_SYSCALL_BASE + 410)
-#define __NR_timerfd_settime64 (__NR_SYSCALL_BASE + 411)
-#define __NR_utimensat_time64 (__NR_SYSCALL_BASE + 412)
-#define __NR_pselect6_time64 (__NR_SYSCALL_BASE + 413)
-#define __NR_ppoll_time64 (__NR_SYSCALL_BASE + 414)
-#define __NR_io_pgetevents_time64 (__NR_SYSCALL_BASE + 416)
-#define __NR_recvmmsg_time64 (__NR_SYSCALL_BASE + 417)
-#define __NR_mq_timedsend_time64 (__NR_SYSCALL_BASE + 418)
-#define __NR_mq_timedreceive_time64 (__NR_SYSCALL_BASE + 419)
-#define __NR_semtimedop_time64 (__NR_SYSCALL_BASE + 420)
-#define __NR_rt_sigtimedwait_time64 (__NR_SYSCALL_BASE + 421)
-#define __NR_futex_time64 (__NR_SYSCALL_BASE + 422)
-#define __NR_sched_rr_get_interval_time64 (__NR_SYSCALL_BASE + 423)
-#define __NR_pidfd_send_signal (__NR_SYSCALL_BASE + 424)
-#define __NR_io_uring_setup (__NR_SYSCALL_BASE + 425)
-#define __NR_io_uring_enter (__NR_SYSCALL_BASE + 426)
-#define __NR_io_uring_register (__NR_SYSCALL_BASE + 427)
-#define __NR_open_tree (__NR_SYSCALL_BASE + 428)
-#define __NR_move_mount (__NR_SYSCALL_BASE + 429)
-#define __NR_fsopen (__NR_SYSCALL_BASE + 430)
-#define __NR_fsconfig (__NR_SYSCALL_BASE + 431)
-#define __NR_fsmount (__NR_SYSCALL_BASE + 432)
-#define __NR_fspick (__NR_SYSCALL_BASE + 433)
-#define __NR_pidfd_open (__NR_SYSCALL_BASE + 434)
-#define __NR_clone3 (__NR_SYSCALL_BASE + 435)
-#define __NR_close_range (__NR_SYSCALL_BASE + 436)
-#define __NR_openat2 (__NR_SYSCALL_BASE + 437)
-#define __NR_pidfd_getfd (__NR_SYSCALL_BASE + 438)
-#define __NR_faccessat2 (__NR_SYSCALL_BASE + 439)
-#define __NR_process_madvise (__NR_SYSCALL_BASE + 440)
-#define __NR_epoll_pwait2 (__NR_SYSCALL_BASE + 441)
-#define __NR_mount_setattr (__NR_SYSCALL_BASE + 442)
-#endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
index 54e1867..71b25e7 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
@@ -16,6 +16,409 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _UAPI_ASM_ARM_UNISTD_EABI_H
-#define _UAPI_ASM_ARM_UNISTD_EABI_H 1
+#ifndef _UAPI_ASM_UNISTD_EABI_H
+#define _UAPI_ASM_UNISTD_EABI_H
+#define __NR_restart_syscall (__NR_SYSCALL_BASE + 0)
+#define __NR_exit (__NR_SYSCALL_BASE + 1)
+#define __NR_fork (__NR_SYSCALL_BASE + 2)
+#define __NR_read (__NR_SYSCALL_BASE + 3)
+#define __NR_write (__NR_SYSCALL_BASE + 4)
+#define __NR_open (__NR_SYSCALL_BASE + 5)
+#define __NR_close (__NR_SYSCALL_BASE + 6)
+#define __NR_creat (__NR_SYSCALL_BASE + 8)
+#define __NR_link (__NR_SYSCALL_BASE + 9)
+#define __NR_unlink (__NR_SYSCALL_BASE + 10)
+#define __NR_execve (__NR_SYSCALL_BASE + 11)
+#define __NR_chdir (__NR_SYSCALL_BASE + 12)
+#define __NR_mknod (__NR_SYSCALL_BASE + 14)
+#define __NR_chmod (__NR_SYSCALL_BASE + 15)
+#define __NR_lchown (__NR_SYSCALL_BASE + 16)
+#define __NR_lseek (__NR_SYSCALL_BASE + 19)
+#define __NR_getpid (__NR_SYSCALL_BASE + 20)
+#define __NR_mount (__NR_SYSCALL_BASE + 21)
+#define __NR_setuid (__NR_SYSCALL_BASE + 23)
+#define __NR_getuid (__NR_SYSCALL_BASE + 24)
+#define __NR_ptrace (__NR_SYSCALL_BASE + 26)
+#define __NR_pause (__NR_SYSCALL_BASE + 29)
+#define __NR_access (__NR_SYSCALL_BASE + 33)
+#define __NR_nice (__NR_SYSCALL_BASE + 34)
+#define __NR_sync (__NR_SYSCALL_BASE + 36)
+#define __NR_kill (__NR_SYSCALL_BASE + 37)
+#define __NR_rename (__NR_SYSCALL_BASE + 38)
+#define __NR_mkdir (__NR_SYSCALL_BASE + 39)
+#define __NR_rmdir (__NR_SYSCALL_BASE + 40)
+#define __NR_dup (__NR_SYSCALL_BASE + 41)
+#define __NR_pipe (__NR_SYSCALL_BASE + 42)
+#define __NR_times (__NR_SYSCALL_BASE + 43)
+#define __NR_brk (__NR_SYSCALL_BASE + 45)
+#define __NR_setgid (__NR_SYSCALL_BASE + 46)
+#define __NR_getgid (__NR_SYSCALL_BASE + 47)
+#define __NR_geteuid (__NR_SYSCALL_BASE + 49)
+#define __NR_getegid (__NR_SYSCALL_BASE + 50)
+#define __NR_acct (__NR_SYSCALL_BASE + 51)
+#define __NR_umount2 (__NR_SYSCALL_BASE + 52)
+#define __NR_ioctl (__NR_SYSCALL_BASE + 54)
+#define __NR_fcntl (__NR_SYSCALL_BASE + 55)
+#define __NR_setpgid (__NR_SYSCALL_BASE + 57)
+#define __NR_umask (__NR_SYSCALL_BASE + 60)
+#define __NR_chroot (__NR_SYSCALL_BASE + 61)
+#define __NR_ustat (__NR_SYSCALL_BASE + 62)
+#define __NR_dup2 (__NR_SYSCALL_BASE + 63)
+#define __NR_getppid (__NR_SYSCALL_BASE + 64)
+#define __NR_getpgrp (__NR_SYSCALL_BASE + 65)
+#define __NR_setsid (__NR_SYSCALL_BASE + 66)
+#define __NR_sigaction (__NR_SYSCALL_BASE + 67)
+#define __NR_setreuid (__NR_SYSCALL_BASE + 70)
+#define __NR_setregid (__NR_SYSCALL_BASE + 71)
+#define __NR_sigsuspend (__NR_SYSCALL_BASE + 72)
+#define __NR_sigpending (__NR_SYSCALL_BASE + 73)
+#define __NR_sethostname (__NR_SYSCALL_BASE + 74)
+#define __NR_setrlimit (__NR_SYSCALL_BASE + 75)
+#define __NR_getrusage (__NR_SYSCALL_BASE + 77)
+#define __NR_gettimeofday (__NR_SYSCALL_BASE + 78)
+#define __NR_settimeofday (__NR_SYSCALL_BASE + 79)
+#define __NR_getgroups (__NR_SYSCALL_BASE + 80)
+#define __NR_setgroups (__NR_SYSCALL_BASE + 81)
+#define __NR_symlink (__NR_SYSCALL_BASE + 83)
+#define __NR_readlink (__NR_SYSCALL_BASE + 85)
+#define __NR_uselib (__NR_SYSCALL_BASE + 86)
+#define __NR_swapon (__NR_SYSCALL_BASE + 87)
+#define __NR_reboot (__NR_SYSCALL_BASE + 88)
+#define __NR_munmap (__NR_SYSCALL_BASE + 91)
+#define __NR_truncate (__NR_SYSCALL_BASE + 92)
+#define __NR_ftruncate (__NR_SYSCALL_BASE + 93)
+#define __NR_fchmod (__NR_SYSCALL_BASE + 94)
+#define __NR_fchown (__NR_SYSCALL_BASE + 95)
+#define __NR_getpriority (__NR_SYSCALL_BASE + 96)
+#define __NR_setpriority (__NR_SYSCALL_BASE + 97)
+#define __NR_statfs (__NR_SYSCALL_BASE + 99)
+#define __NR_fstatfs (__NR_SYSCALL_BASE + 100)
+#define __NR_syslog (__NR_SYSCALL_BASE + 103)
+#define __NR_setitimer (__NR_SYSCALL_BASE + 104)
+#define __NR_getitimer (__NR_SYSCALL_BASE + 105)
+#define __NR_stat (__NR_SYSCALL_BASE + 106)
+#define __NR_lstat (__NR_SYSCALL_BASE + 107)
+#define __NR_fstat (__NR_SYSCALL_BASE + 108)
+#define __NR_vhangup (__NR_SYSCALL_BASE + 111)
+#define __NR_wait4 (__NR_SYSCALL_BASE + 114)
+#define __NR_swapoff (__NR_SYSCALL_BASE + 115)
+#define __NR_sysinfo (__NR_SYSCALL_BASE + 116)
+#define __NR_fsync (__NR_SYSCALL_BASE + 118)
+#define __NR_sigreturn (__NR_SYSCALL_BASE + 119)
+#define __NR_clone (__NR_SYSCALL_BASE + 120)
+#define __NR_setdomainname (__NR_SYSCALL_BASE + 121)
+#define __NR_uname (__NR_SYSCALL_BASE + 122)
+#define __NR_adjtimex (__NR_SYSCALL_BASE + 124)
+#define __NR_mprotect (__NR_SYSCALL_BASE + 125)
+#define __NR_sigprocmask (__NR_SYSCALL_BASE + 126)
+#define __NR_init_module (__NR_SYSCALL_BASE + 128)
+#define __NR_delete_module (__NR_SYSCALL_BASE + 129)
+#define __NR_quotactl (__NR_SYSCALL_BASE + 131)
+#define __NR_getpgid (__NR_SYSCALL_BASE + 132)
+#define __NR_fchdir (__NR_SYSCALL_BASE + 133)
+#define __NR_bdflush (__NR_SYSCALL_BASE + 134)
+#define __NR_sysfs (__NR_SYSCALL_BASE + 135)
+#define __NR_personality (__NR_SYSCALL_BASE + 136)
+#define __NR_setfsuid (__NR_SYSCALL_BASE + 138)
+#define __NR_setfsgid (__NR_SYSCALL_BASE + 139)
+#define __NR__llseek (__NR_SYSCALL_BASE + 140)
+#define __NR_getdents (__NR_SYSCALL_BASE + 141)
+#define __NR__newselect (__NR_SYSCALL_BASE + 142)
+#define __NR_flock (__NR_SYSCALL_BASE + 143)
+#define __NR_msync (__NR_SYSCALL_BASE + 144)
+#define __NR_readv (__NR_SYSCALL_BASE + 145)
+#define __NR_writev (__NR_SYSCALL_BASE + 146)
+#define __NR_getsid (__NR_SYSCALL_BASE + 147)
+#define __NR_fdatasync (__NR_SYSCALL_BASE + 148)
+#define __NR__sysctl (__NR_SYSCALL_BASE + 149)
+#define __NR_mlock (__NR_SYSCALL_BASE + 150)
+#define __NR_munlock (__NR_SYSCALL_BASE + 151)
+#define __NR_mlockall (__NR_SYSCALL_BASE + 152)
+#define __NR_munlockall (__NR_SYSCALL_BASE + 153)
+#define __NR_sched_setparam (__NR_SYSCALL_BASE + 154)
+#define __NR_sched_getparam (__NR_SYSCALL_BASE + 155)
+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE + 156)
+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE + 157)
+#define __NR_sched_yield (__NR_SYSCALL_BASE + 158)
+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE + 159)
+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE + 160)
+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE + 161)
+#define __NR_nanosleep (__NR_SYSCALL_BASE + 162)
+#define __NR_mremap (__NR_SYSCALL_BASE + 163)
+#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
+#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
+#define __NR_poll (__NR_SYSCALL_BASE + 168)
+#define __NR_nfsservctl (__NR_SYSCALL_BASE + 169)
+#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
+#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
+#define __NR_prctl (__NR_SYSCALL_BASE + 172)
+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
+#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
+#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE + 177)
+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE + 178)
+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
+#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
+#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
+#define __NR_chown (__NR_SYSCALL_BASE + 182)
+#define __NR_getcwd (__NR_SYSCALL_BASE + 183)
+#define __NR_capget (__NR_SYSCALL_BASE + 184)
+#define __NR_capset (__NR_SYSCALL_BASE + 185)
+#define __NR_sigaltstack (__NR_SYSCALL_BASE + 186)
+#define __NR_sendfile (__NR_SYSCALL_BASE + 187)
+#define __NR_vfork (__NR_SYSCALL_BASE + 190)
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
+#define __NR_mmap2 (__NR_SYSCALL_BASE + 192)
+#define __NR_truncate64 (__NR_SYSCALL_BASE + 193)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE + 194)
+#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
+#define __NR_lstat64 (__NR_SYSCALL_BASE + 196)
+#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
+#define __NR_lchown32 (__NR_SYSCALL_BASE + 198)
+#define __NR_getuid32 (__NR_SYSCALL_BASE + 199)
+#define __NR_getgid32 (__NR_SYSCALL_BASE + 200)
+#define __NR_geteuid32 (__NR_SYSCALL_BASE + 201)
+#define __NR_getegid32 (__NR_SYSCALL_BASE + 202)
+#define __NR_setreuid32 (__NR_SYSCALL_BASE + 203)
+#define __NR_setregid32 (__NR_SYSCALL_BASE + 204)
+#define __NR_getgroups32 (__NR_SYSCALL_BASE + 205)
+#define __NR_setgroups32 (__NR_SYSCALL_BASE + 206)
+#define __NR_fchown32 (__NR_SYSCALL_BASE + 207)
+#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
+#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
+#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
+#define __NR_chown32 (__NR_SYSCALL_BASE + 212)
+#define __NR_setuid32 (__NR_SYSCALL_BASE + 213)
+#define __NR_setgid32 (__NR_SYSCALL_BASE + 214)
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
+#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
+#define __NR_pivot_root (__NR_SYSCALL_BASE + 218)
+#define __NR_mincore (__NR_SYSCALL_BASE + 219)
+#define __NR_madvise (__NR_SYSCALL_BASE + 220)
+#define __NR_fcntl64 (__NR_SYSCALL_BASE + 221)
+#define __NR_gettid (__NR_SYSCALL_BASE + 224)
+#define __NR_readahead (__NR_SYSCALL_BASE + 225)
+#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
+#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
+#define __NR_fsetxattr (__NR_SYSCALL_BASE + 228)
+#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
+#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
+#define __NR_fgetxattr (__NR_SYSCALL_BASE + 231)
+#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
+#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
+#define __NR_flistxattr (__NR_SYSCALL_BASE + 234)
+#define __NR_removexattr (__NR_SYSCALL_BASE + 235)
+#define __NR_lremovexattr (__NR_SYSCALL_BASE + 236)
+#define __NR_fremovexattr (__NR_SYSCALL_BASE + 237)
+#define __NR_tkill (__NR_SYSCALL_BASE + 238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE + 239)
+#define __NR_futex (__NR_SYSCALL_BASE + 240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
+#define __NR_io_setup (__NR_SYSCALL_BASE + 243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE + 244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE + 245)
+#define __NR_io_submit (__NR_SYSCALL_BASE + 246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE + 247)
+#define __NR_exit_group (__NR_SYSCALL_BASE + 248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE + 249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE + 250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE + 251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE + 252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE + 253)
+#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
+#define __NR_timer_create (__NR_SYSCALL_BASE + 257)
+#define __NR_timer_settime (__NR_SYSCALL_BASE + 258)
+#define __NR_timer_gettime (__NR_SYSCALL_BASE + 259)
+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE + 260)
+#define __NR_timer_delete (__NR_SYSCALL_BASE + 261)
+#define __NR_clock_settime (__NR_SYSCALL_BASE + 262)
+#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
+#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE + 265)
+#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
+#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
+#define __NR_tgkill (__NR_SYSCALL_BASE + 268)
+#define __NR_utimes (__NR_SYSCALL_BASE + 269)
+#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE + 270)
+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE + 271)
+#define __NR_pciconfig_read (__NR_SYSCALL_BASE + 272)
+#define __NR_pciconfig_write (__NR_SYSCALL_BASE + 273)
+#define __NR_mq_open (__NR_SYSCALL_BASE + 274)
+#define __NR_mq_unlink (__NR_SYSCALL_BASE + 275)
+#define __NR_mq_timedsend (__NR_SYSCALL_BASE + 276)
+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE + 277)
+#define __NR_mq_notify (__NR_SYSCALL_BASE + 278)
+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE + 279)
+#define __NR_waitid (__NR_SYSCALL_BASE + 280)
+#define __NR_socket (__NR_SYSCALL_BASE + 281)
+#define __NR_bind (__NR_SYSCALL_BASE + 282)
+#define __NR_connect (__NR_SYSCALL_BASE + 283)
+#define __NR_listen (__NR_SYSCALL_BASE + 284)
+#define __NR_accept (__NR_SYSCALL_BASE + 285)
+#define __NR_getsockname (__NR_SYSCALL_BASE + 286)
+#define __NR_getpeername (__NR_SYSCALL_BASE + 287)
+#define __NR_socketpair (__NR_SYSCALL_BASE + 288)
+#define __NR_send (__NR_SYSCALL_BASE + 289)
+#define __NR_sendto (__NR_SYSCALL_BASE + 290)
+#define __NR_recv (__NR_SYSCALL_BASE + 291)
+#define __NR_recvfrom (__NR_SYSCALL_BASE + 292)
+#define __NR_shutdown (__NR_SYSCALL_BASE + 293)
+#define __NR_setsockopt (__NR_SYSCALL_BASE + 294)
+#define __NR_getsockopt (__NR_SYSCALL_BASE + 295)
+#define __NR_sendmsg (__NR_SYSCALL_BASE + 296)
+#define __NR_recvmsg (__NR_SYSCALL_BASE + 297)
+#define __NR_semop (__NR_SYSCALL_BASE + 298)
+#define __NR_semget (__NR_SYSCALL_BASE + 299)
+#define __NR_semctl (__NR_SYSCALL_BASE + 300)
+#define __NR_msgsnd (__NR_SYSCALL_BASE + 301)
+#define __NR_msgrcv (__NR_SYSCALL_BASE + 302)
+#define __NR_msgget (__NR_SYSCALL_BASE + 303)
+#define __NR_msgctl (__NR_SYSCALL_BASE + 304)
+#define __NR_shmat (__NR_SYSCALL_BASE + 305)
+#define __NR_shmdt (__NR_SYSCALL_BASE + 306)
+#define __NR_shmget (__NR_SYSCALL_BASE + 307)
+#define __NR_shmctl (__NR_SYSCALL_BASE + 308)
+#define __NR_add_key (__NR_SYSCALL_BASE + 309)
+#define __NR_request_key (__NR_SYSCALL_BASE + 310)
+#define __NR_keyctl (__NR_SYSCALL_BASE + 311)
+#define __NR_semtimedop (__NR_SYSCALL_BASE + 312)
+#define __NR_vserver (__NR_SYSCALL_BASE + 313)
+#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
+#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
+#define __NR_inotify_init (__NR_SYSCALL_BASE + 316)
+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE + 317)
+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE + 318)
+#define __NR_mbind (__NR_SYSCALL_BASE + 319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE + 320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE + 321)
+#define __NR_openat (__NR_SYSCALL_BASE + 322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE + 323)
+#define __NR_mknodat (__NR_SYSCALL_BASE + 324)
+#define __NR_fchownat (__NR_SYSCALL_BASE + 325)
+#define __NR_futimesat (__NR_SYSCALL_BASE + 326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE + 328)
+#define __NR_renameat (__NR_SYSCALL_BASE + 329)
+#define __NR_linkat (__NR_SYSCALL_BASE + 330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE + 331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE + 332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE + 333)
+#define __NR_faccessat (__NR_SYSCALL_BASE + 334)
+#define __NR_pselect6 (__NR_SYSCALL_BASE + 335)
+#define __NR_ppoll (__NR_SYSCALL_BASE + 336)
+#define __NR_unshare (__NR_SYSCALL_BASE + 337)
+#define __NR_set_robust_list (__NR_SYSCALL_BASE + 338)
+#define __NR_get_robust_list (__NR_SYSCALL_BASE + 339)
+#define __NR_splice (__NR_SYSCALL_BASE + 340)
+#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE + 341)
+#define __NR_tee (__NR_SYSCALL_BASE + 342)
+#define __NR_vmsplice (__NR_SYSCALL_BASE + 343)
+#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
+#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
+#define __NR_epoll_pwait (__NR_SYSCALL_BASE + 346)
+#define __NR_kexec_load (__NR_SYSCALL_BASE + 347)
+#define __NR_utimensat (__NR_SYSCALL_BASE + 348)
+#define __NR_signalfd (__NR_SYSCALL_BASE + 349)
+#define __NR_timerfd_create (__NR_SYSCALL_BASE + 350)
+#define __NR_eventfd (__NR_SYSCALL_BASE + 351)
+#define __NR_fallocate (__NR_SYSCALL_BASE + 352)
+#define __NR_timerfd_settime (__NR_SYSCALL_BASE + 353)
+#define __NR_timerfd_gettime (__NR_SYSCALL_BASE + 354)
+#define __NR_signalfd4 (__NR_SYSCALL_BASE + 355)
+#define __NR_eventfd2 (__NR_SYSCALL_BASE + 356)
+#define __NR_epoll_create1 (__NR_SYSCALL_BASE + 357)
+#define __NR_dup3 (__NR_SYSCALL_BASE + 358)
+#define __NR_pipe2 (__NR_SYSCALL_BASE + 359)
+#define __NR_inotify_init1 (__NR_SYSCALL_BASE + 360)
+#define __NR_preadv (__NR_SYSCALL_BASE + 361)
+#define __NR_pwritev (__NR_SYSCALL_BASE + 362)
+#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE + 363)
+#define __NR_perf_event_open (__NR_SYSCALL_BASE + 364)
+#define __NR_recvmmsg (__NR_SYSCALL_BASE + 365)
+#define __NR_accept4 (__NR_SYSCALL_BASE + 366)
+#define __NR_fanotify_init (__NR_SYSCALL_BASE + 367)
+#define __NR_fanotify_mark (__NR_SYSCALL_BASE + 368)
+#define __NR_prlimit64 (__NR_SYSCALL_BASE + 369)
+#define __NR_name_to_handle_at (__NR_SYSCALL_BASE + 370)
+#define __NR_open_by_handle_at (__NR_SYSCALL_BASE + 371)
+#define __NR_clock_adjtime (__NR_SYSCALL_BASE + 372)
+#define __NR_syncfs (__NR_SYSCALL_BASE + 373)
+#define __NR_sendmmsg (__NR_SYSCALL_BASE + 374)
+#define __NR_setns (__NR_SYSCALL_BASE + 375)
+#define __NR_process_vm_readv (__NR_SYSCALL_BASE + 376)
+#define __NR_process_vm_writev (__NR_SYSCALL_BASE + 377)
+#define __NR_kcmp (__NR_SYSCALL_BASE + 378)
+#define __NR_finit_module (__NR_SYSCALL_BASE + 379)
+#define __NR_sched_setattr (__NR_SYSCALL_BASE + 380)
+#define __NR_sched_getattr (__NR_SYSCALL_BASE + 381)
+#define __NR_renameat2 (__NR_SYSCALL_BASE + 382)
+#define __NR_seccomp (__NR_SYSCALL_BASE + 383)
+#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
+#define __NR_memfd_create (__NR_SYSCALL_BASE + 385)
+#define __NR_bpf (__NR_SYSCALL_BASE + 386)
+#define __NR_execveat (__NR_SYSCALL_BASE + 387)
+#define __NR_userfaultfd (__NR_SYSCALL_BASE + 388)
+#define __NR_membarrier (__NR_SYSCALL_BASE + 389)
+#define __NR_mlock2 (__NR_SYSCALL_BASE + 390)
+#define __NR_copy_file_range (__NR_SYSCALL_BASE + 391)
+#define __NR_preadv2 (__NR_SYSCALL_BASE + 392)
+#define __NR_pwritev2 (__NR_SYSCALL_BASE + 393)
+#define __NR_pkey_mprotect (__NR_SYSCALL_BASE + 394)
+#define __NR_pkey_alloc (__NR_SYSCALL_BASE + 395)
+#define __NR_pkey_free (__NR_SYSCALL_BASE + 396)
+#define __NR_statx (__NR_SYSCALL_BASE + 397)
+#define __NR_rseq (__NR_SYSCALL_BASE + 398)
+#define __NR_io_pgetevents (__NR_SYSCALL_BASE + 399)
+#define __NR_migrate_pages (__NR_SYSCALL_BASE + 400)
+#define __NR_kexec_file_load (__NR_SYSCALL_BASE + 401)
+#define __NR_clock_gettime64 (__NR_SYSCALL_BASE + 403)
+#define __NR_clock_settime64 (__NR_SYSCALL_BASE + 404)
+#define __NR_clock_adjtime64 (__NR_SYSCALL_BASE + 405)
+#define __NR_clock_getres_time64 (__NR_SYSCALL_BASE + 406)
+#define __NR_clock_nanosleep_time64 (__NR_SYSCALL_BASE + 407)
+#define __NR_timer_gettime64 (__NR_SYSCALL_BASE + 408)
+#define __NR_timer_settime64 (__NR_SYSCALL_BASE + 409)
+#define __NR_timerfd_gettime64 (__NR_SYSCALL_BASE + 410)
+#define __NR_timerfd_settime64 (__NR_SYSCALL_BASE + 411)
+#define __NR_utimensat_time64 (__NR_SYSCALL_BASE + 412)
+#define __NR_pselect6_time64 (__NR_SYSCALL_BASE + 413)
+#define __NR_ppoll_time64 (__NR_SYSCALL_BASE + 414)
+#define __NR_io_pgetevents_time64 (__NR_SYSCALL_BASE + 416)
+#define __NR_recvmmsg_time64 (__NR_SYSCALL_BASE + 417)
+#define __NR_mq_timedsend_time64 (__NR_SYSCALL_BASE + 418)
+#define __NR_mq_timedreceive_time64 (__NR_SYSCALL_BASE + 419)
+#define __NR_semtimedop_time64 (__NR_SYSCALL_BASE + 420)
+#define __NR_rt_sigtimedwait_time64 (__NR_SYSCALL_BASE + 421)
+#define __NR_futex_time64 (__NR_SYSCALL_BASE + 422)
+#define __NR_sched_rr_get_interval_time64 (__NR_SYSCALL_BASE + 423)
+#define __NR_pidfd_send_signal (__NR_SYSCALL_BASE + 424)
+#define __NR_io_uring_setup (__NR_SYSCALL_BASE + 425)
+#define __NR_io_uring_enter (__NR_SYSCALL_BASE + 426)
+#define __NR_io_uring_register (__NR_SYSCALL_BASE + 427)
+#define __NR_open_tree (__NR_SYSCALL_BASE + 428)
+#define __NR_move_mount (__NR_SYSCALL_BASE + 429)
+#define __NR_fsopen (__NR_SYSCALL_BASE + 430)
+#define __NR_fsconfig (__NR_SYSCALL_BASE + 431)
+#define __NR_fsmount (__NR_SYSCALL_BASE + 432)
+#define __NR_fspick (__NR_SYSCALL_BASE + 433)
+#define __NR_pidfd_open (__NR_SYSCALL_BASE + 434)
+#define __NR_clone3 (__NR_SYSCALL_BASE + 435)
+#define __NR_close_range (__NR_SYSCALL_BASE + 436)
+#define __NR_openat2 (__NR_SYSCALL_BASE + 437)
+#define __NR_pidfd_getfd (__NR_SYSCALL_BASE + 438)
+#define __NR_faccessat2 (__NR_SYSCALL_BASE + 439)
+#define __NR_process_madvise (__NR_SYSCALL_BASE + 440)
+#define __NR_epoll_pwait2 (__NR_SYSCALL_BASE + 441)
+#define __NR_mount_setattr (__NR_SYSCALL_BASE + 442)
+#define __NR_quotactl_fd (__NR_SYSCALL_BASE + 443)
+#define __NR_landlock_create_ruleset (__NR_SYSCALL_BASE + 444)
+#define __NR_landlock_add_rule (__NR_SYSCALL_BASE + 445)
+#define __NR_landlock_restrict_self (__NR_SYSCALL_BASE + 446)
+#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)
 #endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
index d2633e8..08b3b9a 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
@@ -16,18 +16,421 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _UAPI_ASM_ARM_UNISTD_OABI_H
-#define _UAPI_ASM_ARM_UNISTD_OABI_H 1
+#ifndef _UAPI_ASM_UNISTD_OABI_H
+#define _UAPI_ASM_UNISTD_OABI_H
+#define __NR_restart_syscall (__NR_SYSCALL_BASE + 0)
+#define __NR_exit (__NR_SYSCALL_BASE + 1)
+#define __NR_fork (__NR_SYSCALL_BASE + 2)
+#define __NR_read (__NR_SYSCALL_BASE + 3)
+#define __NR_write (__NR_SYSCALL_BASE + 4)
+#define __NR_open (__NR_SYSCALL_BASE + 5)
+#define __NR_close (__NR_SYSCALL_BASE + 6)
+#define __NR_creat (__NR_SYSCALL_BASE + 8)
+#define __NR_link (__NR_SYSCALL_BASE + 9)
+#define __NR_unlink (__NR_SYSCALL_BASE + 10)
+#define __NR_execve (__NR_SYSCALL_BASE + 11)
+#define __NR_chdir (__NR_SYSCALL_BASE + 12)
 #define __NR_time (__NR_SYSCALL_BASE + 13)
+#define __NR_mknod (__NR_SYSCALL_BASE + 14)
+#define __NR_chmod (__NR_SYSCALL_BASE + 15)
+#define __NR_lchown (__NR_SYSCALL_BASE + 16)
+#define __NR_lseek (__NR_SYSCALL_BASE + 19)
+#define __NR_getpid (__NR_SYSCALL_BASE + 20)
+#define __NR_mount (__NR_SYSCALL_BASE + 21)
 #define __NR_umount (__NR_SYSCALL_BASE + 22)
+#define __NR_setuid (__NR_SYSCALL_BASE + 23)
+#define __NR_getuid (__NR_SYSCALL_BASE + 24)
 #define __NR_stime (__NR_SYSCALL_BASE + 25)
+#define __NR_ptrace (__NR_SYSCALL_BASE + 26)
 #define __NR_alarm (__NR_SYSCALL_BASE + 27)
+#define __NR_pause (__NR_SYSCALL_BASE + 29)
 #define __NR_utime (__NR_SYSCALL_BASE + 30)
+#define __NR_access (__NR_SYSCALL_BASE + 33)
+#define __NR_nice (__NR_SYSCALL_BASE + 34)
+#define __NR_sync (__NR_SYSCALL_BASE + 36)
+#define __NR_kill (__NR_SYSCALL_BASE + 37)
+#define __NR_rename (__NR_SYSCALL_BASE + 38)
+#define __NR_mkdir (__NR_SYSCALL_BASE + 39)
+#define __NR_rmdir (__NR_SYSCALL_BASE + 40)
+#define __NR_dup (__NR_SYSCALL_BASE + 41)
+#define __NR_pipe (__NR_SYSCALL_BASE + 42)
+#define __NR_times (__NR_SYSCALL_BASE + 43)
+#define __NR_brk (__NR_SYSCALL_BASE + 45)
+#define __NR_setgid (__NR_SYSCALL_BASE + 46)
+#define __NR_getgid (__NR_SYSCALL_BASE + 47)
+#define __NR_geteuid (__NR_SYSCALL_BASE + 49)
+#define __NR_getegid (__NR_SYSCALL_BASE + 50)
+#define __NR_acct (__NR_SYSCALL_BASE + 51)
+#define __NR_umount2 (__NR_SYSCALL_BASE + 52)
+#define __NR_ioctl (__NR_SYSCALL_BASE + 54)
+#define __NR_fcntl (__NR_SYSCALL_BASE + 55)
+#define __NR_setpgid (__NR_SYSCALL_BASE + 57)
+#define __NR_umask (__NR_SYSCALL_BASE + 60)
+#define __NR_chroot (__NR_SYSCALL_BASE + 61)
+#define __NR_ustat (__NR_SYSCALL_BASE + 62)
+#define __NR_dup2 (__NR_SYSCALL_BASE + 63)
+#define __NR_getppid (__NR_SYSCALL_BASE + 64)
+#define __NR_getpgrp (__NR_SYSCALL_BASE + 65)
+#define __NR_setsid (__NR_SYSCALL_BASE + 66)
+#define __NR_sigaction (__NR_SYSCALL_BASE + 67)
+#define __NR_setreuid (__NR_SYSCALL_BASE + 70)
+#define __NR_setregid (__NR_SYSCALL_BASE + 71)
+#define __NR_sigsuspend (__NR_SYSCALL_BASE + 72)
+#define __NR_sigpending (__NR_SYSCALL_BASE + 73)
+#define __NR_sethostname (__NR_SYSCALL_BASE + 74)
+#define __NR_setrlimit (__NR_SYSCALL_BASE + 75)
 #define __NR_getrlimit (__NR_SYSCALL_BASE + 76)
+#define __NR_getrusage (__NR_SYSCALL_BASE + 77)
+#define __NR_gettimeofday (__NR_SYSCALL_BASE + 78)
+#define __NR_settimeofday (__NR_SYSCALL_BASE + 79)
+#define __NR_getgroups (__NR_SYSCALL_BASE + 80)
+#define __NR_setgroups (__NR_SYSCALL_BASE + 81)
 #define __NR_select (__NR_SYSCALL_BASE + 82)
+#define __NR_symlink (__NR_SYSCALL_BASE + 83)
+#define __NR_readlink (__NR_SYSCALL_BASE + 85)
+#define __NR_uselib (__NR_SYSCALL_BASE + 86)
+#define __NR_swapon (__NR_SYSCALL_BASE + 87)
+#define __NR_reboot (__NR_SYSCALL_BASE + 88)
 #define __NR_readdir (__NR_SYSCALL_BASE + 89)
 #define __NR_mmap (__NR_SYSCALL_BASE + 90)
+#define __NR_munmap (__NR_SYSCALL_BASE + 91)
+#define __NR_truncate (__NR_SYSCALL_BASE + 92)
+#define __NR_ftruncate (__NR_SYSCALL_BASE + 93)
+#define __NR_fchmod (__NR_SYSCALL_BASE + 94)
+#define __NR_fchown (__NR_SYSCALL_BASE + 95)
+#define __NR_getpriority (__NR_SYSCALL_BASE + 96)
+#define __NR_setpriority (__NR_SYSCALL_BASE + 97)
+#define __NR_statfs (__NR_SYSCALL_BASE + 99)
+#define __NR_fstatfs (__NR_SYSCALL_BASE + 100)
 #define __NR_socketcall (__NR_SYSCALL_BASE + 102)
+#define __NR_syslog (__NR_SYSCALL_BASE + 103)
+#define __NR_setitimer (__NR_SYSCALL_BASE + 104)
+#define __NR_getitimer (__NR_SYSCALL_BASE + 105)
+#define __NR_stat (__NR_SYSCALL_BASE + 106)
+#define __NR_lstat (__NR_SYSCALL_BASE + 107)
+#define __NR_fstat (__NR_SYSCALL_BASE + 108)
+#define __NR_vhangup (__NR_SYSCALL_BASE + 111)
 #define __NR_syscall (__NR_SYSCALL_BASE + 113)
+#define __NR_wait4 (__NR_SYSCALL_BASE + 114)
+#define __NR_swapoff (__NR_SYSCALL_BASE + 115)
+#define __NR_sysinfo (__NR_SYSCALL_BASE + 116)
 #define __NR_ipc (__NR_SYSCALL_BASE + 117)
+#define __NR_fsync (__NR_SYSCALL_BASE + 118)
+#define __NR_sigreturn (__NR_SYSCALL_BASE + 119)
+#define __NR_clone (__NR_SYSCALL_BASE + 120)
+#define __NR_setdomainname (__NR_SYSCALL_BASE + 121)
+#define __NR_uname (__NR_SYSCALL_BASE + 122)
+#define __NR_adjtimex (__NR_SYSCALL_BASE + 124)
+#define __NR_mprotect (__NR_SYSCALL_BASE + 125)
+#define __NR_sigprocmask (__NR_SYSCALL_BASE + 126)
+#define __NR_init_module (__NR_SYSCALL_BASE + 128)
+#define __NR_delete_module (__NR_SYSCALL_BASE + 129)
+#define __NR_quotactl (__NR_SYSCALL_BASE + 131)
+#define __NR_getpgid (__NR_SYSCALL_BASE + 132)
+#define __NR_fchdir (__NR_SYSCALL_BASE + 133)
+#define __NR_bdflush (__NR_SYSCALL_BASE + 134)
+#define __NR_sysfs (__NR_SYSCALL_BASE + 135)
+#define __NR_personality (__NR_SYSCALL_BASE + 136)
+#define __NR_setfsuid (__NR_SYSCALL_BASE + 138)
+#define __NR_setfsgid (__NR_SYSCALL_BASE + 139)
+#define __NR__llseek (__NR_SYSCALL_BASE + 140)
+#define __NR_getdents (__NR_SYSCALL_BASE + 141)
+#define __NR__newselect (__NR_SYSCALL_BASE + 142)
+#define __NR_flock (__NR_SYSCALL_BASE + 143)
+#define __NR_msync (__NR_SYSCALL_BASE + 144)
+#define __NR_readv (__NR_SYSCALL_BASE + 145)
+#define __NR_writev (__NR_SYSCALL_BASE + 146)
+#define __NR_getsid (__NR_SYSCALL_BASE + 147)
+#define __NR_fdatasync (__NR_SYSCALL_BASE + 148)
+#define __NR__sysctl (__NR_SYSCALL_BASE + 149)
+#define __NR_mlock (__NR_SYSCALL_BASE + 150)
+#define __NR_munlock (__NR_SYSCALL_BASE + 151)
+#define __NR_mlockall (__NR_SYSCALL_BASE + 152)
+#define __NR_munlockall (__NR_SYSCALL_BASE + 153)
+#define __NR_sched_setparam (__NR_SYSCALL_BASE + 154)
+#define __NR_sched_getparam (__NR_SYSCALL_BASE + 155)
+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE + 156)
+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE + 157)
+#define __NR_sched_yield (__NR_SYSCALL_BASE + 158)
+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE + 159)
+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE + 160)
+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE + 161)
+#define __NR_nanosleep (__NR_SYSCALL_BASE + 162)
+#define __NR_mremap (__NR_SYSCALL_BASE + 163)
+#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
+#define __NR_getresuid (__NR_SYSCALL_BASE + 165)
+#define __NR_poll (__NR_SYSCALL_BASE + 168)
+#define __NR_nfsservctl (__NR_SYSCALL_BASE + 169)
+#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
+#define __NR_getresgid (__NR_SYSCALL_BASE + 171)
+#define __NR_prctl (__NR_SYSCALL_BASE + 172)
+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173)
+#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174)
+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175)
+#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176)
+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE + 177)
+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE + 178)
+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179)
+#define __NR_pread64 (__NR_SYSCALL_BASE + 180)
+#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181)
+#define __NR_chown (__NR_SYSCALL_BASE + 182)
+#define __NR_getcwd (__NR_SYSCALL_BASE + 183)
+#define __NR_capget (__NR_SYSCALL_BASE + 184)
+#define __NR_capset (__NR_SYSCALL_BASE + 185)
+#define __NR_sigaltstack (__NR_SYSCALL_BASE + 186)
+#define __NR_sendfile (__NR_SYSCALL_BASE + 187)
+#define __NR_vfork (__NR_SYSCALL_BASE + 190)
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
+#define __NR_mmap2 (__NR_SYSCALL_BASE + 192)
+#define __NR_truncate64 (__NR_SYSCALL_BASE + 193)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE + 194)
+#define __NR_stat64 (__NR_SYSCALL_BASE + 195)
+#define __NR_lstat64 (__NR_SYSCALL_BASE + 196)
+#define __NR_fstat64 (__NR_SYSCALL_BASE + 197)
+#define __NR_lchown32 (__NR_SYSCALL_BASE + 198)
+#define __NR_getuid32 (__NR_SYSCALL_BASE + 199)
+#define __NR_getgid32 (__NR_SYSCALL_BASE + 200)
+#define __NR_geteuid32 (__NR_SYSCALL_BASE + 201)
+#define __NR_getegid32 (__NR_SYSCALL_BASE + 202)
+#define __NR_setreuid32 (__NR_SYSCALL_BASE + 203)
+#define __NR_setregid32 (__NR_SYSCALL_BASE + 204)
+#define __NR_getgroups32 (__NR_SYSCALL_BASE + 205)
+#define __NR_setgroups32 (__NR_SYSCALL_BASE + 206)
+#define __NR_fchown32 (__NR_SYSCALL_BASE + 207)
+#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
+#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
+#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
+#define __NR_chown32 (__NR_SYSCALL_BASE + 212)
+#define __NR_setuid32 (__NR_SYSCALL_BASE + 213)
+#define __NR_setgid32 (__NR_SYSCALL_BASE + 214)
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
+#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
+#define __NR_pivot_root (__NR_SYSCALL_BASE + 218)
+#define __NR_mincore (__NR_SYSCALL_BASE + 219)
+#define __NR_madvise (__NR_SYSCALL_BASE + 220)
+#define __NR_fcntl64 (__NR_SYSCALL_BASE + 221)
+#define __NR_gettid (__NR_SYSCALL_BASE + 224)
+#define __NR_readahead (__NR_SYSCALL_BASE + 225)
+#define __NR_setxattr (__NR_SYSCALL_BASE + 226)
+#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227)
+#define __NR_fsetxattr (__NR_SYSCALL_BASE + 228)
+#define __NR_getxattr (__NR_SYSCALL_BASE + 229)
+#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230)
+#define __NR_fgetxattr (__NR_SYSCALL_BASE + 231)
+#define __NR_listxattr (__NR_SYSCALL_BASE + 232)
+#define __NR_llistxattr (__NR_SYSCALL_BASE + 233)
+#define __NR_flistxattr (__NR_SYSCALL_BASE + 234)
+#define __NR_removexattr (__NR_SYSCALL_BASE + 235)
+#define __NR_lremovexattr (__NR_SYSCALL_BASE + 236)
+#define __NR_fremovexattr (__NR_SYSCALL_BASE + 237)
+#define __NR_tkill (__NR_SYSCALL_BASE + 238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE + 239)
+#define __NR_futex (__NR_SYSCALL_BASE + 240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
+#define __NR_io_setup (__NR_SYSCALL_BASE + 243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE + 244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE + 245)
+#define __NR_io_submit (__NR_SYSCALL_BASE + 246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE + 247)
+#define __NR_exit_group (__NR_SYSCALL_BASE + 248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE + 249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE + 250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE + 251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE + 252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE + 253)
+#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
+#define __NR_timer_create (__NR_SYSCALL_BASE + 257)
+#define __NR_timer_settime (__NR_SYSCALL_BASE + 258)
+#define __NR_timer_gettime (__NR_SYSCALL_BASE + 259)
+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE + 260)
+#define __NR_timer_delete (__NR_SYSCALL_BASE + 261)
+#define __NR_clock_settime (__NR_SYSCALL_BASE + 262)
+#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263)
+#define __NR_clock_getres (__NR_SYSCALL_BASE + 264)
+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE + 265)
+#define __NR_statfs64 (__NR_SYSCALL_BASE + 266)
+#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267)
+#define __NR_tgkill (__NR_SYSCALL_BASE + 268)
+#define __NR_utimes (__NR_SYSCALL_BASE + 269)
+#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE + 270)
+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE + 271)
+#define __NR_pciconfig_read (__NR_SYSCALL_BASE + 272)
+#define __NR_pciconfig_write (__NR_SYSCALL_BASE + 273)
+#define __NR_mq_open (__NR_SYSCALL_BASE + 274)
+#define __NR_mq_unlink (__NR_SYSCALL_BASE + 275)
+#define __NR_mq_timedsend (__NR_SYSCALL_BASE + 276)
+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE + 277)
+#define __NR_mq_notify (__NR_SYSCALL_BASE + 278)
+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE + 279)
+#define __NR_waitid (__NR_SYSCALL_BASE + 280)
+#define __NR_socket (__NR_SYSCALL_BASE + 281)
+#define __NR_bind (__NR_SYSCALL_BASE + 282)
+#define __NR_connect (__NR_SYSCALL_BASE + 283)
+#define __NR_listen (__NR_SYSCALL_BASE + 284)
+#define __NR_accept (__NR_SYSCALL_BASE + 285)
+#define __NR_getsockname (__NR_SYSCALL_BASE + 286)
+#define __NR_getpeername (__NR_SYSCALL_BASE + 287)
+#define __NR_socketpair (__NR_SYSCALL_BASE + 288)
+#define __NR_send (__NR_SYSCALL_BASE + 289)
+#define __NR_sendto (__NR_SYSCALL_BASE + 290)
+#define __NR_recv (__NR_SYSCALL_BASE + 291)
+#define __NR_recvfrom (__NR_SYSCALL_BASE + 292)
+#define __NR_shutdown (__NR_SYSCALL_BASE + 293)
+#define __NR_setsockopt (__NR_SYSCALL_BASE + 294)
+#define __NR_getsockopt (__NR_SYSCALL_BASE + 295)
+#define __NR_sendmsg (__NR_SYSCALL_BASE + 296)
+#define __NR_recvmsg (__NR_SYSCALL_BASE + 297)
+#define __NR_semop (__NR_SYSCALL_BASE + 298)
+#define __NR_semget (__NR_SYSCALL_BASE + 299)
+#define __NR_semctl (__NR_SYSCALL_BASE + 300)
+#define __NR_msgsnd (__NR_SYSCALL_BASE + 301)
+#define __NR_msgrcv (__NR_SYSCALL_BASE + 302)
+#define __NR_msgget (__NR_SYSCALL_BASE + 303)
+#define __NR_msgctl (__NR_SYSCALL_BASE + 304)
+#define __NR_shmat (__NR_SYSCALL_BASE + 305)
+#define __NR_shmdt (__NR_SYSCALL_BASE + 306)
+#define __NR_shmget (__NR_SYSCALL_BASE + 307)
+#define __NR_shmctl (__NR_SYSCALL_BASE + 308)
+#define __NR_add_key (__NR_SYSCALL_BASE + 309)
+#define __NR_request_key (__NR_SYSCALL_BASE + 310)
+#define __NR_keyctl (__NR_SYSCALL_BASE + 311)
+#define __NR_semtimedop (__NR_SYSCALL_BASE + 312)
+#define __NR_vserver (__NR_SYSCALL_BASE + 313)
+#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314)
+#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315)
+#define __NR_inotify_init (__NR_SYSCALL_BASE + 316)
+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE + 317)
+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE + 318)
+#define __NR_mbind (__NR_SYSCALL_BASE + 319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE + 320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE + 321)
+#define __NR_openat (__NR_SYSCALL_BASE + 322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE + 323)
+#define __NR_mknodat (__NR_SYSCALL_BASE + 324)
+#define __NR_fchownat (__NR_SYSCALL_BASE + 325)
+#define __NR_futimesat (__NR_SYSCALL_BASE + 326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE + 328)
+#define __NR_renameat (__NR_SYSCALL_BASE + 329)
+#define __NR_linkat (__NR_SYSCALL_BASE + 330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE + 331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE + 332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE + 333)
+#define __NR_faccessat (__NR_SYSCALL_BASE + 334)
+#define __NR_pselect6 (__NR_SYSCALL_BASE + 335)
+#define __NR_ppoll (__NR_SYSCALL_BASE + 336)
+#define __NR_unshare (__NR_SYSCALL_BASE + 337)
+#define __NR_set_robust_list (__NR_SYSCALL_BASE + 338)
+#define __NR_get_robust_list (__NR_SYSCALL_BASE + 339)
+#define __NR_splice (__NR_SYSCALL_BASE + 340)
+#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE + 341)
+#define __NR_tee (__NR_SYSCALL_BASE + 342)
+#define __NR_vmsplice (__NR_SYSCALL_BASE + 343)
+#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
+#define __NR_getcpu (__NR_SYSCALL_BASE + 345)
+#define __NR_epoll_pwait (__NR_SYSCALL_BASE + 346)
+#define __NR_kexec_load (__NR_SYSCALL_BASE + 347)
+#define __NR_utimensat (__NR_SYSCALL_BASE + 348)
+#define __NR_signalfd (__NR_SYSCALL_BASE + 349)
+#define __NR_timerfd_create (__NR_SYSCALL_BASE + 350)
+#define __NR_eventfd (__NR_SYSCALL_BASE + 351)
+#define __NR_fallocate (__NR_SYSCALL_BASE + 352)
+#define __NR_timerfd_settime (__NR_SYSCALL_BASE + 353)
+#define __NR_timerfd_gettime (__NR_SYSCALL_BASE + 354)
+#define __NR_signalfd4 (__NR_SYSCALL_BASE + 355)
+#define __NR_eventfd2 (__NR_SYSCALL_BASE + 356)
+#define __NR_epoll_create1 (__NR_SYSCALL_BASE + 357)
+#define __NR_dup3 (__NR_SYSCALL_BASE + 358)
+#define __NR_pipe2 (__NR_SYSCALL_BASE + 359)
+#define __NR_inotify_init1 (__NR_SYSCALL_BASE + 360)
+#define __NR_preadv (__NR_SYSCALL_BASE + 361)
+#define __NR_pwritev (__NR_SYSCALL_BASE + 362)
+#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE + 363)
+#define __NR_perf_event_open (__NR_SYSCALL_BASE + 364)
+#define __NR_recvmmsg (__NR_SYSCALL_BASE + 365)
+#define __NR_accept4 (__NR_SYSCALL_BASE + 366)
+#define __NR_fanotify_init (__NR_SYSCALL_BASE + 367)
+#define __NR_fanotify_mark (__NR_SYSCALL_BASE + 368)
+#define __NR_prlimit64 (__NR_SYSCALL_BASE + 369)
+#define __NR_name_to_handle_at (__NR_SYSCALL_BASE + 370)
+#define __NR_open_by_handle_at (__NR_SYSCALL_BASE + 371)
+#define __NR_clock_adjtime (__NR_SYSCALL_BASE + 372)
+#define __NR_syncfs (__NR_SYSCALL_BASE + 373)
+#define __NR_sendmmsg (__NR_SYSCALL_BASE + 374)
+#define __NR_setns (__NR_SYSCALL_BASE + 375)
+#define __NR_process_vm_readv (__NR_SYSCALL_BASE + 376)
+#define __NR_process_vm_writev (__NR_SYSCALL_BASE + 377)
+#define __NR_kcmp (__NR_SYSCALL_BASE + 378)
+#define __NR_finit_module (__NR_SYSCALL_BASE + 379)
+#define __NR_sched_setattr (__NR_SYSCALL_BASE + 380)
+#define __NR_sched_getattr (__NR_SYSCALL_BASE + 381)
+#define __NR_renameat2 (__NR_SYSCALL_BASE + 382)
+#define __NR_seccomp (__NR_SYSCALL_BASE + 383)
+#define __NR_getrandom (__NR_SYSCALL_BASE + 384)
+#define __NR_memfd_create (__NR_SYSCALL_BASE + 385)
+#define __NR_bpf (__NR_SYSCALL_BASE + 386)
+#define __NR_execveat (__NR_SYSCALL_BASE + 387)
+#define __NR_userfaultfd (__NR_SYSCALL_BASE + 388)
+#define __NR_membarrier (__NR_SYSCALL_BASE + 389)
+#define __NR_mlock2 (__NR_SYSCALL_BASE + 390)
+#define __NR_copy_file_range (__NR_SYSCALL_BASE + 391)
+#define __NR_preadv2 (__NR_SYSCALL_BASE + 392)
+#define __NR_pwritev2 (__NR_SYSCALL_BASE + 393)
+#define __NR_pkey_mprotect (__NR_SYSCALL_BASE + 394)
+#define __NR_pkey_alloc (__NR_SYSCALL_BASE + 395)
+#define __NR_pkey_free (__NR_SYSCALL_BASE + 396)
+#define __NR_statx (__NR_SYSCALL_BASE + 397)
+#define __NR_rseq (__NR_SYSCALL_BASE + 398)
+#define __NR_io_pgetevents (__NR_SYSCALL_BASE + 399)
+#define __NR_migrate_pages (__NR_SYSCALL_BASE + 400)
+#define __NR_kexec_file_load (__NR_SYSCALL_BASE + 401)
+#define __NR_clock_gettime64 (__NR_SYSCALL_BASE + 403)
+#define __NR_clock_settime64 (__NR_SYSCALL_BASE + 404)
+#define __NR_clock_adjtime64 (__NR_SYSCALL_BASE + 405)
+#define __NR_clock_getres_time64 (__NR_SYSCALL_BASE + 406)
+#define __NR_clock_nanosleep_time64 (__NR_SYSCALL_BASE + 407)
+#define __NR_timer_gettime64 (__NR_SYSCALL_BASE + 408)
+#define __NR_timer_settime64 (__NR_SYSCALL_BASE + 409)
+#define __NR_timerfd_gettime64 (__NR_SYSCALL_BASE + 410)
+#define __NR_timerfd_settime64 (__NR_SYSCALL_BASE + 411)
+#define __NR_utimensat_time64 (__NR_SYSCALL_BASE + 412)
+#define __NR_pselect6_time64 (__NR_SYSCALL_BASE + 413)
+#define __NR_ppoll_time64 (__NR_SYSCALL_BASE + 414)
+#define __NR_io_pgetevents_time64 (__NR_SYSCALL_BASE + 416)
+#define __NR_recvmmsg_time64 (__NR_SYSCALL_BASE + 417)
+#define __NR_mq_timedsend_time64 (__NR_SYSCALL_BASE + 418)
+#define __NR_mq_timedreceive_time64 (__NR_SYSCALL_BASE + 419)
+#define __NR_semtimedop_time64 (__NR_SYSCALL_BASE + 420)
+#define __NR_rt_sigtimedwait_time64 (__NR_SYSCALL_BASE + 421)
+#define __NR_futex_time64 (__NR_SYSCALL_BASE + 422)
+#define __NR_sched_rr_get_interval_time64 (__NR_SYSCALL_BASE + 423)
+#define __NR_pidfd_send_signal (__NR_SYSCALL_BASE + 424)
+#define __NR_io_uring_setup (__NR_SYSCALL_BASE + 425)
+#define __NR_io_uring_enter (__NR_SYSCALL_BASE + 426)
+#define __NR_io_uring_register (__NR_SYSCALL_BASE + 427)
+#define __NR_open_tree (__NR_SYSCALL_BASE + 428)
+#define __NR_move_mount (__NR_SYSCALL_BASE + 429)
+#define __NR_fsopen (__NR_SYSCALL_BASE + 430)
+#define __NR_fsconfig (__NR_SYSCALL_BASE + 431)
+#define __NR_fsmount (__NR_SYSCALL_BASE + 432)
+#define __NR_fspick (__NR_SYSCALL_BASE + 433)
+#define __NR_pidfd_open (__NR_SYSCALL_BASE + 434)
+#define __NR_clone3 (__NR_SYSCALL_BASE + 435)
+#define __NR_close_range (__NR_SYSCALL_BASE + 436)
+#define __NR_openat2 (__NR_SYSCALL_BASE + 437)
+#define __NR_pidfd_getfd (__NR_SYSCALL_BASE + 438)
+#define __NR_faccessat2 (__NR_SYSCALL_BASE + 439)
+#define __NR_process_madvise (__NR_SYSCALL_BASE + 440)
+#define __NR_epoll_pwait2 (__NR_SYSCALL_BASE + 441)
+#define __NR_mount_setattr (__NR_SYSCALL_BASE + 442)
+#define __NR_quotactl_fd (__NR_SYSCALL_BASE + 443)
+#define __NR_landlock_create_ruleset (__NR_SYSCALL_BASE + 444)
+#define __NR_landlock_add_rule (__NR_SYSCALL_BASE + 445)
+#define __NR_landlock_restrict_self (__NR_SYSCALL_BASE + 446)
+#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)
 #endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd.h b/libc/kernel/uapi/asm-arm/asm/unistd.h
index f4b1f3a..8bb0f58 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd.h
@@ -19,9 +19,9 @@
 #ifndef _UAPI__ASM_ARM_UNISTD_H
 #define _UAPI__ASM_ARM_UNISTD_H
 #define __NR_OABI_SYSCALL_BASE 0x900000
+#define __NR_SYSCALL_MASK 0x0fffff
 #define __NR_SYSCALL_BASE 0
 #include <asm/unistd-eabi.h>
-#include <asm/unistd-common.h>
 #define __NR_sync_file_range2 __NR_arm_sync_file_range
 #define __ARM_NR_BASE (__NR_SYSCALL_BASE + 0x0f0000)
 #define __ARM_NR_breakpoint (__ARM_NR_BASE + 1)
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 8a70a52..4316724 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -69,4 +69,7 @@
 #define HWCAP2_RNG (1 << 16)
 #define HWCAP2_BTI (1 << 17)
 #define HWCAP2_MTE (1 << 18)
+#define HWCAP2_ECV (1 << 19)
+#define HWCAP2_AFP (1 << 20)
+#define HWCAP2_RPRES (1 << 21)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index 014504a..c53ee87 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -115,6 +115,15 @@
   } exception;
   __u32 reserved[12];
 };
+struct kvm_arm_copy_mte_tags {
+  __u64 guest_ipa;
+  __u64 length;
+  void __user * addr;
+  __u64 flags;
+  __u64 reserved[2];
+};
+#define KVM_ARM_TAGS_TO_GUEST 0
+#define KVM_ARM_TAGS_FROM_GUEST 1
 #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
 #define KVM_REG_ARM_COPROC_SHIFT 16
 #define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
@@ -158,6 +167,10 @@
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL 2
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL 0
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL 1
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED 2
 #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT)
 #define KVM_REG_ARM64_SVE_ZREG_BASE 0
 #define KVM_REG_ARM64_SVE_PREG_BASE 0x400
diff --git a/libc/kernel/uapi/asm-arm64/asm/unistd.h b/libc/kernel/uapi/asm-arm64/asm/unistd.h
index e93f3f1..06b85ed 100644
--- a/libc/kernel/uapi/asm-arm64/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm64/asm/unistd.h
@@ -21,4 +21,5 @@
 #define __ARCH_WANT_SET_GET_RLIMIT
 #define __ARCH_WANT_TIME32_SYSCALLS
 #define __ARCH_WANT_SYS_CLONE3
+#define __ARCH_WANT_MEMFD_SECRET
 #include <asm-generic/unistd.h>
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index a088ce5..9440576 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -60,6 +60,8 @@
 #define MADV_KEEPONFORK 19
 #define MADV_COLD 20
 #define MADV_PAGEOUT 21
+#define MADV_POPULATE_READ 22
+#define MADV_POPULATE_WRITE 23
 #define MAP_FILE 0
 #define PKEY_DISABLE_ACCESS 0x1
 #define PKEY_DISABLE_WRITE 0x2
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index 8bcbabb..f9199e5 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -59,9 +59,6 @@
   } _sigchld;
   struct {
     void __user * _addr;
-#ifdef __ARCH_SI_TRAPNO
-    int _trapno;
-#endif
 #ifdef __ia64__
     int _imm;
     unsigned int _flags;
@@ -69,6 +66,7 @@
 #endif
 #define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? sizeof(short) : __alignof__(void *))
     union {
+      int _trapno;
       short _addr_lsb;
       struct {
         char _dummy_bnd[__ADDR_BND_PKEY_PAD];
@@ -79,6 +77,10 @@
         char _dummy_pkey[__ADDR_BND_PKEY_PAD];
         __u32 _pkey;
       } _addr_pkey;
+      struct {
+        unsigned long _data;
+        __u32 _type;
+      } _perf;
     };
   } _sigfault;
   struct {
@@ -116,13 +118,13 @@
 #define si_int _sifields._rt._sigval.sival_int
 #define si_ptr _sifields._rt._sigval.sival_ptr
 #define si_addr _sifields._sigfault._addr
-#ifdef __ARCH_SI_TRAPNO
 #define si_trapno _sifields._sigfault._trapno
-#endif
 #define si_addr_lsb _sifields._sigfault._addr_lsb
 #define si_lower _sifields._sigfault._addr_bnd._lower
 #define si_upper _sifields._sigfault._addr_bnd._upper
 #define si_pkey _sifields._sigfault._addr_pkey._pkey
+#define si_perf_data _sifields._sigfault._perf._data
+#define si_perf_type _sifields._sigfault._perf._type
 #define si_band _sifields._sigpoll._band
 #define si_fd _sifields._sigpoll._fd
 #define si_call_addr _sifields._sigsys._call_addr
@@ -193,7 +195,8 @@
 #define TRAP_BRANCH 3
 #define TRAP_HWBKPT 4
 #define TRAP_UNK 5
-#define NSIGTRAP 5
+#define TRAP_PERF 6
+#define NSIGTRAP 6
 #define CLD_EXITED 1
 #define CLD_KILLED 2
 #define CLD_DUMPED 3
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index 7372be8..6767993 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -97,6 +97,9 @@
 #define SO_DETACH_REUSEPORT_BPF 68
 #define SO_PREFER_BUSY_POLL 69
 #define SO_BUSY_POLL_BUDGET 70
+#define SO_NETNS_COOKIE 71
+#define SO_BUF_LOCK 72
+#define SO_RESERVE_MEM 73
 #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 1409701..4b9f174 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -403,8 +403,18 @@
 #define __NR_process_madvise 440
 #define __NR_epoll_pwait2 441
 #define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#ifdef __ARCH_WANT_MEMFD_SECRET
+#define __NR_memfd_secret 447
+#endif
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
 #undef __NR_syscalls
-#define __NR_syscalls 443
+#define __NR_syscalls 451
 #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-x86/asm/auxvec.h b/libc/kernel/uapi/asm-x86/asm/auxvec.h
index 4fd53f0..dd86783 100644
--- a/libc/kernel/uapi/asm-x86/asm/auxvec.h
+++ b/libc/kernel/uapi/asm-x86/asm/auxvec.h
@@ -22,5 +22,5 @@
 #define AT_SYSINFO 32
 #endif
 #define AT_SYSINFO_EHDR 33
-#define AT_VECTOR_SIZE_ARCH 2
+#define AT_VECTOR_SIZE_ARCH 3
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/debugreg.h b/libc/kernel/uapi/asm-x86/asm/debugreg.h
index aeb8b02..360f432 100644
--- a/libc/kernel/uapi/asm-x86/asm/debugreg.h
+++ b/libc/kernel/uapi/asm-x86/asm/debugreg.h
@@ -28,6 +28,7 @@
 #define DR_TRAP2 (0x4)
 #define DR_TRAP3 (0x8)
 #define DR_TRAP_BITS (DR_TRAP0 | DR_TRAP1 | DR_TRAP2 | DR_TRAP3)
+#define DR_BUS_LOCK (0x800)
 #define DR_STEP (0x4000)
 #define DR_SWITCH (0x8000)
 #define DR_CONTROL_SHIFT 16
diff --git a/libc/kernel/uapi/asm-x86/asm/hwcap2.h b/libc/kernel/uapi/asm-x86/asm/hwcap2.h
index a6dbfb9..9f715c9 100644
--- a/libc/kernel/uapi/asm-x86/asm/hwcap2.h
+++ b/libc/kernel/uapi/asm-x86/asm/hwcap2.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef _ASM_X86_HWCAP2_H
 #define _ASM_X86_HWCAP2_H
-#define HWCAP2_RING3MWAIT (1 << 0)
-#define HWCAP2_FSGSBASE BIT(1)
+#include <linux/const.h>
+#define HWCAP2_RING3MWAIT _BITUL(0)
+#define HWCAP2_FSGSBASE _BITUL(1)
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 0d82c5d..caf8fc0 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -146,6 +146,17 @@
   __u64 apic_base;
   __u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
 };
+struct kvm_sregs2 {
+  struct kvm_segment cs, ds, es, fs, gs, ss;
+  struct kvm_segment tr, ldt;
+  struct kvm_dtable gdt, idt;
+  __u64 cr0, cr2, cr3, cr4, cr8;
+  __u64 efer;
+  __u64 apic_base;
+  __u64 flags;
+  __u64 pdptrs[4];
+};
+#define KVM_SREGS2_FLAGS_PDPTRS_VALID 1
 struct kvm_fpu {
   __u8 fpr[8][16];
   __u16 fcw;
@@ -246,6 +257,7 @@
 #define KVM_GUESTDBG_USE_HW_BP 0x00020000
 #define KVM_GUESTDBG_INJECT_DB 0x00040000
 #define KVM_GUESTDBG_INJECT_BP 0x00080000
+#define KVM_GUESTDBG_BLOCKIRQ 0x00100000
 struct kvm_guest_debug_arch {
   __u64 debugreg[8];
 };
@@ -310,6 +322,7 @@
 };
 struct kvm_xsave {
   __u32 region[1024];
+  __u32 extra[0];
 };
 #define KVM_MAX_XCRS 16
 struct kvm_xcr {
@@ -349,6 +362,7 @@
 #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000
 #define KVM_STATE_NESTED_SVM_VMCB_SIZE 0x1000
 #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001
+#define KVM_X86_XCOMP_GUEST_SUPP 0
 struct kvm_vmx_nested_state_data {
   __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
   __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
@@ -359,6 +373,7 @@
   struct {
     __u16 flags;
   } smm;
+  __u16 pad;
   __u32 flags;
   __u64 preemption_timer_deadline;
 };
@@ -392,4 +407,6 @@
 };
 #define KVM_PMU_EVENT_ALLOW 0
 #define KVM_PMU_EVENT_DENY 1
+#define KVM_VCPU_TSC_CTRL 0
+#define KVM_VCPU_TSC_OFFSET 0
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm_para.h b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
index 091fb27..dd72af0 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm_para.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
@@ -20,6 +20,7 @@
 #define _UAPI_ASM_X86_KVM_PARA_H
 #include <linux/types.h>
 #define KVM_CPUID_SIGNATURE 0x40000000
+#define KVM_SIGNATURE "KVMKVMKVM\0\0\0"
 #define KVM_CPUID_FEATURES 0x40000001
 #define KVM_FEATURE_CLOCKSOURCE 0
 #define KVM_FEATURE_NOP_IO_DELAY 1
@@ -36,6 +37,8 @@
 #define KVM_FEATURE_PV_SCHED_YIELD 13
 #define KVM_FEATURE_ASYNC_PF_INT 14
 #define KVM_FEATURE_MSI_EXT_DEST_ID 15
+#define KVM_FEATURE_HC_MAP_GPA_RANGE 16
+#define KVM_FEATURE_MIGRATION_CONTROL 17
 #define KVM_HINTS_REALTIME 0
 #define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 24
 #define MSR_KVM_WALL_CLOCK 0x11
@@ -49,6 +52,7 @@
 #define MSR_KVM_POLL_CONTROL 0x4b564d05
 #define MSR_KVM_ASYNC_PF_INT 0x4b564d06
 #define MSR_KVM_ASYNC_PF_ACK 0x4b564d07
+#define MSR_KVM_MIGRATION_CONTROL 0x4b564d08
 struct kvm_steal_time {
   __u64 steal;
   __u32 version;
@@ -76,6 +80,13 @@
 #define KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT (1 << 2)
 #define KVM_ASYNC_PF_DELIVERY_AS_INT (1 << 3)
 #define KVM_ASYNC_PF_VEC_MASK GENMASK(7, 0)
+#define KVM_MIGRATION_READY (1 << 0)
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M (1 << 0)
+#define KVM_MAP_GPA_RANGE_PAGE_SZ_1G (1 << 1)
+#define KVM_MAP_GPA_RANGE_ENC_STAT(n) (n << 4)
+#define KVM_MAP_GPA_RANGE_ENCRYPTED KVM_MAP_GPA_RANGE_ENC_STAT(1)
+#define KVM_MAP_GPA_RANGE_DECRYPTED KVM_MAP_GPA_RANGE_ENC_STAT(0)
 #define KVM_MMU_OP_WRITE_PTE 1
 #define KVM_MMU_OP_FLUSH_TLB 2
 #define KVM_MMU_OP_RELEASE_PT 3
diff --git a/libc/kernel/uapi/asm-x86/asm/prctl.h b/libc/kernel/uapi/asm-x86/asm/prctl.h
index 0e6bed9..c5ba2d6 100644
--- a/libc/kernel/uapi/asm-x86/asm/prctl.h
+++ b/libc/kernel/uapi/asm-x86/asm/prctl.h
@@ -24,6 +24,11 @@
 #define ARCH_GET_GS 0x1004
 #define ARCH_GET_CPUID 0x1011
 #define ARCH_SET_CPUID 0x1012
+#define ARCH_GET_XCOMP_SUPP 0x1021
+#define ARCH_GET_XCOMP_PERM 0x1022
+#define ARCH_REQ_XCOMP_PERM 0x1023
+#define ARCH_GET_XCOMP_GUEST_PERM 0x1024
+#define ARCH_REQ_XCOMP_GUEST_PERM 0x1025
 #define ARCH_MAP_VDSO_X32 0x2001
 #define ARCH_MAP_VDSO_32 0x2002
 #define ARCH_MAP_VDSO_64 0x2003
diff --git a/libc/kernel/uapi/asm-x86/asm/sgx.h b/libc/kernel/uapi/asm-x86/asm/sgx.h
index 349791a..1874b78 100644
--- a/libc/kernel/uapi/asm-x86/asm/sgx.h
+++ b/libc/kernel/uapi/asm-x86/asm/sgx.h
@@ -28,6 +28,7 @@
 #define SGX_IOC_ENCLAVE_ADD_PAGES _IOWR(SGX_MAGIC, 0x01, struct sgx_enclave_add_pages)
 #define SGX_IOC_ENCLAVE_INIT _IOW(SGX_MAGIC, 0x02, struct sgx_enclave_init)
 #define SGX_IOC_ENCLAVE_PROVISION _IOW(SGX_MAGIC, 0x03, struct sgx_enclave_provision)
+#define SGX_IOC_VEPC_REMOVE_ALL _IO(SGX_MAGIC, 0x04)
 struct sgx_enclave_create {
   __u64 src;
 };
diff --git a/libc/kernel/uapi/asm-x86/asm/svm.h b/libc/kernel/uapi/asm-x86/asm/svm.h
index db9918b..d051481 100644
--- a/libc/kernel/uapi/asm-x86/asm/svm.h
+++ b/libc/kernel/uapi/asm-x86/asm/svm.h
@@ -123,6 +123,7 @@
 #define SVM_VMGEXIT_SET_AP_JUMP_TABLE 0
 #define SVM_VMGEXIT_GET_AP_JUMP_TABLE 1
 #define SVM_VMGEXIT_UNSUPPORTED_EVENT 0x8000ffff
+#define SVM_EXIT_SW 0xf0000000
 #define SVM_EXIT_ERR - 1
 #define SVM_EXIT_REASONS { SVM_EXIT_READ_CR0, "read_cr0" }, { SVM_EXIT_READ_CR2, "read_cr2" }, { SVM_EXIT_READ_CR3, "read_cr3" }, { SVM_EXIT_READ_CR4, "read_cr4" }, { SVM_EXIT_READ_CR8, "read_cr8" }, { SVM_EXIT_WRITE_CR0, "write_cr0" }, { SVM_EXIT_WRITE_CR2, "write_cr2" }, { SVM_EXIT_WRITE_CR3, "write_cr3" }, { SVM_EXIT_WRITE_CR4, "write_cr4" }, { SVM_EXIT_WRITE_CR8, "write_cr8" }, { SVM_EXIT_READ_DR0, "read_dr0" }, { SVM_EXIT_READ_DR1, "read_dr1" }, { SVM_EXIT_READ_DR2, "read_dr2" }, { SVM_EXIT_READ_DR3, "read_dr3" }, { SVM_EXIT_READ_DR4, "read_dr4" }, { SVM_EXIT_READ_DR5, "read_dr5" }, { SVM_EXIT_READ_DR6, "read_dr6" }, { SVM_EXIT_READ_DR7, "read_dr7" }, { SVM_EXIT_WRITE_DR0, "write_dr0" }, { SVM_EXIT_WRITE_DR1, "write_dr1" }, { SVM_EXIT_WRITE_DR2, "write_dr2" }, { SVM_EXIT_WRITE_DR3, "write_dr3" }, { SVM_EXIT_WRITE_DR4, "write_dr4" }, { SVM_EXIT_WRITE_DR5, "write_dr5" }, { SVM_EXIT_WRITE_DR6, "write_dr6" }, { SVM_EXIT_WRITE_DR7, "write_dr7" }, { SVM_EXIT_EXCP_BASE + DE_VECTOR, "DE excp" }, { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" }, { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" }, { SVM_EXIT_EXCP_BASE + OF_VECTOR, "OF excp" }, { SVM_EXIT_EXCP_BASE + BR_VECTOR, "BR excp" }, { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" }, { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" }, { SVM_EXIT_EXCP_BASE + DF_VECTOR, "DF excp" }, { SVM_EXIT_EXCP_BASE + TS_VECTOR, "TS excp" }, { SVM_EXIT_EXCP_BASE + NP_VECTOR, "NP excp" }, { SVM_EXIT_EXCP_BASE + SS_VECTOR, "SS excp" }, { SVM_EXIT_EXCP_BASE + GP_VECTOR, "GP excp" }, { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" }, { SVM_EXIT_EXCP_BASE + MF_VECTOR, "MF excp" }, { SVM_EXIT_EXCP_BASE + AC_VECTOR, "AC excp" }, { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" }, { SVM_EXIT_EXCP_BASE + XM_VECTOR, "XF excp" }, { SVM_EXIT_INTR, "interrupt" }, { SVM_EXIT_NMI, "nmi" }, { SVM_EXIT_SMI, "smi" }, { SVM_EXIT_INIT, "init" }, { SVM_EXIT_VINTR, "vintr" }, { SVM_EXIT_CR0_SEL_WRITE, "cr0_sel_write" }, { SVM_EXIT_IDTR_READ, "read_idtr" }, { SVM_EXIT_GDTR_READ, "read_gdtr" }, { SVM_EXIT_LDTR_READ, "read_ldtr" }, { SVM_EXIT_TR_READ, "read_rt" }, { SVM_EXIT_IDTR_WRITE, "write_idtr" }, { SVM_EXIT_GDTR_WRITE, "write_gdtr" }, { SVM_EXIT_LDTR_WRITE, "write_ldtr" }, { SVM_EXIT_TR_WRITE, "write_rt" }, { SVM_EXIT_RDTSC, "rdtsc" }, { SVM_EXIT_RDPMC, "rdpmc" }, { SVM_EXIT_PUSHF, "pushf" }, { SVM_EXIT_POPF, "popf" }, { SVM_EXIT_CPUID, "cpuid" }, { SVM_EXIT_RSM, "rsm" }, { SVM_EXIT_IRET, "iret" }, { SVM_EXIT_SWINT, "swint" }, { SVM_EXIT_INVD, "invd" }, { SVM_EXIT_PAUSE, "pause" }, { SVM_EXIT_HLT, "hlt" }, { SVM_EXIT_INVLPG, "invlpg" }, { SVM_EXIT_INVLPGA, "invlpga" }, { SVM_EXIT_IOIO, "io" }, { SVM_EXIT_MSR, "msr" }, { SVM_EXIT_TASK_SWITCH, "task_switch" }, { SVM_EXIT_FERR_FREEZE, "ferr_freeze" }, { SVM_EXIT_SHUTDOWN, "shutdown" }, { SVM_EXIT_VMRUN, "vmrun" }, { SVM_EXIT_VMMCALL, "hypercall" }, { SVM_EXIT_VMLOAD, "vmload" }, { SVM_EXIT_VMSAVE, "vmsave" }, { SVM_EXIT_STGI, "stgi" }, { SVM_EXIT_CLGI, "clgi" }, { SVM_EXIT_SKINIT, "skinit" }, { SVM_EXIT_RDTSCP, "rdtscp" }, { SVM_EXIT_ICEBP, "icebp" }, { SVM_EXIT_WBINVD, "wbinvd" }, { SVM_EXIT_MONITOR, "monitor" }, { SVM_EXIT_MWAIT, "mwait" }, { SVM_EXIT_XSETBV, "xsetbv" }, { SVM_EXIT_EFER_WRITE_TRAP, "write_efer_trap" }, { SVM_EXIT_CR0_WRITE_TRAP, "write_cr0_trap" }, { SVM_EXIT_CR4_WRITE_TRAP, "write_cr4_trap" }, { SVM_EXIT_CR8_WRITE_TRAP, "write_cr8_trap" }, { SVM_EXIT_INVPCID, "invpcid" }, { SVM_EXIT_NPF, "npf" }, { SVM_EXIT_AVIC_INCOMPLETE_IPI, "avic_incomplete_ipi" }, { SVM_EXIT_AVIC_UNACCELERATED_ACCESS, "avic_unaccelerated_access" }, { SVM_EXIT_VMGEXIT, "vmgexit" }, { SVM_VMGEXIT_MMIO_READ, "vmgexit_mmio_read" }, { SVM_VMGEXIT_MMIO_WRITE, "vmgexit_mmio_write" }, { SVM_VMGEXIT_NMI_COMPLETE, "vmgexit_nmi_complete" }, { SVM_VMGEXIT_AP_HLT_LOOP, "vmgexit_ap_hlt_loop" }, { SVM_VMGEXIT_AP_JUMP_TABLE, "vmgexit_ap_jump_table" }, { SVM_EXIT_ERR, "invalid_guest_state" }
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index 7fe2421..8e57516 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _ASM_X86_UNISTD_32_H
-#define _ASM_X86_UNISTD_32_H 1
+#ifndef _UAPI_ASM_UNISTD_32_H
+#define _UAPI_ASM_UNISTD_32_H
 #define __NR_restart_syscall 0
 #define __NR_exit 1
 #define __NR_fork 2
@@ -450,4 +450,12 @@
 #define __NR_process_madvise 440
 #define __NR_epoll_pwait2 441
 #define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#define __NR_memfd_secret 447
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index 7e3c924..54ff16f 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _ASM_X86_UNISTD_64_H
-#define _ASM_X86_UNISTD_64_H 1
+#ifndef _UAPI_ASM_UNISTD_64_H
+#define _UAPI_ASM_UNISTD_64_H
 #define __NR_read 0
 #define __NR_write 1
 #define __NR_open 2
@@ -372,4 +372,12 @@
 #define __NR_process_madvise 440
 #define __NR_epoll_pwait2 441
 #define __NR_mount_setattr 442
+#define __NR_quotactl_fd 443
+#define __NR_landlock_create_ruleset 444
+#define __NR_landlock_add_rule 445
+#define __NR_landlock_restrict_self 446
+#define __NR_memfd_secret 447
+#define __NR_process_mrelease 448
+#define __NR_futex_waitv 449
+#define __NR_set_mempolicy_home_node 450
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index 529ded3..1e05d75 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _ASM_X86_UNISTD_X32_H
-#define _ASM_X86_UNISTD_X32_H 1
+#ifndef _UAPI_ASM_UNISTD_X32_H
+#define _UAPI_ASM_UNISTD_X32_H
 #define __NR_read (__X32_SYSCALL_BIT + 0)
 #define __NR_write (__X32_SYSCALL_BIT + 1)
 #define __NR_open (__X32_SYSCALL_BIT + 2)
@@ -325,6 +325,14 @@
 #define __NR_process_madvise (__X32_SYSCALL_BIT + 440)
 #define __NR_epoll_pwait2 (__X32_SYSCALL_BIT + 441)
 #define __NR_mount_setattr (__X32_SYSCALL_BIT + 442)
+#define __NR_quotactl_fd (__X32_SYSCALL_BIT + 443)
+#define __NR_landlock_create_ruleset (__X32_SYSCALL_BIT + 444)
+#define __NR_landlock_add_rule (__X32_SYSCALL_BIT + 445)
+#define __NR_landlock_restrict_self (__X32_SYSCALL_BIT + 446)
+#define __NR_memfd_secret (__X32_SYSCALL_BIT + 447)
+#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_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/asm-x86/asm/vmx.h b/libc/kernel/uapi/asm-x86/asm/vmx.h
index 1771faa..6c07d4c 100644
--- a/libc/kernel/uapi/asm-x86/asm/vmx.h
+++ b/libc/kernel/uapi/asm-x86/asm/vmx.h
@@ -19,6 +19,7 @@
 #ifndef _UAPIVMX_H
 #define _UAPIVMX_H
 #define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000
+#define VMX_EXIT_REASONS_SGX_ENCLAVE_MODE 0x08000000
 #define EXIT_REASON_EXCEPTION_NMI 0
 #define EXIT_REASON_EXTERNAL_INTERRUPT 1
 #define EXIT_REASON_TRIPLE_FAULT 2
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index f8eb023..3764d51 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -65,13 +65,13 @@
 #define AMDGPU_GEM_CREATE_NO_CPU_ACCESS (1 << 1)
 #define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
 #define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
-#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
 #define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5)
 #define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6)
 #define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7)
 #define AMDGPU_GEM_CREATE_CP_MQD_GFX9 (1 << 8)
 #define AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE (1 << 9)
 #define AMDGPU_GEM_CREATE_ENCRYPTED (1 << 10)
+#define AMDGPU_GEM_CREATE_PREEMPTIBLE (1 << 11)
 struct drm_amdgpu_gem_create_in {
   __u64 bo_size;
   __u64 alignment;
@@ -452,6 +452,7 @@
 #define AMDGPU_INFO_VBIOS 0x1B
 #define AMDGPU_INFO_VBIOS_SIZE 0x1
 #define AMDGPU_INFO_VBIOS_IMAGE 0x2
+#define AMDGPU_INFO_VBIOS_INFO 0x3
 #define AMDGPU_INFO_NUM_HANDLES 0x1C
 #define AMDGPU_INFO_SENSOR 0x1D
 #define AMDGPU_INFO_SENSOR_GFX_SCLK 0x1
@@ -480,6 +481,9 @@
 #define AMDGPU_INFO_RAS_ENABLED_MP0 (1 << 11)
 #define AMDGPU_INFO_RAS_ENABLED_MP1 (1 << 12)
 #define AMDGPU_INFO_RAS_ENABLED_FUSE (1 << 13)
+#define AMDGPU_INFO_VIDEO_CAPS 0x21
+#define AMDGPU_INFO_VIDEO_CAPS_DECODE 0
+#define AMDGPU_INFO_VIDEO_CAPS_ENCODE 1
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
 #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
@@ -517,6 +521,9 @@
     struct {
       __u32 type;
     } sensor_info;
+    struct {
+      __u32 type;
+    } video_cap;
   };
 };
 struct drm_amdgpu_info_gds {
@@ -549,6 +556,14 @@
   __u32 ver;
   __u32 feature;
 };
+struct drm_amdgpu_info_vbios {
+  __u8 name[64];
+  __u8 vbios_pn[64];
+  __u32 version;
+  __u32 pad;
+  __u8 vbios_ver_str[32];
+  __u8 date[32];
+};
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2 2
@@ -636,6 +651,26 @@
   __u32 num_valid_entries;
   __u32 pad;
 };
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2 0
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4 1
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1 2
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC 3
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC 4
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG 5
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9 6
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1 7
+#define AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_COUNT 8
+struct drm_amdgpu_info_video_codec_info {
+  __u32 valid;
+  __u32 max_width;
+  __u32 max_height;
+  __u32 max_pixels_per_frame;
+  __u32 max_level;
+  __u32 pad;
+};
+struct drm_amdgpu_info_video_caps {
+  struct drm_amdgpu_info_video_codec_info codec_info[AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_COUNT];
+};
 #define AMDGPU_FAMILY_UNKNOWN 0
 #define AMDGPU_FAMILY_SI 110
 #define AMDGPU_FAMILY_CI 120
@@ -646,6 +681,7 @@
 #define AMDGPU_FAMILY_RV 142
 #define AMDGPU_FAMILY_NV 143
 #define AMDGPU_FAMILY_VGH 144
+#define AMDGPU_FAMILY_YC 146
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 4574c1c..e845c8c 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -27,6 +27,8 @@
 #define DRM_FORMAT_INVALID 0
 #define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')
 #define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
+#define DRM_FORMAT_R10 fourcc_code('R', '1', '0', ' ')
+#define DRM_FORMAT_R12 fourcc_code('R', '1', '2', ' ')
 #define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
 #define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
 #define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
@@ -70,6 +72,10 @@
 #define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0')
 #define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0')
 #define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0')
+#define DRM_FORMAT_XRGB16161616 fourcc_code('X', 'R', '4', '8')
+#define DRM_FORMAT_XBGR16161616 fourcc_code('X', 'B', '4', '8')
+#define DRM_FORMAT_ARGB16161616 fourcc_code('A', 'R', '4', '8')
+#define DRM_FORMAT_ABGR16161616 fourcc_code('A', 'B', '4', '8')
 #define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H')
 #define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H')
 #define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H')
@@ -117,6 +123,7 @@
 #define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0')
 #define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2')
 #define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6')
+#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0')
 #define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0')
 #define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
 #define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9')
@@ -141,6 +148,8 @@
 #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09
 #define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a
 #define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
+#define fourcc_mod_get_vendor(modifier) (((modifier) >> 56) & 0xff)
+#define fourcc_mod_is_vendor(modifier,vendor) (fourcc_mod_get_vendor(modifier) == DRM_FORMAT_MOD_VENDOR_ ##vendor)
 #define fourcc_mod_code(vendor,val) ((((__u64) DRM_FORMAT_MOD_VENDOR_ ##vendor) << 56) | ((val) & 0x00ffffffffffffffULL))
 #define DRM_FORMAT_MOD_GENERIC_16_16_TILE DRM_FORMAT_MOD_SAMSUNG_16_16_TILE
 #define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
@@ -203,6 +212,15 @@
 #define AFBC_FORMAT_MOD_DB (1ULL << 10)
 #define AFBC_FORMAT_MOD_BCH (1ULL << 11)
 #define AFBC_FORMAT_MOD_USM (1ULL << 12)
+#define DRM_FORMAT_MOD_ARM_TYPE_AFRC 0x02
+#define DRM_FORMAT_MOD_ARM_AFRC(__afrc_mode) DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_AFRC, __afrc_mode)
+#define AFRC_FORMAT_MOD_CU_SIZE_MASK 0xf
+#define AFRC_FORMAT_MOD_CU_SIZE_16 (1ULL)
+#define AFRC_FORMAT_MOD_CU_SIZE_24 (2ULL)
+#define AFRC_FORMAT_MOD_CU_SIZE_32 (3ULL)
+#define AFRC_FORMAT_MOD_CU_SIZE_P0(__afrc_cu_size) (__afrc_cu_size)
+#define AFRC_FORMAT_MOD_CU_SIZE_P12(__afrc_cu_size) ((__afrc_cu_size) << 4)
+#define AFRC_FORMAT_MOD_LAYOUT_SCAN (1ULL << 8)
 #define DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_MISC, 1ULL)
 #define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1)
 #define __fourcc_mod_amlogic_layout_mask 0xff
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index 643ae98..9a6a6d9 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -223,6 +223,7 @@
 #define DRM_MODE_CONNECTOR_DPI 17
 #define DRM_MODE_CONNECTOR_WRITEBACK 18
 #define DRM_MODE_CONNECTOR_SPI 19
+#define DRM_MODE_CONNECTOR_USB 20
 struct drm_mode_get_connector {
   __u64 encoders_ptr;
   __u64 modes_ptr;
diff --git a/libc/kernel/uapi/drm/etnaviv_drm.h b/libc/kernel/uapi/drm/etnaviv_drm.h
index c92d110..7f8d5fa 100644
--- a/libc/kernel/uapi/drm/etnaviv_drm.h
+++ b/libc/kernel/uapi/drm/etnaviv_drm.h
@@ -53,6 +53,9 @@
 #define ETNAVIV_PARAM_GPU_NUM_CONSTANTS 0x19
 #define ETNAVIV_PARAM_GPU_NUM_VARYINGS 0x1a
 #define ETNAVIV_PARAM_SOFTPIN_START_ADDR 0x1b
+#define ETNAVIV_PARAM_GPU_PRODUCT_ID 0x1c
+#define ETNAVIV_PARAM_GPU_CUSTOMER_ID 0x1d
+#define ETNAVIV_PARAM_GPU_ECO_ID 0x1e
 #define ETNA_MAX_PIPES 4
 struct drm_etnaviv_param {
   __u32 pipe;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index f265d92..52bfad2 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -217,6 +217,7 @@
 #define DRM_I915_QUERY 0x39
 #define DRM_I915_GEM_VM_CREATE 0x3a
 #define DRM_I915_GEM_VM_DESTROY 0x3b
+#define DRM_I915_GEM_CREATE_EXT 0x3c
 #define DRM_IOCTL_I915_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
 #define DRM_IOCTL_I915_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLUSH)
 #define DRM_IOCTL_I915_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLIP)
@@ -247,6 +248,7 @@
 #define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
 #define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
 #define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_CREATE_EXT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE_EXT, struct drm_i915_gem_create_ext)
 #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
@@ -349,6 +351,7 @@
 #define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2)
 #define I915_SCHEDULER_CAP_SEMAPHORES (1ul << 3)
 #define I915_SCHEDULER_CAP_ENGINE_BUSY_STATS (1ul << 4)
+#define I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP (1ul << 5)
 #define I915_PARAM_HUC_STATUS 42
 #define I915_PARAM_HAS_EXEC_ASYNC 43
 #define I915_PARAM_HAS_EXEC_FENCE 44
@@ -363,6 +366,7 @@
 #define I915_PARAM_HAS_EXEC_SUBMIT_FENCE 53
 #define I915_PARAM_PERF_REVISION 54
 #define I915_PARAM_HAS_EXEC_TIMELINE_FENCES 55
+#define I915_PARAM_HAS_USERPTR_PROBE 56
 typedef struct drm_i915_getparam {
   __s32 param;
   int __user * value;
@@ -453,6 +457,7 @@
 #define I915_MMAP_OFFSET_WC 1
 #define I915_MMAP_OFFSET_WB 2
 #define I915_MMAP_OFFSET_UC 3
+#define I915_MMAP_OFFSET_FIXED 4
   __u64 extensions;
 };
 struct drm_i915_gem_set_domain {
@@ -590,11 +595,11 @@
   __u32 handle;
   __u32 busy;
 };
+struct drm_i915_gem_caching {
+  __u32 handle;
 #define I915_CACHING_NONE 0
 #define I915_CACHING_CACHED 1
 #define I915_CACHING_DISPLAY 2
-struct drm_i915_gem_caching {
-  __u32 handle;
   __u32 caching;
 };
 #define I915_TILING_NONE 0
@@ -736,6 +741,7 @@
 #define I915_CONTEXT_PARAM_ENGINES 0xa
 #define I915_CONTEXT_PARAM_PERSISTENCE 0xb
 #define I915_CONTEXT_PARAM_RINGSIZE 0xc
+#define I915_CONTEXT_PARAM_PROTECTED_CONTENT 0xd
   __u64 value;
 };
 struct drm_i915_gem_context_param_sseu {
@@ -769,10 +775,23 @@
 } __attribute__((packed));
 #define I915_DEFINE_CONTEXT_ENGINES_BOND(name__,N__) struct { struct i915_user_extension base; struct i915_engine_class_instance master; __u16 virtual_index; __u16 num_bonds; __u64 flags; __u64 mbz64[4]; struct i915_engine_class_instance engines[N__]; \
 } __attribute__((packed)) name__
+struct i915_context_engines_parallel_submit {
+  struct i915_user_extension base;
+  __u16 engine_index;
+  __u16 width;
+  __u16 num_siblings;
+  __u16 mbz16;
+  __u64 flags;
+  __u64 mbz64[3];
+  struct i915_engine_class_instance engines[0];
+} __packed;
+#define I915_DEFINE_CONTEXT_ENGINES_PARALLEL_SUBMIT(name__,N__) struct { struct i915_user_extension base; __u16 engine_index; __u16 width; __u16 num_siblings; __u16 mbz16; __u64 flags; __u64 mbz64[3]; struct i915_engine_class_instance engines[N__]; \
+} __attribute__((packed)) name__
 struct i915_context_param_engines {
   __u64 extensions;
 #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];
 } __attribute__((packed));
 #define I915_DEFINE_CONTEXT_PARAM_ENGINES(name__,N__) struct { __u64 extensions; struct i915_engine_class_instance engines[N__]; \
@@ -782,20 +801,7 @@
   struct i915_user_extension base;
   struct drm_i915_gem_context_param param;
 };
-struct drm_i915_gem_context_create_ext_clone {
 #define I915_CONTEXT_CREATE_EXT_CLONE 1
-  struct i915_user_extension base;
-  __u32 clone_id;
-  __u32 flags;
-#define I915_CONTEXT_CLONE_ENGINES (1u << 0)
-#define I915_CONTEXT_CLONE_FLAGS (1u << 1)
-#define I915_CONTEXT_CLONE_SCHEDATTR (1u << 2)
-#define I915_CONTEXT_CLONE_SSEU (1u << 3)
-#define I915_CONTEXT_CLONE_TIMELINE (1u << 4)
-#define I915_CONTEXT_CLONE_VM (1u << 5)
-#define I915_CONTEXT_CLONE_UNKNOWN - (I915_CONTEXT_CLONE_VM << 1)
-  __u64 rsvd;
-};
 struct drm_i915_gem_context_destroy {
   __u32 ctx_id;
   __u32 pad;
@@ -823,6 +829,7 @@
   __u64 user_size;
   __u32 flags;
 #define I915_USERPTR_READ_ONLY 0x1
+#define I915_USERPTR_PROBE 0x2
 #define I915_USERPTR_UNSYNCHRONIZED 0x80000000
   __u32 handle;
 };
@@ -886,6 +893,7 @@
 #define DRM_I915_QUERY_TOPOLOGY_INFO 1
 #define DRM_I915_QUERY_ENGINE_INFO 2
 #define DRM_I915_QUERY_PERF_CONFIG 3
+#define DRM_I915_QUERY_MEMORY_REGIONS 4
   __s32 length;
   __u32 flags;
 #define DRM_I915_QUERY_PERF_CONFIG_LIST 1
@@ -913,10 +921,13 @@
   struct i915_engine_class_instance engine;
   __u32 rsvd0;
   __u64 flags;
+#define I915_ENGINE_INFO_HAS_LOGICAL_INSTANCE (1 << 0)
   __u64 capabilities;
 #define I915_VIDEO_CLASS_CAPABILITY_HEVC (1 << 0)
 #define I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC (1 << 1)
-  __u64 rsvd1[4];
+  __u16 logical_instance;
+  __u16 rsvd1[3];
+  __u64 rsvd2[3];
 };
 struct drm_i915_query_engine_info {
   __u32 num_engines;
@@ -932,6 +943,45 @@
   __u32 flags;
   __u8 data[];
 };
+enum drm_i915_gem_memory_class {
+  I915_MEMORY_CLASS_SYSTEM = 0,
+  I915_MEMORY_CLASS_DEVICE,
+};
+struct drm_i915_gem_memory_class_instance {
+  __u16 memory_class;
+  __u16 memory_instance;
+};
+struct drm_i915_memory_region_info {
+  struct drm_i915_gem_memory_class_instance region;
+  __u32 rsvd0;
+  __u64 probed_size;
+  __u64 unallocated_size;
+  __u64 rsvd1[8];
+};
+struct drm_i915_query_memory_regions {
+  __u32 num_regions;
+  __u32 rsvd[3];
+  struct drm_i915_memory_region_info regions[];
+};
+struct drm_i915_gem_create_ext {
+  __u64 size;
+  __u32 handle;
+  __u32 flags;
+#define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
+#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
+  __u64 extensions;
+};
+struct drm_i915_gem_create_ext_memory_regions {
+  struct i915_user_extension base;
+  __u32 pad;
+  __u32 num_regions;
+  __u64 regions;
+};
+struct drm_i915_gem_create_ext_protected_content {
+  struct i915_user_extension base;
+  __u32 flags;
+};
+#define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/drm/mga_drm.h b/libc/kernel/uapi/drm/mga_drm.h
index 4959502..dc62961 100644
--- a/libc/kernel/uapi/drm/mga_drm.h
+++ b/libc/kernel/uapi/drm/mga_drm.h
@@ -175,7 +175,7 @@
     MGA_CLEANUP_DMA = 0x02
   } func;
   unsigned long sarea_priv_offset;
-  int chipset;
+  __struct_group(, always32bit,, int chipset;
   int sgram;
   unsigned int maccess;
   unsigned int fb_cpp;
@@ -185,6 +185,7 @@
   unsigned int depth_offset, depth_pitch;
   unsigned int texture_offset[MGA_NR_TEX_HEAPS];
   unsigned int texture_size[MGA_NR_TEX_HEAPS];
+ );
   unsigned long fb_offset;
   unsigned long mmio_offset;
   unsigned long status_offset;
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index fcfcc20..b4ba1d0 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -39,9 +39,11 @@
 #define MSM_PARAM_MAX_FREQ 0x04
 #define MSM_PARAM_TIMESTAMP 0x05
 #define MSM_PARAM_GMEM_BASE 0x06
-#define MSM_PARAM_NR_RINGS 0x07
+#define MSM_PARAM_PRIORITIES 0x07
 #define MSM_PARAM_PP_PGTABLE 0x08
 #define MSM_PARAM_FAULTS 0x09
+#define MSM_PARAM_SUSPENDS 0x0a
+#define MSM_PARAM_NR_RINGS MSM_PARAM_PRIORITIES
 struct drm_msm_param {
   __u32 pipe;
   __u32 param;
@@ -53,7 +55,8 @@
 #define MSM_BO_CACHED 0x00010000
 #define MSM_BO_WC 0x00020000
 #define MSM_BO_UNCACHED 0x00040000
-#define MSM_BO_FLAGS (MSM_BO_SCANOUT | MSM_BO_GPU_READONLY | MSM_BO_CACHED | MSM_BO_WC | MSM_BO_UNCACHED)
+#define MSM_BO_CACHED_COHERENT 0x080000
+#define MSM_BO_FLAGS (MSM_BO_SCANOUT | MSM_BO_GPU_READONLY | MSM_BO_CACHE_MASK)
 struct drm_msm_gem_new {
   __u64 size;
   __u32 flags;
diff --git a/libc/kernel/uapi/drm/panfrost_drm.h b/libc/kernel/uapi/drm/panfrost_drm.h
index f8b8aa1..1f4473d 100644
--- a/libc/kernel/uapi/drm/panfrost_drm.h
+++ b/libc/kernel/uapi/drm/panfrost_drm.h
@@ -110,6 +110,7 @@
   DRM_PANFROST_PARAM_JS_FEATURES15,
   DRM_PANFROST_PARAM_NR_CORE_GROUPS,
   DRM_PANFROST_PARAM_THREAD_TLS_ALLOC,
+  DRM_PANFROST_PARAM_AFBC_FEATURES,
 };
 struct drm_panfrost_get_param {
   __u32 param;
diff --git a/libc/kernel/uapi/drm/tegra_drm.h b/libc/kernel/uapi/drm/tegra_drm.h
index 5244a27..5e90635 100644
--- a/libc/kernel/uapi/drm/tegra_drm.h
+++ b/libc/kernel/uapi/drm/tegra_drm.h
@@ -163,6 +163,104 @@
 #define DRM_IOCTL_TEGRA_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_TILING, struct drm_tegra_gem_get_tiling)
 #define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)
 #define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags)
+#define DRM_TEGRA_CHANNEL_CAP_CACHE_COHERENT (1 << 0)
+struct drm_tegra_channel_open {
+  __u32 host1x_class;
+  __u32 flags;
+  __u32 context;
+  __u32 version;
+  __u32 capabilities;
+  __u32 padding;
+};
+struct drm_tegra_channel_close {
+  __u32 context;
+  __u32 padding;
+};
+#define DRM_TEGRA_CHANNEL_MAP_READ (1 << 0)
+#define DRM_TEGRA_CHANNEL_MAP_WRITE (1 << 1)
+#define DRM_TEGRA_CHANNEL_MAP_READ_WRITE (DRM_TEGRA_CHANNEL_MAP_READ | DRM_TEGRA_CHANNEL_MAP_WRITE)
+struct drm_tegra_channel_map {
+  __u32 context;
+  __u32 handle;
+  __u32 flags;
+  __u32 mapping;
+};
+struct drm_tegra_channel_unmap {
+  __u32 context;
+  __u32 mapping;
+};
+#define DRM_TEGRA_SUBMIT_RELOC_SECTOR_LAYOUT (1 << 0)
+struct drm_tegra_submit_buf {
+  __u32 mapping;
+  __u32 flags;
+  struct {
+    __u64 target_offset;
+    __u32 gather_offset_words;
+    __u32 shift;
+  } reloc;
+};
+#define DRM_TEGRA_SUBMIT_CMD_GATHER_UPTR 0
+#define DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT 1
+#define DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT_RELATIVE 2
+struct drm_tegra_submit_cmd_gather_uptr {
+  __u32 words;
+  __u32 reserved[3];
+};
+struct drm_tegra_submit_cmd_wait_syncpt {
+  __u32 id;
+  __u32 value;
+  __u32 reserved[2];
+};
+struct drm_tegra_submit_cmd {
+  __u32 type;
+  __u32 flags;
+  union {
+    struct drm_tegra_submit_cmd_gather_uptr gather_uptr;
+    struct drm_tegra_submit_cmd_wait_syncpt wait_syncpt;
+    __u32 reserved[4];
+  };
+};
+struct drm_tegra_submit_syncpt {
+  __u32 id;
+  __u32 flags;
+  __u32 increments;
+  __u32 value;
+};
+struct drm_tegra_channel_submit {
+  __u32 context;
+  __u32 num_bufs;
+  __u32 num_cmds;
+  __u32 gather_data_words;
+  __u64 bufs_ptr;
+  __u64 cmds_ptr;
+  __u64 gather_data_ptr;
+  __u32 syncobj_in;
+  __u32 syncobj_out;
+  struct drm_tegra_submit_syncpt syncpt;
+};
+struct drm_tegra_syncpoint_allocate {
+  __u32 id;
+  __u32 padding;
+};
+struct drm_tegra_syncpoint_free {
+  __u32 id;
+  __u32 padding;
+};
+struct drm_tegra_syncpoint_wait {
+  __s64 timeout_ns;
+  __u32 id;
+  __u32 threshold;
+  __u32 value;
+  __u32 padding;
+};
+#define DRM_IOCTL_TEGRA_CHANNEL_OPEN DRM_IOWR(DRM_COMMAND_BASE + 0x10, struct drm_tegra_channel_open)
+#define DRM_IOCTL_TEGRA_CHANNEL_CLOSE DRM_IOWR(DRM_COMMAND_BASE + 0x11, struct drm_tegra_channel_close)
+#define DRM_IOCTL_TEGRA_CHANNEL_MAP DRM_IOWR(DRM_COMMAND_BASE + 0x12, struct drm_tegra_channel_map)
+#define DRM_IOCTL_TEGRA_CHANNEL_UNMAP DRM_IOWR(DRM_COMMAND_BASE + 0x13, struct drm_tegra_channel_unmap)
+#define DRM_IOCTL_TEGRA_CHANNEL_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + 0x14, struct drm_tegra_channel_submit)
+#define DRM_IOCTL_TEGRA_SYNCPOINT_ALLOCATE DRM_IOWR(DRM_COMMAND_BASE + 0x20, struct drm_tegra_syncpoint_allocate)
+#define DRM_IOCTL_TEGRA_SYNCPOINT_FREE DRM_IOWR(DRM_COMMAND_BASE + 0x21, struct drm_tegra_syncpoint_free)
+#define DRM_IOCTL_TEGRA_SYNCPOINT_WAIT DRM_IOWR(DRM_COMMAND_BASE + 0x22, struct drm_tegra_syncpoint_wait)
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/drm/v3d_drm.h b/libc/kernel/uapi/drm/v3d_drm.h
index cdc2cf5..5887678 100644
--- a/libc/kernel/uapi/drm/v3d_drm.h
+++ b/libc/kernel/uapi/drm/v3d_drm.h
@@ -30,6 +30,9 @@
 #define DRM_V3D_GET_BO_OFFSET 0x05
 #define DRM_V3D_SUBMIT_TFU 0x06
 #define DRM_V3D_SUBMIT_CSD 0x07
+#define DRM_V3D_PERFMON_CREATE 0x08
+#define DRM_V3D_PERFMON_DESTROY 0x09
+#define DRM_V3D_PERFMON_GET_VALUES 0x0a
 #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
 #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
 #define DRM_IOCTL_V3D_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_CREATE_BO, struct drm_v3d_create_bo)
@@ -38,7 +41,39 @@
 #define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset)
 #define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu)
 #define DRM_IOCTL_V3D_SUBMIT_CSD DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CSD, struct drm_v3d_submit_csd)
+#define DRM_IOCTL_V3D_PERFMON_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_CREATE, struct drm_v3d_perfmon_create)
+#define DRM_IOCTL_V3D_PERFMON_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_DESTROY, struct drm_v3d_perfmon_destroy)
+#define DRM_IOCTL_V3D_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_VALUES, struct drm_v3d_perfmon_get_values)
 #define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01
+#define DRM_V3D_SUBMIT_EXTENSION 0x02
+struct drm_v3d_extension {
+  __u64 next;
+  __u32 id;
+#define DRM_V3D_EXT_ID_MULTI_SYNC 0x01
+  __u32 flags;
+};
+struct drm_v3d_sem {
+  __u32 handle;
+  __u32 flags;
+  __u64 point;
+  __u64 mbz[2];
+};
+enum v3d_queue {
+  V3D_BIN,
+  V3D_RENDER,
+  V3D_TFU,
+  V3D_CSD,
+  V3D_CACHE_CLEAN,
+};
+struct drm_v3d_multi_sync {
+  struct drm_v3d_extension base;
+  __u64 in_syncs;
+  __u64 out_syncs;
+  __u32 in_sync_count;
+  __u32 out_sync_count;
+  __u32 wait_stage;
+  __u32 pad;
+};
 struct drm_v3d_submit_cl {
   __u32 bcl_start;
   __u32 bcl_end;
@@ -53,6 +88,9 @@
   __u64 bo_handles;
   __u32 bo_handle_count;
   __u32 flags;
+  __u32 perfmon_id;
+  __u32 pad;
+  __u64 extensions;
 };
 struct drm_v3d_wait_bo {
   __u32 handle;
@@ -81,6 +119,8 @@
   DRM_V3D_PARAM_SUPPORTS_TFU,
   DRM_V3D_PARAM_SUPPORTS_CSD,
   DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH,
+  DRM_V3D_PARAM_SUPPORTS_PERFMON,
+  DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT,
 };
 struct drm_v3d_get_param {
   __u32 param;
@@ -103,6 +143,8 @@
   __u32 bo_handles[4];
   __u32 in_sync;
   __u32 out_sync;
+  __u32 flags;
+  __u64 extensions;
 };
 struct drm_v3d_submit_csd {
   __u32 cfg[7];
@@ -111,6 +153,114 @@
   __u32 bo_handle_count;
   __u32 in_sync;
   __u32 out_sync;
+  __u32 perfmon_id;
+  __u64 extensions;
+  __u32 flags;
+  __u32 pad;
+};
+enum {
+  V3D_PERFCNT_FEP_VALID_PRIMTS_NO_PIXELS,
+  V3D_PERFCNT_FEP_VALID_PRIMS,
+  V3D_PERFCNT_FEP_EZ_NFCLIP_QUADS,
+  V3D_PERFCNT_FEP_VALID_QUADS,
+  V3D_PERFCNT_TLB_QUADS_STENCIL_FAIL,
+  V3D_PERFCNT_TLB_QUADS_STENCILZ_FAIL,
+  V3D_PERFCNT_TLB_QUADS_STENCILZ_PASS,
+  V3D_PERFCNT_TLB_QUADS_ZERO_COV,
+  V3D_PERFCNT_TLB_QUADS_NONZERO_COV,
+  V3D_PERFCNT_TLB_QUADS_WRITTEN,
+  V3D_PERFCNT_PTB_PRIM_VIEWPOINT_DISCARD,
+  V3D_PERFCNT_PTB_PRIM_CLIP,
+  V3D_PERFCNT_PTB_PRIM_REV,
+  V3D_PERFCNT_QPU_IDLE_CYCLES,
+  V3D_PERFCNT_QPU_ACTIVE_CYCLES_VERTEX_COORD_USER,
+  V3D_PERFCNT_QPU_ACTIVE_CYCLES_FRAG,
+  V3D_PERFCNT_QPU_CYCLES_VALID_INSTR,
+  V3D_PERFCNT_QPU_CYCLES_TMU_STALL,
+  V3D_PERFCNT_QPU_CYCLES_SCOREBOARD_STALL,
+  V3D_PERFCNT_QPU_CYCLES_VARYINGS_STALL,
+  V3D_PERFCNT_QPU_IC_HIT,
+  V3D_PERFCNT_QPU_IC_MISS,
+  V3D_PERFCNT_QPU_UC_HIT,
+  V3D_PERFCNT_QPU_UC_MISS,
+  V3D_PERFCNT_TMU_TCACHE_ACCESS,
+  V3D_PERFCNT_TMU_TCACHE_MISS,
+  V3D_PERFCNT_VPM_VDW_STALL,
+  V3D_PERFCNT_VPM_VCD_STALL,
+  V3D_PERFCNT_BIN_ACTIVE,
+  V3D_PERFCNT_RDR_ACTIVE,
+  V3D_PERFCNT_L2T_HITS,
+  V3D_PERFCNT_L2T_MISSES,
+  V3D_PERFCNT_CYCLE_COUNT,
+  V3D_PERFCNT_QPU_CYCLES_STALLED_VERTEX_COORD_USER,
+  V3D_PERFCNT_QPU_CYCLES_STALLED_FRAGMENT,
+  V3D_PERFCNT_PTB_PRIMS_BINNED,
+  V3D_PERFCNT_AXI_WRITES_WATCH_0,
+  V3D_PERFCNT_AXI_READS_WATCH_0,
+  V3D_PERFCNT_AXI_WRITE_STALLS_WATCH_0,
+  V3D_PERFCNT_AXI_READ_STALLS_WATCH_0,
+  V3D_PERFCNT_AXI_WRITE_BYTES_WATCH_0,
+  V3D_PERFCNT_AXI_READ_BYTES_WATCH_0,
+  V3D_PERFCNT_AXI_WRITES_WATCH_1,
+  V3D_PERFCNT_AXI_READS_WATCH_1,
+  V3D_PERFCNT_AXI_WRITE_STALLS_WATCH_1,
+  V3D_PERFCNT_AXI_READ_STALLS_WATCH_1,
+  V3D_PERFCNT_AXI_WRITE_BYTES_WATCH_1,
+  V3D_PERFCNT_AXI_READ_BYTES_WATCH_1,
+  V3D_PERFCNT_TLB_PARTIAL_QUADS,
+  V3D_PERFCNT_TMU_CONFIG_ACCESSES,
+  V3D_PERFCNT_L2T_NO_ID_STALL,
+  V3D_PERFCNT_L2T_COM_QUE_STALL,
+  V3D_PERFCNT_L2T_TMU_WRITES,
+  V3D_PERFCNT_TMU_ACTIVE_CYCLES,
+  V3D_PERFCNT_TMU_STALLED_CYCLES,
+  V3D_PERFCNT_CLE_ACTIVE,
+  V3D_PERFCNT_L2T_TMU_READS,
+  V3D_PERFCNT_L2T_CLE_READS,
+  V3D_PERFCNT_L2T_VCD_READS,
+  V3D_PERFCNT_L2T_TMUCFG_READS,
+  V3D_PERFCNT_L2T_SLC0_READS,
+  V3D_PERFCNT_L2T_SLC1_READS,
+  V3D_PERFCNT_L2T_SLC2_READS,
+  V3D_PERFCNT_L2T_TMU_W_MISSES,
+  V3D_PERFCNT_L2T_TMU_R_MISSES,
+  V3D_PERFCNT_L2T_CLE_MISSES,
+  V3D_PERFCNT_L2T_VCD_MISSES,
+  V3D_PERFCNT_L2T_TMUCFG_MISSES,
+  V3D_PERFCNT_L2T_SLC0_MISSES,
+  V3D_PERFCNT_L2T_SLC1_MISSES,
+  V3D_PERFCNT_L2T_SLC2_MISSES,
+  V3D_PERFCNT_CORE_MEM_WRITES,
+  V3D_PERFCNT_L2T_MEM_WRITES,
+  V3D_PERFCNT_PTB_MEM_WRITES,
+  V3D_PERFCNT_TLB_MEM_WRITES,
+  V3D_PERFCNT_CORE_MEM_READS,
+  V3D_PERFCNT_L2T_MEM_READS,
+  V3D_PERFCNT_PTB_MEM_READS,
+  V3D_PERFCNT_PSE_MEM_READS,
+  V3D_PERFCNT_TLB_MEM_READS,
+  V3D_PERFCNT_GMP_MEM_READS,
+  V3D_PERFCNT_PTB_W_MEM_WORDS,
+  V3D_PERFCNT_TLB_W_MEM_WORDS,
+  V3D_PERFCNT_PSE_R_MEM_WORDS,
+  V3D_PERFCNT_TLB_R_MEM_WORDS,
+  V3D_PERFCNT_TMU_MRU_HITS,
+  V3D_PERFCNT_COMPUTE_ACTIVE,
+  V3D_PERFCNT_NUM,
+};
+#define DRM_V3D_MAX_PERF_COUNTERS 32
+struct drm_v3d_perfmon_create {
+  __u32 id;
+  __u32 ncounters;
+  __u8 counters[DRM_V3D_MAX_PERF_COUNTERS];
+};
+struct drm_v3d_perfmon_destroy {
+  __u32 id;
+};
+struct drm_v3d_perfmon_get_values {
+  __u32 id;
+  __u32 pad;
+  __u64 values_ptr;
 };
 #ifdef __cplusplus
 }
diff --git a/libc/kernel/uapi/drm/virtgpu_drm.h b/libc/kernel/uapi/drm/virtgpu_drm.h
index 842c1fd..342282d 100644
--- a/libc/kernel/uapi/drm/virtgpu_drm.h
+++ b/libc/kernel/uapi/drm/virtgpu_drm.h
@@ -32,9 +32,11 @@
 #define DRM_VIRTGPU_WAIT 0x08
 #define DRM_VIRTGPU_GET_CAPS 0x09
 #define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a
+#define DRM_VIRTGPU_CONTEXT_INIT 0x0b
 #define VIRTGPU_EXECBUF_FENCE_FD_IN 0x01
 #define VIRTGPU_EXECBUF_FENCE_FD_OUT 0x02
-#define VIRTGPU_EXECBUF_FLAGS (VIRTGPU_EXECBUF_FENCE_FD_IN | VIRTGPU_EXECBUF_FENCE_FD_OUT | 0)
+#define VIRTGPU_EXECBUF_RING_IDX 0x04
+#define VIRTGPU_EXECBUF_FLAGS (VIRTGPU_EXECBUF_FENCE_FD_IN | VIRTGPU_EXECBUF_FENCE_FD_OUT | VIRTGPU_EXECBUF_RING_IDX | 0)
 struct drm_virtgpu_map {
   __u64 offset;
   __u32 handle;
@@ -47,12 +49,16 @@
   __u64 bo_handles;
   __u32 num_bo_handles;
   __s32 fence_fd;
+  __u32 ring_idx;
+  __u32 pad;
 };
 #define VIRTGPU_PARAM_3D_FEATURES 1
 #define VIRTGPU_PARAM_CAPSET_QUERY_FIX 2
 #define VIRTGPU_PARAM_RESOURCE_BLOB 3
 #define VIRTGPU_PARAM_HOST_VISIBLE 4
 #define VIRTGPU_PARAM_CROSS_DEVICE 5
+#define VIRTGPU_PARAM_CONTEXT_INIT 6
+#define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7
 struct drm_virtgpu_getparam {
   __u64 param;
   __u64 value;
@@ -132,6 +138,19 @@
   __u64 cmd;
   __u64 blob_id;
 };
+#define VIRTGPU_CONTEXT_PARAM_CAPSET_ID 0x0001
+#define VIRTGPU_CONTEXT_PARAM_NUM_RINGS 0x0002
+#define VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK 0x0003
+struct drm_virtgpu_context_set_param {
+  __u64 param;
+  __u64 value;
+};
+struct drm_virtgpu_context_init {
+  __u32 num_params;
+  __u32 pad;
+  __u64 ctx_set_params;
+};
+#define VIRTGPU_EVENT_FENCE_SIGNALED 0x90000000
 #define DRM_IOCTL_VIRTGPU_MAP DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_MAP, struct drm_virtgpu_map)
 #define DRM_IOCTL_VIRTGPU_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_EXECBUFFER, struct drm_virtgpu_execbuffer)
 #define DRM_IOCTL_VIRTGPU_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GETPARAM, struct drm_virtgpu_getparam)
@@ -142,6 +161,7 @@
 #define DRM_IOCTL_VIRTGPU_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_WAIT, struct drm_virtgpu_3d_wait)
 #define DRM_IOCTL_VIRTGPU_GET_CAPS DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_GET_CAPS, struct drm_virtgpu_get_caps)
 #define DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_CREATE_BLOB, struct drm_virtgpu_resource_create_blob)
+#define DRM_IOCTL_VIRTGPU_CONTEXT_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_CONTEXT_INIT, struct drm_virtgpu_context_init)
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index 982b64f..395743b 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -56,6 +56,9 @@
 #define DRM_VMW_GB_SURFACE_CREATE_EXT 27
 #define DRM_VMW_GB_SURFACE_REF_EXT 28
 #define DRM_VMW_MSG 29
+#define DRM_VMW_MKSSTAT_RESET 30
+#define DRM_VMW_MKSSTAT_ADD 31
+#define DRM_VMW_MKSSTAT_REMOVE 32
 #define DRM_VMW_PARAM_NUM_STREAMS 0
 #define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
 #define DRM_VMW_PARAM_3D 2
@@ -72,6 +75,7 @@
 #define DRM_VMW_PARAM_HW_CAPS2 13
 #define DRM_VMW_PARAM_SM4_1 14
 #define DRM_VMW_PARAM_SM5 15
+#define DRM_VMW_PARAM_GL43 16
 enum drm_vmw_handle_type {
   DRM_VMW_HANDLE_LEGACY = 0,
   DRM_VMW_HANDLE_PRIME = 1
@@ -360,6 +364,19 @@
   __s32 send_only;
   __u32 receive_len;
 };
+struct drm_vmw_mksstat_add_arg {
+  __u64 stat;
+  __u64 info;
+  __u64 strs;
+  __u64 stat_len;
+  __u64 info_len;
+  __u64 strs_len;
+  __u64 description;
+  __u64 id;
+};
+struct drm_vmw_mksstat_remove_arg {
+  __u64 id;
+};
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/linux/acrn.h b/libc/kernel/uapi/linux/acrn.h
index 74b719a..c991ac0 100644
--- a/libc/kernel/uapi/linux/acrn.h
+++ b/libc/kernel/uapi/linux/acrn.h
@@ -178,6 +178,7 @@
   } intx;
 };
 #define ACRN_PTDEV_QUIRK_ASSIGN (1U << 0)
+#define ACRN_MMIODEV_RES_NUM 3
 #define ACRN_PCI_NUM_BARS 6
 struct acrn_pcidev {
   __u32 type;
@@ -187,6 +188,29 @@
   __u8 intr_pin;
   __u32 bar[ACRN_PCI_NUM_BARS];
 };
+struct acrn_mmiodev {
+  __u8 name[8];
+  struct {
+    __u64 user_vm_pa;
+    __u64 service_vm_pa;
+    __u64 size;
+    __u64 mem_type;
+  } res[ACRN_MMIODEV_RES_NUM];
+};
+struct acrn_vdev {
+  union {
+    __u64 value;
+    struct {
+      __le16 vendor;
+      __le16 device;
+      __le32 legacy_id;
+    } fields;
+  } id;
+  __u64 slot;
+  __u32 io_addr[ACRN_PCI_NUM_BARS];
+  __u32 io_size[ACRN_PCI_NUM_BARS];
+  __u8 args[128];
+};
 struct acrn_msi_entry {
   __u64 msi_addr;
   __u64 msi_data;
@@ -257,6 +281,10 @@
 #define ACRN_IOCTL_RESET_PTDEV_INTR _IOW(ACRN_IOCTL_TYPE, 0x54, struct acrn_ptdev_irq)
 #define ACRN_IOCTL_ASSIGN_PCIDEV _IOW(ACRN_IOCTL_TYPE, 0x55, struct acrn_pcidev)
 #define ACRN_IOCTL_DEASSIGN_PCIDEV _IOW(ACRN_IOCTL_TYPE, 0x56, struct acrn_pcidev)
+#define ACRN_IOCTL_ASSIGN_MMIODEV _IOW(ACRN_IOCTL_TYPE, 0x57, struct acrn_mmiodev)
+#define ACRN_IOCTL_DEASSIGN_MMIODEV _IOW(ACRN_IOCTL_TYPE, 0x58, struct acrn_mmiodev)
+#define ACRN_IOCTL_CREATE_VDEV _IOW(ACRN_IOCTL_TYPE, 0x59, struct acrn_vdev)
+#define ACRN_IOCTL_DESTROY_VDEV _IOW(ACRN_IOCTL_TYPE, 0x5A, struct acrn_vdev)
 #define ACRN_IOCTL_PM_GET_CPU_STATE _IOWR(ACRN_IOCTL_TYPE, 0x60, __u64)
 #define ACRN_IOCTL_IOEVENTFD _IOW(ACRN_IOCTL_TYPE, 0x70, struct acrn_ioeventfd)
 #define ACRN_IOCTL_IRQFD _IOW(ACRN_IOCTL_TYPE, 0x71, struct acrn_irqfd)
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/amt.h
similarity index 69%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/amt.h
index bb45c3d..049006d 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/amt.h
@@ -16,14 +16,25 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
-#include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
+#ifndef _UAPI_AMT_H_
+#define _UAPI_AMT_H_
+enum ifla_amt_mode {
+  AMT_MODE_GATEWAY = 0,
+  AMT_MODE_RELAY,
+  __AMT_MODE_MAX,
 };
+#define AMT_MODE_MAX (__AMT_MODE_MAX - 1)
+enum {
+  IFLA_AMT_UNSPEC,
+  IFLA_AMT_MODE,
+  IFLA_AMT_RELAY_PORT,
+  IFLA_AMT_GATEWAY_PORT,
+  IFLA_AMT_LINK,
+  IFLA_AMT_LOCAL_IP,
+  IFLA_AMT_REMOTE_IP,
+  IFLA_AMT_DISCOVERY_IP,
+  IFLA_AMT_MAX_TUNNELS,
+  __IFLA_AMT_MAX,
+};
+#define IFLA_AMT_MAX (__IFLA_AMT_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 5416344..ded1756 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -117,6 +117,16 @@
   __u32 reserved2;
   __u32 reserved3;
 };
+struct binder_freeze_info {
+  __u32 pid;
+  __u32 enable;
+  __u32 timeout_ms;
+};
+struct binder_frozen_status_info {
+  __u32 pid;
+  __u32 sync_recv;
+  __u32 async_recv;
+};
 #define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
 #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
 #define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
@@ -127,6 +137,9 @@
 #define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
 #define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
 #define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
+#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
+#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)
+#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32)
 enum transaction_flags {
   TF_ONE_WAY = 0x01,
   TF_ROOT_OBJECT = 0x04,
@@ -199,6 +212,8 @@
   BR_DEAD_BINDER = _IOR('r', 15, binder_uintptr_t),
   BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, binder_uintptr_t),
   BR_FAILED_REPLY = _IO('r', 17),
+  BR_FROZEN_REPLY = _IO('r', 18),
+  BR_ONEWAY_SPAM_SUSPECT = _IO('r', 19),
 };
 enum binder_driver_command_protocol {
   BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 2c18e07..30a94af 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -83,6 +83,10 @@
 #define AUDIT_TIME_ADJNTPVAL 1333
 #define AUDIT_BPF 1334
 #define AUDIT_EVENT_LISTENER 1335
+#define AUDIT_URINGOP 1336
+#define AUDIT_OPENAT2 1337
+#define AUDIT_DM_CTRL 1338
+#define AUDIT_DM_EVENT 1339
 #define AUDIT_AVC 1400
 #define AUDIT_SELINUX_ERR 1401
 #define AUDIT_AVC_PATH 1402
@@ -126,7 +130,8 @@
 #define AUDIT_FILTER_EXCLUDE 0x05
 #define AUDIT_FILTER_TYPE AUDIT_FILTER_EXCLUDE
 #define AUDIT_FILTER_FS 0x06
-#define AUDIT_NR_FILTERS 7
+#define AUDIT_FILTER_URING_EXIT 0x07
+#define AUDIT_NR_FILTERS 8
 #define AUDIT_FILTER_PREPEND 0x10
 #define AUDIT_NEVER 0
 #define AUDIT_POSSIBLE 1
@@ -372,6 +377,6 @@
   __u32 values[AUDIT_MAX_FIELDS];
   __u32 fieldflags[AUDIT_MAX_FIELDS];
   __u32 buflen;
-  char buf[0];
+  char buf[];
 };
 #endif
diff --git a/libc/kernel/uapi/linux/auxvec.h b/libc/kernel/uapi/linux/auxvec.h
index e8c2336..c80c170 100644
--- a/libc/kernel/uapi/linux/auxvec.h
+++ b/libc/kernel/uapi/linux/auxvec.h
@@ -42,4 +42,7 @@
 #define AT_RANDOM 25
 #define AT_HWCAP2 26
 #define AT_EXECFN 31
+#ifndef AT_MINSIGSTKSZ
+#define AT_MINSIGSTKSZ 51
+#endif
 #endif
diff --git a/libc/kernel/uapi/linux/bcache.h b/libc/kernel/uapi/linux/bcache.h
deleted file mode 100644
index 25b6987..0000000
--- a/libc/kernel/uapi/linux/bcache.h
+++ /dev/null
@@ -1,221 +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 _LINUX_BCACHE_H
-#define _LINUX_BCACHE_H
-#include <linux/types.h>
-#define BITMASK(name,type,field,offset,size) static inline __u64 name(const type * k) \
-{ return(k->field >> offset) & ~(~0ULL << size); } static inline void SET_ ##name(type * k, __u64 v) \
-{ k->field &= ~(~(~0ULL << size) << offset); k->field |= (v & ~(~0ULL << size)) << offset; \
-}
-struct bkey {
-  __u64 high;
-  __u64 low;
-  __u64 ptr[];
-};
-#define KEY_FIELD(name,field,offset,size) BITMASK(name, struct bkey, field, offset, size)
-#define PTR_FIELD(name,offset,size) static inline __u64 name(const struct bkey * k, unsigned int i) \
-{ return(k->ptr[i] >> offset) & ~(~0ULL << size); } static inline void SET_ ##name(struct bkey * k, unsigned int i, __u64 v) \
-{ k->ptr[i] &= ~(~(~0ULL << size) << offset); k->ptr[i] |= (v & ~(~0ULL << size)) << offset; \
-}
-#define KEY_SIZE_BITS 16
-#define KEY_MAX_U64S 8
-#define KEY(inode,offset,size) \
-((struct bkey) {.high = (1ULL << 63) | ((__u64) (size) << 20) | (inode),.low = (offset) \
-})
-#define ZERO_KEY KEY(0, 0, 0)
-#define MAX_KEY_INODE (~(~0 << 20))
-#define MAX_KEY_OFFSET (~0ULL >> 1)
-#define MAX_KEY KEY(MAX_KEY_INODE, MAX_KEY_OFFSET, 0)
-#define KEY_START(k) (KEY_OFFSET(k) - KEY_SIZE(k))
-#define START_KEY(k) KEY(KEY_INODE(k), KEY_START(k), 0)
-#define PTR_DEV_BITS 12
-#define PTR_CHECK_DEV ((1 << PTR_DEV_BITS) - 1)
-#define MAKE_PTR(gen,offset,dev) ((((__u64) dev) << 51) | ((__u64) offset) << 8 | gen)
-#define bkey_copy(_dest,_src) memcpy(_dest, _src, bkey_bytes(_src))
-#define BKEY_PAD 8
-#define BKEY_PADDED(key) union { struct bkey key; __u64 key ##_pad[BKEY_PAD]; }
-#define BCACHE_SB_VERSION_CDEV 0
-#define BCACHE_SB_VERSION_BDEV 1
-#define BCACHE_SB_VERSION_CDEV_WITH_UUID 3
-#define BCACHE_SB_VERSION_BDEV_WITH_OFFSET 4
-#define BCACHE_SB_VERSION_CDEV_WITH_FEATURES 5
-#define BCACHE_SB_VERSION_BDEV_WITH_FEATURES 6
-#define BCACHE_SB_MAX_VERSION 6
-#define SB_SECTOR 8
-#define SB_OFFSET (SB_SECTOR << SECTOR_SHIFT)
-#define SB_SIZE 4096
-#define SB_LABEL_SIZE 32
-#define SB_JOURNAL_BUCKETS 256U
-#define MAX_CACHES_PER_SET 8
-#define BDEV_DATA_START_DEFAULT 16
-struct cache_sb_disk {
-  __le64 csum;
-  __le64 offset;
-  __le64 version;
-  __u8 magic[16];
-  __u8 uuid[16];
-  union {
-    __u8 set_uuid[16];
-    __le64 set_magic;
-  };
-  __u8 label[SB_LABEL_SIZE];
-  __le64 flags;
-  __le64 seq;
-  __le64 feature_compat;
-  __le64 feature_incompat;
-  __le64 feature_ro_compat;
-  __le64 pad[5];
-  union {
-    struct {
-      __le64 nbuckets;
-      __le16 block_size;
-      __le16 bucket_size;
-      __le16 nr_in_set;
-      __le16 nr_this_dev;
-    };
-    struct {
-      __le64 data_offset;
-    };
-  };
-  __le32 last_mount;
-  __le16 first_bucket;
-  union {
-    __le16 njournal_buckets;
-    __le16 keys;
-  };
-  __le64 d[SB_JOURNAL_BUCKETS];
-  __le16 obso_bucket_size_hi;
-};
-struct cache_sb {
-  __u64 offset;
-  __u64 version;
-  __u8 magic[16];
-  __u8 uuid[16];
-  union {
-    __u8 set_uuid[16];
-    __u64 set_magic;
-  };
-  __u8 label[SB_LABEL_SIZE];
-  __u64 flags;
-  __u64 seq;
-  __u64 feature_compat;
-  __u64 feature_incompat;
-  __u64 feature_ro_compat;
-  union {
-    struct {
-      __u64 nbuckets;
-      __u16 block_size;
-      __u16 nr_in_set;
-      __u16 nr_this_dev;
-      __u32 bucket_size;
-    };
-    struct {
-      __u64 data_offset;
-    };
-  };
-  __u32 last_mount;
-  __u16 first_bucket;
-  union {
-    __u16 njournal_buckets;
-    __u16 keys;
-  };
-  __u64 d[SB_JOURNAL_BUCKETS];
-};
-#define CACHE_REPLACEMENT_LRU 0U
-#define CACHE_REPLACEMENT_FIFO 1U
-#define CACHE_REPLACEMENT_RANDOM 2U
-#define CACHE_MODE_WRITETHROUGH 0U
-#define CACHE_MODE_WRITEBACK 1U
-#define CACHE_MODE_WRITEAROUND 2U
-#define CACHE_MODE_NONE 3U
-#define BDEV_STATE_NONE 0U
-#define BDEV_STATE_CLEAN 1U
-#define BDEV_STATE_DIRTY 2U
-#define BDEV_STATE_STALE 3U
-#define JSET_MAGIC 0x245235c1a3625032ULL
-#define PSET_MAGIC 0x6750e15f87337f91ULL
-#define BSET_MAGIC 0x90135c78b99e07f5ULL
-#define BCACHE_JSET_VERSION_UUIDv1 1
-#define BCACHE_JSET_VERSION_UUID 1
-#define BCACHE_JSET_VERSION 1
-struct jset {
-  __u64 csum;
-  __u64 magic;
-  __u64 seq;
-  __u32 version;
-  __u32 keys;
-  __u64 last_seq;
-  BKEY_PADDED(uuid_bucket);
-  BKEY_PADDED(btree_root);
-  __u16 btree_level;
-  __u16 pad[3];
-  __u64 prio_bucket[MAX_CACHES_PER_SET];
-  union {
-    struct bkey start[0];
-    __u64 d[0];
-  };
-};
-struct prio_set {
-  __u64 csum;
-  __u64 magic;
-  __u64 seq;
-  __u32 version;
-  __u32 pad;
-  __u64 next_bucket;
-  struct bucket_disk {
-    __u16 prio;
-    __u8 gen;
-  } __attribute((packed)) data[];
-};
-struct uuid_entry {
-  union {
-    struct {
-      __u8 uuid[16];
-      __u8 label[32];
-      __u32 first_reg;
-      __u32 last_reg;
-      __u32 invalidated;
-      __u32 flags;
-      __u64 sectors;
-    };
-    __u8 pad[128];
-  };
-};
-#define BCACHE_BSET_CSUM 1
-#define BCACHE_BSET_VERSION 1
-struct bset {
-  __u64 csum;
-  __u64 magic;
-  __u64 seq;
-  __u32 version;
-  __u32 keys;
-  union {
-    struct bkey start[0];
-    __u64 d[0];
-  };
-};
-struct uuid_entry_v0 {
-  __u8 uuid[16];
-  __u8 label[32];
-  __u32 first_reg;
-  __u32 last_reg;
-  __u32 invalidated;
-  __u32 pad;
-};
-#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index c643ffa..d363e81 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -91,6 +91,7 @@
   BPF_PROG_ATTACH,
   BPF_PROG_DETACH,
   BPF_PROG_TEST_RUN,
+  BPF_PROG_RUN = BPF_PROG_TEST_RUN,
   BPF_PROG_GET_NEXT_ID,
   BPF_MAP_GET_NEXT_ID,
   BPF_PROG_GET_FD_BY_ID,
@@ -148,6 +149,7 @@
   BPF_MAP_TYPE_RINGBUF,
   BPF_MAP_TYPE_INODE_STORAGE,
   BPF_MAP_TYPE_TASK_STORAGE,
+  BPF_MAP_TYPE_BLOOM_FILTER,
 };
 enum bpf_prog_type {
   BPF_PROG_TYPE_UNSPEC,
@@ -181,6 +183,7 @@
   BPF_PROG_TYPE_EXT,
   BPF_PROG_TYPE_LSM,
   BPF_PROG_TYPE_SK_LOOKUP,
+  BPF_PROG_TYPE_SYSCALL,
 };
 enum bpf_attach_type {
   BPF_CGROUP_INET_INGRESS,
@@ -221,6 +224,10 @@
   BPF_XDP_CPUMAP,
   BPF_SK_LOOKUP,
   BPF_XDP,
+  BPF_SK_SKB_VERDICT,
+  BPF_SK_REUSEPORT_SELECT,
+  BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
+  BPF_PERF_EVENT,
   __MAX_BPF_ATTACH_TYPE
 };
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -232,6 +239,7 @@
   BPF_LINK_TYPE_ITER = 4,
   BPF_LINK_TYPE_NETNS = 5,
   BPF_LINK_TYPE_XDP = 6,
+  BPF_LINK_TYPE_PERF_EVENT = 7,
   MAX_BPF_LINK_TYPE,
 };
 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
@@ -243,9 +251,13 @@
 #define BPF_F_TEST_STATE_FREQ (1U << 3)
 #define BPF_F_SLEEPABLE (1U << 4)
 #define BPF_PSEUDO_MAP_FD 1
+#define BPF_PSEUDO_MAP_IDX 5
 #define BPF_PSEUDO_MAP_VALUE 2
+#define BPF_PSEUDO_MAP_IDX_VALUE 6
 #define BPF_PSEUDO_BTF_ID 3
+#define BPF_PSEUDO_FUNC 4
 #define BPF_PSEUDO_CALL 1
+#define BPF_PSEUDO_KFUNC_CALL 2
 enum {
   BPF_ANY = 0,
   BPF_NOEXIST = 1,
@@ -302,6 +314,7 @@
     __u32 btf_key_type_id;
     __u32 btf_value_type_id;
     __u32 btf_vmlinux_value_type_id;
+    __u64 map_extra;
   };
   struct {
     __u32 map_fd;
@@ -347,6 +360,10 @@
       __u32 attach_prog_fd;
       __u32 attach_btf_obj_fd;
     };
+    __u32 core_relo_cnt;
+    __aligned_u64 fd_array;
+    __aligned_u64 core_relos;
+    __u32 core_relo_rec_size;
   };
   struct {
     __aligned_u64 pathname;
@@ -436,6 +453,9 @@
         __aligned_u64 iter_info;
         __u32 iter_info_len;
       };
+      struct {
+        __u64 bpf_cookie;
+      } perf_event;
     };
   } link_create;
   struct {
@@ -460,7 +480,7 @@
     __u32 flags;
   } prog_bind_map;
 } __attribute__((aligned(8)));
-#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data), FN(msg_pop_data), FN(rc_pointer_rel), FN(spin_lock), FN(spin_unlock), FN(sk_fullsock), FN(tcp_sock), FN(skb_ecn_set_ce), FN(get_listener_sock), FN(skc_lookup_tcp), FN(tcp_check_syncookie), FN(sysctl_get_name), FN(sysctl_get_current_value), FN(sysctl_get_new_value), FN(sysctl_set_new_value), FN(strtol), FN(strtoul), FN(sk_storage_get), FN(sk_storage_delete), FN(send_signal), FN(tcp_gen_syncookie), FN(skb_output), FN(probe_read_user), FN(probe_read_kernel), FN(probe_read_user_str), FN(probe_read_kernel_str), FN(tcp_send_ack), FN(send_signal_thread), FN(jiffies64), FN(read_branch_records), FN(get_ns_current_pid_tgid), FN(xdp_output), FN(get_netns_cookie), FN(get_current_ancestor_cgroup_id), FN(sk_assign), FN(ktime_get_boot_ns), FN(seq_printf), FN(seq_write), FN(sk_cgroup_id), FN(sk_ancestor_cgroup_id), FN(ringbuf_output), FN(ringbuf_reserve), FN(ringbuf_submit), FN(ringbuf_discard), FN(ringbuf_query), FN(csum_level), FN(skc_to_tcp6_sock), FN(skc_to_tcp_sock), FN(skc_to_tcp_timewait_sock), FN(skc_to_tcp_request_sock), FN(skc_to_udp6_sock), FN(get_task_stack), FN(load_hdr_opt), FN(store_hdr_opt), FN(reserve_hdr_opt), FN(inode_storage_get), FN(inode_storage_delete), FN(d_path), FN(copy_from_user), FN(snprintf_btf), FN(seq_printf_btf), FN(skb_cgroup_classid), FN(redirect_neigh), FN(per_cpu_ptr), FN(this_cpu_ptr), FN(redirect_peer), FN(task_storage_get), FN(task_storage_delete), FN(get_current_task_btf), FN(bprm_opts_set), FN(ktime_get_coarse_ns), FN(ima_inode_hash), FN(sock_from_file), FN(check_mtu),
+#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update), FN(xdp_adjust_meta), FN(perf_event_read_value), FN(perf_prog_read_value), FN(getsockopt), FN(override_return), FN(sock_ops_cb_flags_set), FN(msg_redirect_map), FN(msg_apply_bytes), FN(msg_cork_bytes), FN(msg_pull_data), FN(bind), FN(xdp_adjust_tail), FN(skb_get_xfrm_state), FN(get_stack), FN(skb_load_bytes_relative), FN(fib_lookup), FN(sock_hash_update), FN(msg_redirect_hash), FN(sk_redirect_hash), FN(lwt_push_encap), FN(lwt_seg6_store_bytes), FN(lwt_seg6_adjust_srh), FN(lwt_seg6_action), FN(rc_repeat), FN(rc_keydown), FN(skb_cgroup_id), FN(get_current_cgroup_id), FN(get_local_storage), FN(sk_select_reuseport), FN(skb_ancestor_cgroup_id), FN(sk_lookup_tcp), FN(sk_lookup_udp), FN(sk_release), FN(map_push_elem), FN(map_pop_elem), FN(map_peek_elem), FN(msg_push_data), FN(msg_pop_data), FN(rc_pointer_rel), FN(spin_lock), FN(spin_unlock), FN(sk_fullsock), FN(tcp_sock), FN(skb_ecn_set_ce), FN(get_listener_sock), FN(skc_lookup_tcp), FN(tcp_check_syncookie), FN(sysctl_get_name), FN(sysctl_get_current_value), FN(sysctl_get_new_value), FN(sysctl_set_new_value), FN(strtol), FN(strtoul), FN(sk_storage_get), FN(sk_storage_delete), FN(send_signal), FN(tcp_gen_syncookie), FN(skb_output), FN(probe_read_user), FN(probe_read_kernel), FN(probe_read_user_str), FN(probe_read_kernel_str), FN(tcp_send_ack), FN(send_signal_thread), FN(jiffies64), FN(read_branch_records), FN(get_ns_current_pid_tgid), FN(xdp_output), FN(get_netns_cookie), FN(get_current_ancestor_cgroup_id), FN(sk_assign), FN(ktime_get_boot_ns), FN(seq_printf), FN(seq_write), FN(sk_cgroup_id), FN(sk_ancestor_cgroup_id), FN(ringbuf_output), FN(ringbuf_reserve), FN(ringbuf_submit), FN(ringbuf_discard), FN(ringbuf_query), FN(csum_level), FN(skc_to_tcp6_sock), FN(skc_to_tcp_sock), FN(skc_to_tcp_timewait_sock), FN(skc_to_tcp_request_sock), FN(skc_to_udp6_sock), FN(get_task_stack), FN(load_hdr_opt), FN(store_hdr_opt), FN(reserve_hdr_opt), FN(inode_storage_get), FN(inode_storage_delete), FN(d_path), FN(copy_from_user), FN(snprintf_btf), FN(seq_printf_btf), FN(skb_cgroup_classid), FN(redirect_neigh), FN(per_cpu_ptr), FN(this_cpu_ptr), FN(redirect_peer), FN(task_storage_get), FN(task_storage_delete), FN(get_current_task_btf), FN(bprm_opts_set), FN(ktime_get_coarse_ns), FN(ima_inode_hash), FN(sock_from_file), FN(check_mtu), FN(for_each_map_elem), FN(snprintf), FN(sys_bpf), FN(btf_find_by_name_kind), FN(sys_close), FN(timer_init), FN(timer_set_callback), FN(timer_start), FN(timer_cancel), FN(get_func_ip), FN(get_attach_cookie), FN(task_pt_regs), FN(get_branch_snapshot), FN(trace_vprintk), FN(skc_to_unix_sock), FN(kallsyms_lookup_name), FN(find_vma), FN(loop), FN(strncmp), FN(get_func_arg), FN(get_func_ret), FN(get_func_arg_cnt),
 #define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
 enum bpf_func_id {
   __BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -517,6 +537,7 @@
   BPF_F_ADJ_ROOM_ENCAP_L4_GRE = (1ULL << 3),
   BPF_F_ADJ_ROOM_ENCAP_L4_UDP = (1ULL << 4),
   BPF_F_ADJ_ROOM_NO_CSUM_RESET = (1ULL << 5),
+  BPF_F_ADJ_ROOM_ENCAP_L2_ETH = (1ULL << 6),
 };
 enum {
   BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff,
@@ -568,6 +589,10 @@
 enum {
   BPF_F_BPRM_SECUREEXEC = (1ULL << 0),
 };
+enum {
+  BPF_F_BROADCAST = (1ULL << 3),
+  BPF_F_EXCLUDE_INGRESS = (1ULL << 4),
+};
 #define __bpf_md_ptr(type,name) union { type name; __u64 : 64; \
 } __attribute__((aligned(8)))
 struct __sk_buff {
@@ -603,6 +628,8 @@
   __u32 gso_segs;
   __bpf_md_ptr(struct bpf_sock *, sk);
   __u32 gso_size;
+  __u32 : 32;
+  __u64 hwtstamp;
 };
 struct bpf_tunnel_key {
   __u32 tunnel_id;
@@ -749,6 +776,8 @@
   __u32 ip_protocol;
   __u32 bind_inany;
   __u32 hash;
+  __bpf_md_ptr(struct bpf_sock *, sk);
+  __bpf_md_ptr(struct bpf_sock *, migrating_sk);
 };
 #define BPF_TAG_SIZE 8
 struct bpf_prog_info {
@@ -788,6 +817,7 @@
   __u64 run_time_ns;
   __u64 run_cnt;
   __u64 recursion_misses;
+  __u32 verified_insns;
 } __attribute__((aligned(8)));
 struct bpf_map_info {
   __u32 type;
@@ -804,6 +834,8 @@
   __u32 btf_id;
   __u32 btf_key_type_id;
   __u32 btf_value_type_id;
+  __u32 : 32;
+  __u64 map_extra;
 } __attribute__((aligned(8)));
 struct bpf_btf_info {
   __aligned_u64 btf;
@@ -824,6 +856,8 @@
     } raw_tracepoint;
     struct {
       __u32 attach_type;
+      __u32 target_obj_id;
+      __u32 target_btf_id;
     } tracing;
     struct {
       __u64 cgroup_id;
@@ -1096,6 +1130,10 @@
 struct bpf_spin_lock {
   __u32 val;
 };
+struct bpf_timer {
+  __u64 : 64;
+  __u64 : 64;
+} __attribute__((aligned(8)));
 struct bpf_sysctl {
   __u32 write;
   __u32 file_pos;
@@ -1114,7 +1152,10 @@
   __u32 tgid;
 };
 struct bpf_sk_lookup {
-  __bpf_md_ptr(struct bpf_sock *, sk);
+  union {
+    __bpf_md_ptr(struct bpf_sock *, sk);
+    __u64 cookie;
+  };
   __u32 family;
   __u32 protocol;
   __u32 remote_ip4;
@@ -1123,6 +1164,7 @@
   __u32 local_ip4;
   __u32 local_ip6[4];
   __u32 local_port;
+  __u32 ingress_ifindex;
 };
 struct btf_ptr {
   void * ptr;
@@ -1135,4 +1177,24 @@
   BTF_F_PTR_RAW = (1ULL << 2),
   BTF_F_ZERO = (1ULL << 3),
 };
+enum bpf_core_relo_kind {
+  BPF_CORE_FIELD_BYTE_OFFSET = 0,
+  BPF_CORE_FIELD_BYTE_SIZE = 1,
+  BPF_CORE_FIELD_EXISTS = 2,
+  BPF_CORE_FIELD_SIGNED = 3,
+  BPF_CORE_FIELD_LSHIFT_U64 = 4,
+  BPF_CORE_FIELD_RSHIFT_U64 = 5,
+  BPF_CORE_TYPE_ID_LOCAL = 6,
+  BPF_CORE_TYPE_ID_TARGET = 7,
+  BPF_CORE_TYPE_EXISTS = 8,
+  BPF_CORE_TYPE_SIZE = 9,
+  BPF_CORE_ENUMVAL_EXISTS = 10,
+  BPF_CORE_ENUMVAL_VALUE = 11,
+};
+struct bpf_core_relo {
+  __u32 insn_off;
+  __u32 type_id;
+  __u32 access_str_off;
+  enum bpf_core_relo_kind kind;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/btf.h b/libc/kernel/uapi/linux/btf.h
index f22d637..fc57d3c 100644
--- a/libc/kernel/uapi/linux/btf.h
+++ b/libc/kernel/uapi/linux/btf.h
@@ -42,27 +42,32 @@
     __u32 type;
   };
 };
-#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
+#define BTF_INFO_KIND(info) (((info) >> 24) & 0x1f)
 #define BTF_INFO_VLEN(info) ((info) & 0xffff)
 #define BTF_INFO_KFLAG(info) ((info) >> 31)
-#define BTF_KIND_UNKN 0
-#define BTF_KIND_INT 1
-#define BTF_KIND_PTR 2
-#define BTF_KIND_ARRAY 3
-#define BTF_KIND_STRUCT 4
-#define BTF_KIND_UNION 5
-#define BTF_KIND_ENUM 6
-#define BTF_KIND_FWD 7
-#define BTF_KIND_TYPEDEF 8
-#define BTF_KIND_VOLATILE 9
-#define BTF_KIND_CONST 10
-#define BTF_KIND_RESTRICT 11
-#define BTF_KIND_FUNC 12
-#define BTF_KIND_FUNC_PROTO 13
-#define BTF_KIND_VAR 14
-#define BTF_KIND_DATASEC 15
-#define BTF_KIND_MAX BTF_KIND_DATASEC
-#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
+enum {
+  BTF_KIND_UNKN = 0,
+  BTF_KIND_INT = 1,
+  BTF_KIND_PTR = 2,
+  BTF_KIND_ARRAY = 3,
+  BTF_KIND_STRUCT = 4,
+  BTF_KIND_UNION = 5,
+  BTF_KIND_ENUM = 6,
+  BTF_KIND_FWD = 7,
+  BTF_KIND_TYPEDEF = 8,
+  BTF_KIND_VOLATILE = 9,
+  BTF_KIND_CONST = 10,
+  BTF_KIND_RESTRICT = 11,
+  BTF_KIND_FUNC = 12,
+  BTF_KIND_FUNC_PROTO = 13,
+  BTF_KIND_VAR = 14,
+  BTF_KIND_DATASEC = 15,
+  BTF_KIND_FLOAT = 16,
+  BTF_KIND_DECL_TAG = 17,
+  BTF_KIND_TYPE_TAG = 18,
+  NR_BTF_KINDS,
+  BTF_KIND_MAX = NR_BTF_KINDS - 1,
+};
 #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
 #define BTF_INT_OFFSET(VAL) (((VAL) & 0x00ff0000) >> 16)
 #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)
@@ -107,4 +112,7 @@
   __u32 offset;
   __u32 size;
 };
+struct btf_decl_tag {
+  __s32 component_idx;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index c0a586c..08b96a3 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -175,6 +175,7 @@
 };
 #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0)
 #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1)
+#define BTRFS_FEATURE_COMPAT_RO_VERITY (1ULL << 2)
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
 #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
@@ -419,14 +420,16 @@
 #define BTRFS_SEND_FLAG_NO_FILE_DATA 0x1
 #define BTRFS_SEND_FLAG_OMIT_STREAM_HEADER 0x2
 #define BTRFS_SEND_FLAG_OMIT_END_CMD 0x4
-#define BTRFS_SEND_FLAG_MASK (BTRFS_SEND_FLAG_NO_FILE_DATA | BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | BTRFS_SEND_FLAG_OMIT_END_CMD)
+#define BTRFS_SEND_FLAG_VERSION 0x8
+#define BTRFS_SEND_FLAG_MASK (BTRFS_SEND_FLAG_NO_FILE_DATA | BTRFS_SEND_FLAG_OMIT_STREAM_HEADER | BTRFS_SEND_FLAG_OMIT_END_CMD | BTRFS_SEND_FLAG_VERSION)
 struct btrfs_ioctl_send_args {
   __s64 send_fd;
   __u64 clone_sources_count;
   __u64 __user * clone_sources;
   __u64 parent_root;
   __u64 flags;
-  __u64 reserved[4];
+  __u32 version;
+  __u8 reserved[28];
 };
 struct btrfs_ioctl_get_subvol_info_args {
   __u64 treeid;
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index 4e36c37..0476733 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -53,6 +53,8 @@
 #define BTRFS_INODE_REF_KEY 12
 #define BTRFS_INODE_EXTREF_KEY 13
 #define BTRFS_XATTR_ITEM_KEY 24
+#define BTRFS_VERITY_DESC_ITEM_KEY 36
+#define BTRFS_VERITY_MERKLE_ITEM_KEY 37
 #define BTRFS_ORPHAN_ITEM_KEY 48
 #define BTRFS_DIR_LOG_ITEM_KEY 60
 #define BTRFS_DIR_LOG_INDEX_KEY 72
@@ -424,4 +426,9 @@
   __le64 rsv_rfer;
   __le64 rsv_excl;
 } __attribute__((__packed__));
+struct btrfs_verity_descriptor_item {
+  __le64 size;
+  __le64 reserved[2];
+  __u8 encryption;
+} __attribute__((__packed__));
 #endif
diff --git a/libc/kernel/uapi/linux/byteorder/big_endian.h b/libc/kernel/uapi/linux/byteorder/big_endian.h
index c0ddccc..b6c978b 100644
--- a/libc/kernel/uapi/linux/byteorder/big_endian.h
+++ b/libc/kernel/uapi/linux/byteorder/big_endian.h
@@ -24,6 +24,7 @@
 #ifndef __BIG_ENDIAN_BITFIELD
 #define __BIG_ENDIAN_BITFIELD
 #endif
+#include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/swab.h>
 #define __constant_htonl(x) ((__force __be32) (__u32) (x))
diff --git a/libc/kernel/uapi/linux/byteorder/little_endian.h b/libc/kernel/uapi/linux/byteorder/little_endian.h
index ea00092..a272d4d 100644
--- a/libc/kernel/uapi/linux/byteorder/little_endian.h
+++ b/libc/kernel/uapi/linux/byteorder/little_endian.h
@@ -24,6 +24,7 @@
 #ifndef __LITTLE_ENDIAN_BITFIELD
 #define __LITTLE_ENDIAN_BITFIELD
 #endif
+#include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/swab.h>
 #define __constant_htonl(x) ((__force __be32) ___constant_swab32((x)))
diff --git a/libc/kernel/uapi/linux/can.h b/libc/kernel/uapi/linux/can.h
index 59fc31e..30eeca2 100644
--- a/libc/kernel/uapi/linux/can.h
+++ b/libc/kernel/uapi/linux/can.h
@@ -48,6 +48,7 @@
 };
 #define CANFD_BRS 0x01
 #define CANFD_ESI 0x02
+#define CANFD_FDF 0x04
 struct canfd_frame {
   canid_t can_id;
   __u8 len;
diff --git a/libc/kernel/uapi/linux/can/j1939.h b/libc/kernel/uapi/linux/can/j1939.h
index 531a222..42dbf15 100644
--- a/libc/kernel/uapi/linux/can/j1939.h
+++ b/libc/kernel/uapi/linux/can/j1939.h
@@ -50,10 +50,19 @@
 enum {
   J1939_NLA_PAD,
   J1939_NLA_BYTES_ACKED,
+  J1939_NLA_TOTAL_SIZE,
+  J1939_NLA_PGN,
+  J1939_NLA_SRC_NAME,
+  J1939_NLA_DEST_NAME,
+  J1939_NLA_SRC_ADDR,
+  J1939_NLA_DEST_ADDR,
 };
 enum {
   J1939_EE_INFO_NONE,
   J1939_EE_INFO_TX_ABORT,
+  J1939_EE_INFO_RX_RTS,
+  J1939_EE_INFO_RX_DPO,
+  J1939_EE_INFO_RX_ABORT,
 };
 struct j1939_filter {
   name_t name;
diff --git a/libc/kernel/uapi/linux/can/netlink.h b/libc/kernel/uapi/linux/can/netlink.h
index 3e6551d..f4086c0 100644
--- a/libc/kernel/uapi/linux/can/netlink.h
+++ b/libc/kernel/uapi/linux/can/netlink.h
@@ -69,6 +69,8 @@
 #define CAN_CTRLMODE_PRESUME_ACK 0x40
 #define CAN_CTRLMODE_FD_NON_ISO 0x80
 #define CAN_CTRLMODE_CC_LEN8_DLC 0x100
+#define CAN_CTRLMODE_TDC_AUTO 0x200
+#define CAN_CTRLMODE_TDC_MANUAL 0x400
 struct can_device_stats {
   __u32 bus_error;
   __u32 error_warning;
@@ -94,8 +96,30 @@
   IFLA_CAN_BITRATE_CONST,
   IFLA_CAN_DATA_BITRATE_CONST,
   IFLA_CAN_BITRATE_MAX,
-  __IFLA_CAN_MAX
+  IFLA_CAN_TDC,
+  IFLA_CAN_CTRLMODE_EXT,
+  __IFLA_CAN_MAX,
+  IFLA_CAN_MAX = __IFLA_CAN_MAX - 1
 };
-#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
+enum {
+  IFLA_CAN_TDC_UNSPEC,
+  IFLA_CAN_TDC_TDCV_MIN,
+  IFLA_CAN_TDC_TDCV_MAX,
+  IFLA_CAN_TDC_TDCO_MIN,
+  IFLA_CAN_TDC_TDCO_MAX,
+  IFLA_CAN_TDC_TDCF_MIN,
+  IFLA_CAN_TDC_TDCF_MAX,
+  IFLA_CAN_TDC_TDCV,
+  IFLA_CAN_TDC_TDCO,
+  IFLA_CAN_TDC_TDCF,
+  __IFLA_CAN_TDC,
+  IFLA_CAN_TDC_MAX = __IFLA_CAN_TDC - 1
+};
+enum {
+  IFLA_CAN_CTRLMODE_UNSPEC,
+  IFLA_CAN_CTRLMODE_SUPPORTED,
+  __IFLA_CAN_CTRLMODE,
+  IFLA_CAN_CTRLMODE_MAX = __IFLA_CAN_CTRLMODE - 1
+};
 #define CAN_TERMINATION_DISABLED 0
 #endif
diff --git a/libc/kernel/uapi/linux/cdrom.h b/libc/kernel/uapi/linux/cdrom.h
index 8f1c2f0..0fe0727 100644
--- a/libc/kernel/uapi/linux/cdrom.h
+++ b/libc/kernel/uapi/linux/cdrom.h
@@ -67,6 +67,7 @@
 #define CDROM_SEND_PACKET 0x5393
 #define CDROM_NEXT_WRITABLE 0x5394
 #define CDROM_LAST_WRITTEN 0x5395
+#define CDROM_TIMED_MEDIA_CHANGE 0x5396
 struct cdrom_msf0 {
   __u8 minute;
   __u8 second;
@@ -160,6 +161,11 @@
     void __user * unused;
   };
 };
+struct cdrom_timed_media_change_info {
+  __s64 last_media_change;
+  __u64 media_flags;
+};
+#define MEDIA_CHANGED_FLAG 0x1
 #define CD_MINS 74
 #define CD_SECS 60
 #define CD_FRAMES 75
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 238fa0a..b90dc49 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -262,7 +262,7 @@
 #define CEC_OP_REC_SEQ_WEDNESDAY 0x08
 #define CEC_OP_REC_SEQ_THURSDAY 0x10
 #define CEC_OP_REC_SEQ_FRIDAY 0x20
-#define CEC_OP_REC_SEQ_SATERDAY 0x40
+#define CEC_OP_REC_SEQ_SATURDAY 0x40
 #define CEC_OP_REC_SEQ_ONCE_ONLY 0x00
 #define CEC_MSG_CLEAR_DIGITAL_TIMER 0x99
 #define CEC_MSG_CLEAR_EXT_TIMER 0xa1
diff --git a/libc/kernel/uapi/linux/comedi.h b/libc/kernel/uapi/linux/comedi.h
new file mode 100644
index 0000000..e0d015a
--- /dev/null
+++ b/libc/kernel/uapi/linux/comedi.h
@@ -0,0 +1,669 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _COMEDI_H
+#define _COMEDI_H
+#define COMEDI_MAJORVERSION 0
+#define COMEDI_MINORVERSION 7
+#define COMEDI_MICROVERSION 76
+#define VERSION "0.7.76"
+#define COMEDI_MAJOR 98
+#define COMEDI_NDEVICES 16
+#define COMEDI_NDEVCONFOPTS 32
+#define COMEDI_DEVCONF_AUX_DATA3_LENGTH 25
+#define COMEDI_DEVCONF_AUX_DATA2_LENGTH 26
+#define COMEDI_DEVCONF_AUX_DATA1_LENGTH 27
+#define COMEDI_DEVCONF_AUX_DATA0_LENGTH 28
+#define COMEDI_DEVCONF_AUX_DATA_HI 29
+#define COMEDI_DEVCONF_AUX_DATA_LO 30
+#define COMEDI_DEVCONF_AUX_DATA_LENGTH 31
+#define COMEDI_NAMELEN 20
+#define CR_PACK(chan,rng,aref) ((((aref) & 0x3) << 24) | (((rng) & 0xff) << 16) | (chan))
+#define CR_PACK_FLAGS(chan,range,aref,flags) (CR_PACK(chan, range, aref) | ((flags) & CR_FLAGS_MASK))
+#define CR_CHAN(a) ((a) & 0xffff)
+#define CR_RANGE(a) (((a) >> 16) & 0xff)
+#define CR_AREF(a) (((a) >> 24) & 0x03)
+#define CR_FLAGS_MASK 0xfc000000
+#define CR_ALT_FILTER 0x04000000
+#define CR_DITHER CR_ALT_FILTER
+#define CR_DEGLITCH CR_ALT_FILTER
+#define CR_ALT_SOURCE 0x08000000
+#define CR_EDGE 0x40000000
+#define CR_INVERT 0x80000000
+#define AREF_GROUND 0x00
+#define AREF_COMMON 0x01
+#define AREF_DIFF 0x02
+#define AREF_OTHER 0x03
+#define GPCT_RESET 0x0001
+#define GPCT_SET_SOURCE 0x0002
+#define GPCT_SET_GATE 0x0004
+#define GPCT_SET_DIRECTION 0x0008
+#define GPCT_SET_OPERATION 0x0010
+#define GPCT_ARM 0x0020
+#define GPCT_DISARM 0x0040
+#define GPCT_GET_INT_CLK_FRQ 0x0080
+#define GPCT_INT_CLOCK 0x0001
+#define GPCT_EXT_PIN 0x0002
+#define GPCT_NO_GATE 0x0004
+#define GPCT_UP 0x0008
+#define GPCT_DOWN 0x0010
+#define GPCT_HWUD 0x0020
+#define GPCT_SIMPLE_EVENT 0x0040
+#define GPCT_SINGLE_PERIOD 0x0080
+#define GPCT_SINGLE_PW 0x0100
+#define GPCT_CONT_PULSE_OUT 0x0200
+#define GPCT_SINGLE_PULSE_OUT 0x0400
+#define INSN_MASK_WRITE 0x8000000
+#define INSN_MASK_READ 0x4000000
+#define INSN_MASK_SPECIAL 0x2000000
+#define INSN_READ (0 | INSN_MASK_READ)
+#define INSN_WRITE (1 | INSN_MASK_WRITE)
+#define INSN_BITS (2 | INSN_MASK_READ | INSN_MASK_WRITE)
+#define INSN_CONFIG (3 | INSN_MASK_READ | INSN_MASK_WRITE)
+#define INSN_DEVICE_CONFIG (INSN_CONFIG | INSN_MASK_SPECIAL)
+#define INSN_GTOD (4 | INSN_MASK_READ | INSN_MASK_SPECIAL)
+#define INSN_WAIT (5 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
+#define INSN_INTTRIG (6 | INSN_MASK_WRITE | INSN_MASK_SPECIAL)
+#define CMDF_BOGUS 0x00000001
+#define CMDF_PRIORITY 0x00000008
+#define CMDF_WAKE_EOS 0x00000020
+#define CMDF_WRITE 0x00000040
+#define CMDF_RAWDATA 0x00000080
+#define CMDF_ROUND_MASK 0x00030000
+#define CMDF_ROUND_NEAREST 0x00000000
+#define CMDF_ROUND_DOWN 0x00010000
+#define CMDF_ROUND_UP 0x00020000
+#define CMDF_ROUND_UP_NEXT 0x00030000
+#define COMEDI_EV_START 0x00040000
+#define COMEDI_EV_SCAN_BEGIN 0x00080000
+#define COMEDI_EV_CONVERT 0x00100000
+#define COMEDI_EV_SCAN_END 0x00200000
+#define COMEDI_EV_STOP 0x00400000
+#define TRIG_BOGUS CMDF_BOGUS
+#define TRIG_RT CMDF_PRIORITY
+#define TRIG_WAKE_EOS CMDF_WAKE_EOS
+#define TRIG_WRITE CMDF_WRITE
+#define TRIG_ROUND_MASK CMDF_ROUND_MASK
+#define TRIG_ROUND_NEAREST CMDF_ROUND_NEAREST
+#define TRIG_ROUND_DOWN CMDF_ROUND_DOWN
+#define TRIG_ROUND_UP CMDF_ROUND_UP
+#define TRIG_ROUND_UP_NEXT CMDF_ROUND_UP_NEXT
+#define TRIG_ANY 0xffffffff
+#define TRIG_INVALID 0x00000000
+#define TRIG_NONE 0x00000001
+#define TRIG_NOW 0x00000002
+#define TRIG_FOLLOW 0x00000004
+#define TRIG_TIME 0x00000008
+#define TRIG_TIMER 0x00000010
+#define TRIG_COUNT 0x00000020
+#define TRIG_EXT 0x00000040
+#define TRIG_INT 0x00000080
+#define TRIG_OTHER 0x00000100
+#define SDF_BUSY 0x0001
+#define SDF_BUSY_OWNER 0x0002
+#define SDF_LOCKED 0x0004
+#define SDF_LOCK_OWNER 0x0008
+#define SDF_MAXDATA 0x0010
+#define SDF_FLAGS 0x0020
+#define SDF_RANGETYPE 0x0040
+#define SDF_PWM_COUNTER 0x0080
+#define SDF_PWM_HBRIDGE 0x0100
+#define SDF_CMD 0x1000
+#define SDF_SOFT_CALIBRATED 0x2000
+#define SDF_CMD_WRITE 0x4000
+#define SDF_CMD_READ 0x8000
+#define SDF_READABLE 0x00010000
+#define SDF_WRITABLE 0x00020000
+#define SDF_WRITEABLE SDF_WRITABLE
+#define SDF_INTERNAL 0x00040000
+#define SDF_GROUND 0x00100000
+#define SDF_COMMON 0x00200000
+#define SDF_DIFF 0x00400000
+#define SDF_OTHER 0x00800000
+#define SDF_DITHER 0x01000000
+#define SDF_DEGLITCH 0x02000000
+#define SDF_MMAP 0x04000000
+#define SDF_RUNNING 0x08000000
+#define SDF_LSAMPL 0x10000000
+#define SDF_PACKED 0x20000000
+enum comedi_subdevice_type {
+  COMEDI_SUBD_UNUSED,
+  COMEDI_SUBD_AI,
+  COMEDI_SUBD_AO,
+  COMEDI_SUBD_DI,
+  COMEDI_SUBD_DO,
+  COMEDI_SUBD_DIO,
+  COMEDI_SUBD_COUNTER,
+  COMEDI_SUBD_TIMER,
+  COMEDI_SUBD_MEMORY,
+  COMEDI_SUBD_CALIB,
+  COMEDI_SUBD_PROC,
+  COMEDI_SUBD_SERIAL,
+  COMEDI_SUBD_PWM
+};
+enum comedi_io_direction {
+  COMEDI_INPUT = 0,
+  COMEDI_OUTPUT = 1,
+  COMEDI_OPENDRAIN = 2
+};
+enum configuration_ids {
+  INSN_CONFIG_DIO_INPUT = COMEDI_INPUT,
+  INSN_CONFIG_DIO_OUTPUT = COMEDI_OUTPUT,
+  INSN_CONFIG_DIO_OPENDRAIN = COMEDI_OPENDRAIN,
+  INSN_CONFIG_ANALOG_TRIG = 16,
+  INSN_CONFIG_ALT_SOURCE = 20,
+  INSN_CONFIG_DIGITAL_TRIG = 21,
+  INSN_CONFIG_BLOCK_SIZE = 22,
+  INSN_CONFIG_TIMER_1 = 23,
+  INSN_CONFIG_FILTER = 24,
+  INSN_CONFIG_CHANGE_NOTIFY = 25,
+  INSN_CONFIG_SERIAL_CLOCK = 26,
+  INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
+  INSN_CONFIG_DIO_QUERY = 28,
+  INSN_CONFIG_PWM_OUTPUT = 29,
+  INSN_CONFIG_GET_PWM_OUTPUT = 30,
+  INSN_CONFIG_ARM = 31,
+  INSN_CONFIG_DISARM = 32,
+  INSN_CONFIG_GET_COUNTER_STATUS = 33,
+  INSN_CONFIG_RESET = 34,
+  INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,
+  INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,
+  INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,
+  INSN_CONFIG_SET_GATE_SRC = 2001,
+  INSN_CONFIG_GET_GATE_SRC = 2002,
+  INSN_CONFIG_SET_CLOCK_SRC = 2003,
+  INSN_CONFIG_GET_CLOCK_SRC = 2004,
+  INSN_CONFIG_SET_OTHER_SRC = 2005,
+  INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,
+  INSN_CONFIG_SET_COUNTER_MODE = 4097,
+  INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,
+  INSN_CONFIG_8254_READ_STATUS = 4098,
+  INSN_CONFIG_SET_ROUTING = 4099,
+  INSN_CONFIG_GET_ROUTING = 4109,
+  INSN_CONFIG_PWM_SET_PERIOD = 5000,
+  INSN_CONFIG_PWM_GET_PERIOD = 5001,
+  INSN_CONFIG_GET_PWM_STATUS = 5002,
+  INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
+  INSN_CONFIG_PWM_GET_H_BRIDGE = 5004,
+  INSN_CONFIG_GET_CMD_TIMING_CONSTRAINTS = 5005,
+};
+enum device_config_route_ids {
+  INSN_DEVICE_CONFIG_TEST_ROUTE = 0,
+  INSN_DEVICE_CONFIG_CONNECT_ROUTE = 1,
+  INSN_DEVICE_CONFIG_DISCONNECT_ROUTE = 2,
+  INSN_DEVICE_CONFIG_GET_ROUTES = 3,
+};
+enum comedi_digital_trig_op {
+  COMEDI_DIGITAL_TRIG_DISABLE = 0,
+  COMEDI_DIGITAL_TRIG_ENABLE_EDGES = 1,
+  COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = 2
+};
+enum comedi_support_level {
+  COMEDI_UNKNOWN_SUPPORT = 0,
+  COMEDI_SUPPORTED,
+  COMEDI_UNSUPPORTED
+};
+enum comedi_counter_status_flags {
+  COMEDI_COUNTER_ARMED = 0x1,
+  COMEDI_COUNTER_COUNTING = 0x2,
+  COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
+};
+#define CIO 'd'
+#define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
+#define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
+#define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
+#define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
+#define COMEDI_LOCK _IO(CIO, 5)
+#define COMEDI_UNLOCK _IO(CIO, 6)
+#define COMEDI_CANCEL _IO(CIO, 7)
+#define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
+#define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
+#define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
+#define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
+#define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
+#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
+#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
+#define COMEDI_POLL _IO(CIO, 15)
+#define COMEDI_SETRSUBD _IO(CIO, 16)
+#define COMEDI_SETWSUBD _IO(CIO, 17)
+struct comedi_insn {
+  unsigned int insn;
+  unsigned int n;
+  unsigned int __user * data;
+  unsigned int subdev;
+  unsigned int chanspec;
+  unsigned int unused[3];
+};
+struct comedi_insnlist {
+  unsigned int n_insns;
+  struct comedi_insn __user * insns;
+};
+struct comedi_cmd {
+  unsigned int subdev;
+  unsigned int flags;
+  unsigned int start_src;
+  unsigned int start_arg;
+  unsigned int scan_begin_src;
+  unsigned int scan_begin_arg;
+  unsigned int convert_src;
+  unsigned int convert_arg;
+  unsigned int scan_end_src;
+  unsigned int scan_end_arg;
+  unsigned int stop_src;
+  unsigned int stop_arg;
+  unsigned int * chanlist;
+  unsigned int chanlist_len;
+  short __user * data;
+  unsigned int data_len;
+};
+struct comedi_chaninfo {
+  unsigned int subdev;
+  unsigned int __user * maxdata_list;
+  unsigned int __user * flaglist;
+  unsigned int __user * rangelist;
+  unsigned int unused[4];
+};
+struct comedi_rangeinfo {
+  unsigned int range_type;
+  void __user * range_ptr;
+};
+struct comedi_krange {
+  int min;
+  int max;
+  unsigned int flags;
+};
+struct comedi_subdinfo {
+  unsigned int type;
+  unsigned int n_chan;
+  unsigned int subd_flags;
+  unsigned int timer_type;
+  unsigned int len_chanlist;
+  unsigned int maxdata;
+  unsigned int flags;
+  unsigned int range_type;
+  unsigned int settling_time_0;
+  unsigned int insn_bits_support;
+  unsigned int unused[8];
+};
+struct comedi_devinfo {
+  unsigned int version_code;
+  unsigned int n_subdevs;
+  char driver_name[COMEDI_NAMELEN];
+  char board_name[COMEDI_NAMELEN];
+  int read_subdevice;
+  int write_subdevice;
+  int unused[30];
+};
+struct comedi_devconfig {
+  char board_name[COMEDI_NAMELEN];
+  int options[COMEDI_NDEVCONFOPTS];
+};
+struct comedi_bufconfig {
+  unsigned int subdevice;
+  unsigned int flags;
+  unsigned int maximum_size;
+  unsigned int size;
+  unsigned int unused[4];
+};
+struct comedi_bufinfo {
+  unsigned int subdevice;
+  unsigned int bytes_read;
+  unsigned int buf_write_ptr;
+  unsigned int buf_read_ptr;
+  unsigned int buf_write_count;
+  unsigned int buf_read_count;
+  unsigned int bytes_written;
+  unsigned int unused[4];
+};
+#define __RANGE(a,b) ((((a) & 0xffff) << 16) | ((b) & 0xffff))
+#define RANGE_OFFSET(a) (((a) >> 16) & 0xffff)
+#define RANGE_LENGTH(b) ((b) & 0xffff)
+#define RF_UNIT(flags) ((flags) & 0xff)
+#define RF_EXTERNAL 0x100
+#define UNIT_volt 0
+#define UNIT_mA 1
+#define UNIT_none 2
+#define COMEDI_MIN_SPEED 0xffffffffu
+enum i8254_mode {
+  I8254_MODE0 = (0 << 1),
+  I8254_MODE1 = (1 << 1),
+  I8254_MODE2 = (2 << 1),
+  I8254_MODE3 = (3 << 1),
+  I8254_MODE4 = (4 << 1),
+  I8254_MODE5 = (5 << 1),
+  I8254_BCD = 1,
+  I8254_BINARY = 0
+};
+#define NI_NAMES_BASE 0x8000u
+#define _TERM_N(base,n,x) ((base) + ((x) & ((n) - 1)))
+#define NI_PFI(x) _TERM_N(NI_NAMES_BASE, 64, x)
+#define TRIGGER_LINE(x) _TERM_N(NI_PFI(- 1) + 1, 8, x)
+#define NI_RTSI_BRD(x) _TERM_N(TRIGGER_LINE(- 1) + 1, 4, x)
+#define NI_MAX_COUNTERS 8
+#define NI_COUNTER_NAMES_BASE (NI_RTSI_BRD(- 1) + 1)
+#define NI_CtrSource(x) _TERM_N(NI_COUNTER_NAMES_BASE, NI_MAX_COUNTERS, x)
+#define NI_GATES_NAMES_BASE (NI_CtrSource(- 1) + 1)
+#define NI_CtrGate(x) _TERM_N(NI_GATES_NAMES_BASE, NI_MAX_COUNTERS, x)
+#define NI_CtrAux(x) _TERM_N(NI_CtrGate(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_CtrA(x) _TERM_N(NI_CtrAux(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_CtrB(x) _TERM_N(NI_CtrA(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_CtrZ(x) _TERM_N(NI_CtrB(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_GATES_NAMES_MAX NI_CtrZ(- 1)
+#define NI_CtrArmStartTrigger(x) _TERM_N(NI_CtrZ(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_CtrInternalOutput(x) _TERM_N(NI_CtrArmStartTrigger(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_CtrOut(x) _TERM_N(NI_CtrInternalOutput(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_CtrSampleClock(x) _TERM_N(NI_CtrOut(- 1) + 1, NI_MAX_COUNTERS, x)
+#define NI_COUNTER_NAMES_MAX NI_CtrSampleClock(- 1)
+enum ni_common_signal_names {
+  PXI_Star = NI_COUNTER_NAMES_MAX + 1,
+  PXI_Clk10,
+  PXIe_Clk100,
+  NI_AI_SampleClock,
+  NI_AI_SampleClockTimebase,
+  NI_AI_StartTrigger,
+  NI_AI_ReferenceTrigger,
+  NI_AI_ConvertClock,
+  NI_AI_ConvertClockTimebase,
+  NI_AI_PauseTrigger,
+  NI_AI_HoldCompleteEvent,
+  NI_AI_HoldComplete,
+  NI_AI_ExternalMUXClock,
+  NI_AI_STOP,
+  NI_AO_SampleClock,
+  NI_AO_SampleClockTimebase,
+  NI_AO_StartTrigger,
+  NI_AO_PauseTrigger,
+  NI_DI_SampleClock,
+  NI_DI_SampleClockTimebase,
+  NI_DI_StartTrigger,
+  NI_DI_ReferenceTrigger,
+  NI_DI_PauseTrigger,
+  NI_DI_InputBufferFull,
+  NI_DI_ReadyForStartEvent,
+  NI_DI_ReadyForTransferEventBurst,
+  NI_DI_ReadyForTransferEventPipelined,
+  NI_DO_SampleClock,
+  NI_DO_SampleClockTimebase,
+  NI_DO_StartTrigger,
+  NI_DO_PauseTrigger,
+  NI_DO_OutputBufferFull,
+  NI_DO_DataActiveEvent,
+  NI_DO_ReadyForStartEvent,
+  NI_DO_ReadyForTransferEvent,
+  NI_MasterTimebase,
+  NI_20MHzTimebase,
+  NI_80MHzTimebase,
+  NI_100MHzTimebase,
+  NI_200MHzTimebase,
+  NI_100kHzTimebase,
+  NI_10MHzRefClock,
+  NI_FrequencyOutput,
+  NI_ChangeDetectionEvent,
+  NI_AnalogComparisonEvent,
+  NI_WatchdogExpiredEvent,
+  NI_WatchdogExpirationTrigger,
+  NI_SCXI_Trig1,
+  NI_LogicLow,
+  NI_LogicHigh,
+  NI_ExternalStrobe,
+  NI_PFI_DO,
+  NI_CaseGround,
+  NI_RGOUT0,
+  _NI_NAMES_MAX_PLUS_1,
+  NI_NUM_NAMES = _NI_NAMES_MAX_PLUS_1 - NI_NAMES_BASE,
+};
+#define NI_USUAL_PFI_SELECT(x) (((x) < 10) ? (0x1 + (x)) : (0xb + (x)))
+#define NI_USUAL_RTSI_SELECT(x) (((x) < 7) ? (0xb + (x)) : 0x1b)
+#define NI_GPCT_COUNTING_MODE_SHIFT 16
+#define NI_GPCT_INDEX_PHASE_BITSHIFT 20
+#define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
+enum ni_gpct_mode_bits {
+  NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
+  NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
+  NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
+  NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
+  NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
+  NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
+  NI_GPCT_STOP_MODE_MASK = 0x60,
+  NI_GPCT_STOP_ON_GATE_BITS = 0x00,
+  NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
+  NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
+  NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
+  NI_GPCT_OUTPUT_MODE_MASK = 0x300,
+  NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
+  NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
+  NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
+  NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
+  NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
+  NI_GPCT_DISARM_AT_TC_BITS = 0x400,
+  NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
+  NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
+  NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
+  NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
+  NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_COUNTING_MODE_NORMAL_BITS = 0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS = 0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS = 0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS = 0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS = 0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS = 0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
+  NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+  NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS = 0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+  NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS = 0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+  NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS = 0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+  NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+  NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
+  NI_GPCT_COUNTING_DIRECTION_MASK = 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+  NI_GPCT_COUNTING_DIRECTION_DOWN_BITS = 0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+  NI_GPCT_COUNTING_DIRECTION_UP_BITS = 0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+  NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS = 0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+  NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS = 0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+  NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
+  NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
+  NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
+  NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
+  NI_GPCT_OR_GATE_BIT = 0x10000000,
+  NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
+};
+enum ni_gpct_clock_source_bits {
+  NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
+  NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
+  NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
+  NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
+  NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
+  NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
+  NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
+  NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,
+  NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
+  NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
+  NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
+  NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
+  NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
+  NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,
+  NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,
+  NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
+};
+#define NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(x) (0x10 + (x))
+#define NI_GPCT_RTSI_CLOCK_SRC_BITS(x) (0x18 + (x))
+#define NI_GPCT_PFI_CLOCK_SRC_BITS(x) (0x20 + (x))
+enum ni_gpct_gate_select {
+  NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
+  NI_GPCT_AI_START2_GATE_SELECT = 0x12,
+  NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
+  NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
+  NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
+  NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
+  NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
+  NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
+  NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
+  NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
+  NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
+  NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
+  NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
+};
+#define NI_GPCT_GATE_PIN_GATE_SELECT(x) (0x102 + (x))
+#define NI_GPCT_RTSI_GATE_SELECT(x) NI_USUAL_RTSI_SELECT(x)
+#define NI_GPCT_PFI_GATE_SELECT(x) NI_USUAL_PFI_SELECT(x)
+#define NI_GPCT_UP_DOWN_PIN_GATE_SELECT(x) (0x202 + (x))
+enum ni_gpct_other_index {
+  NI_GPCT_SOURCE_ENCODER_A,
+  NI_GPCT_SOURCE_ENCODER_B,
+  NI_GPCT_SOURCE_ENCODER_Z
+};
+enum ni_gpct_other_select {
+  NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
+};
+#define NI_GPCT_PFI_OTHER_SELECT(x) NI_USUAL_PFI_SELECT(x)
+enum ni_gpct_arm_source {
+  NI_GPCT_ARM_IMMEDIATE = 0x0,
+  NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1,
+  NI_GPCT_HW_ARM = 0x1000,
+  NI_GPCT_ARM_UNKNOWN = NI_GPCT_HW_ARM,
+};
+enum ni_gpct_filter_select {
+  NI_GPCT_FILTER_OFF = 0x0,
+  NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
+  NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
+  NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
+  NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
+  NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
+  NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
+};
+enum ni_pfi_filter_select {
+  NI_PFI_FILTER_OFF = 0x0,
+  NI_PFI_FILTER_125ns = 0x1,
+  NI_PFI_FILTER_6425ns = 0x2,
+  NI_PFI_FILTER_2550us = 0x3
+};
+enum ni_mio_clock_source {
+  NI_MIO_INTERNAL_CLOCK = 0,
+  NI_MIO_RTSI_CLOCK = 1,
+  NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
+  NI_MIO_PLL_PXI10_CLOCK = 3,
+  NI_MIO_PLL_RTSI0_CLOCK = 4
+};
+#define NI_MIO_PLL_RTSI_CLOCK(x) (NI_MIO_PLL_RTSI0_CLOCK + (x))
+enum ni_rtsi_routing {
+  NI_RTSI_OUTPUT_ADR_START1 = 0,
+  NI_RTSI_OUTPUT_ADR_START2 = 1,
+  NI_RTSI_OUTPUT_SCLKG = 2,
+  NI_RTSI_OUTPUT_DACUPDN = 3,
+  NI_RTSI_OUTPUT_DA_START1 = 4,
+  NI_RTSI_OUTPUT_G_SRC0 = 5,
+  NI_RTSI_OUTPUT_G_GATE0 = 6,
+  NI_RTSI_OUTPUT_RGOUT0 = 7,
+  NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
+  NI_RTSI_OUTPUT_RTSI_OSC = 12
+};
+#define NI_RTSI_OUTPUT_RTSI_BRD(x) (NI_RTSI_OUTPUT_RTSI_BRD_0 + (x))
+enum ni_pfi_routing {
+  NI_PFI_OUTPUT_PFI_DEFAULT = 0,
+  NI_PFI_OUTPUT_AI_START1 = 1,
+  NI_PFI_OUTPUT_AI_START2 = 2,
+  NI_PFI_OUTPUT_AI_CONVERT = 3,
+  NI_PFI_OUTPUT_G_SRC1 = 4,
+  NI_PFI_OUTPUT_G_GATE1 = 5,
+  NI_PFI_OUTPUT_AO_UPDATE_N = 6,
+  NI_PFI_OUTPUT_AO_START1 = 7,
+  NI_PFI_OUTPUT_AI_START_PULSE = 8,
+  NI_PFI_OUTPUT_G_SRC0 = 9,
+  NI_PFI_OUTPUT_G_GATE0 = 10,
+  NI_PFI_OUTPUT_EXT_STROBE = 11,
+  NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
+  NI_PFI_OUTPUT_GOUT0 = 13,
+  NI_PFI_OUTPUT_GOUT1 = 14,
+  NI_PFI_OUTPUT_FREQ_OUT = 15,
+  NI_PFI_OUTPUT_PFI_DO = 16,
+  NI_PFI_OUTPUT_I_ATRIG = 17,
+  NI_PFI_OUTPUT_RTSI0 = 18,
+  NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
+  NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
+  NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
+  NI_PFI_OUTPUT_CDI_SAMPLE = 29,
+  NI_PFI_OUTPUT_CDO_UPDATE = 30
+};
+#define NI_PFI_OUTPUT_RTSI(x) (NI_PFI_OUTPUT_RTSI0 + (x))
+enum ni_660x_pfi_routing {
+  NI_660X_PFI_OUTPUT_COUNTER = 1,
+  NI_660X_PFI_OUTPUT_DIO = 2,
+};
+#define NI_EXT_PFI(x) (NI_USUAL_PFI_SELECT(x) - 1)
+#define NI_EXT_RTSI(x) (NI_USUAL_RTSI_SELECT(x) - 1)
+enum ni_m_series_cdio_scan_begin_src {
+  NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
+  NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
+  NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
+  NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
+  NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
+  NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
+  NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
+  NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
+  NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
+  NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
+};
+#define NI_CDIO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x)
+#define NI_CDIO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
+#define NI_AO_SCAN_BEGIN_SRC_PFI(x) NI_USUAL_PFI_SELECT(x)
+#define NI_AO_SCAN_BEGIN_SRC_RTSI(x) NI_USUAL_RTSI_SELECT(x)
+enum ni_freq_out_clock_source_bits {
+  NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC,
+  NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC
+};
+enum amplc_dio_clock_source {
+  AMPLC_DIO_CLK_CLKN,
+  AMPLC_DIO_CLK_10MHZ,
+  AMPLC_DIO_CLK_1MHZ,
+  AMPLC_DIO_CLK_100KHZ,
+  AMPLC_DIO_CLK_10KHZ,
+  AMPLC_DIO_CLK_1KHZ,
+  AMPLC_DIO_CLK_OUTNM1,
+  AMPLC_DIO_CLK_EXT,
+  AMPLC_DIO_CLK_VCC,
+  AMPLC_DIO_CLK_GND,
+  AMPLC_DIO_CLK_PAT_PRESENT,
+  AMPLC_DIO_CLK_20MHZ
+};
+enum amplc_dio_ts_clock_src {
+  AMPLC_DIO_TS_CLK_1GHZ,
+  AMPLC_DIO_TS_CLK_1MHZ,
+  AMPLC_DIO_TS_CLK_1KHZ
+};
+enum amplc_dio_gate_source {
+  AMPLC_DIO_GAT_VCC,
+  AMPLC_DIO_GAT_GND,
+  AMPLC_DIO_GAT_GATN,
+  AMPLC_DIO_GAT_NOUTNM2,
+  AMPLC_DIO_GAT_RESERVED4,
+  AMPLC_DIO_GAT_RESERVED5,
+  AMPLC_DIO_GAT_RESERVED6,
+  AMPLC_DIO_GAT_RESERVED7,
+  AMPLC_DIO_GAT_NGATN = 6,
+  AMPLC_DIO_GAT_OUTNM2,
+  AMPLC_DIO_GAT_PAT_PRESENT,
+  AMPLC_DIO_GAT_PAT_OCCURRED,
+  AMPLC_DIO_GAT_PAT_GONE,
+  AMPLC_DIO_GAT_NPAT_PRESENT,
+  AMPLC_DIO_GAT_NPAT_OCCURRED,
+  AMPLC_DIO_GAT_NPAT_GONE
+};
+enum ke_counter_clock_source {
+  KE_CLK_20MHZ,
+  KE_CLK_4MHZ,
+  KE_CLK_EXT
+};
+#endif
diff --git a/libc/kernel/uapi/linux/counter.h b/libc/kernel/uapi/linux/counter.h
new file mode 100644
index 0000000..091e33d
--- /dev/null
+++ b/libc/kernel/uapi/linux/counter.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_COUNTER_H_
+#define _UAPI_COUNTER_H_
+#include <linux/ioctl.h>
+#include <linux/types.h>
+enum counter_component_type {
+  COUNTER_COMPONENT_NONE,
+  COUNTER_COMPONENT_SIGNAL,
+  COUNTER_COMPONENT_COUNT,
+  COUNTER_COMPONENT_FUNCTION,
+  COUNTER_COMPONENT_SYNAPSE_ACTION,
+  COUNTER_COMPONENT_EXTENSION,
+};
+enum counter_scope {
+  COUNTER_SCOPE_DEVICE,
+  COUNTER_SCOPE_SIGNAL,
+  COUNTER_SCOPE_COUNT,
+};
+struct counter_component {
+  __u8 type;
+  __u8 scope;
+  __u8 parent;
+  __u8 id;
+};
+enum counter_event_type {
+  COUNTER_EVENT_OVERFLOW,
+  COUNTER_EVENT_UNDERFLOW,
+  COUNTER_EVENT_OVERFLOW_UNDERFLOW,
+  COUNTER_EVENT_THRESHOLD,
+  COUNTER_EVENT_INDEX,
+};
+struct counter_watch {
+  struct counter_component component;
+  __u8 event;
+  __u8 channel;
+};
+#define COUNTER_ADD_WATCH_IOCTL _IOW(0x3E, 0x00, struct counter_watch)
+#define COUNTER_ENABLE_EVENTS_IOCTL _IO(0x3E, 0x01)
+#define COUNTER_DISABLE_EVENTS_IOCTL _IO(0x3E, 0x02)
+struct counter_event {
+  __aligned_u64 timestamp;
+  __aligned_u64 value;
+  struct counter_watch watch;
+  __u8 status;
+};
+enum counter_count_direction {
+  COUNTER_COUNT_DIRECTION_FORWARD,
+  COUNTER_COUNT_DIRECTION_BACKWARD,
+};
+enum counter_count_mode {
+  COUNTER_COUNT_MODE_NORMAL,
+  COUNTER_COUNT_MODE_RANGE_LIMIT,
+  COUNTER_COUNT_MODE_NON_RECYCLE,
+  COUNTER_COUNT_MODE_MODULO_N,
+};
+enum counter_function {
+  COUNTER_FUNCTION_INCREASE,
+  COUNTER_FUNCTION_DECREASE,
+  COUNTER_FUNCTION_PULSE_DIRECTION,
+  COUNTER_FUNCTION_QUADRATURE_X1_A,
+  COUNTER_FUNCTION_QUADRATURE_X1_B,
+  COUNTER_FUNCTION_QUADRATURE_X2_A,
+  COUNTER_FUNCTION_QUADRATURE_X2_B,
+  COUNTER_FUNCTION_QUADRATURE_X4,
+};
+enum counter_signal_level {
+  COUNTER_SIGNAL_LEVEL_LOW,
+  COUNTER_SIGNAL_LEVEL_HIGH,
+};
+enum counter_synapse_action {
+  COUNTER_SYNAPSE_ACTION_NONE,
+  COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+  COUNTER_SYNAPSE_ACTION_FALLING_EDGE,
+  COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+};
+#endif
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 851bd79..15e9e29 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -21,7 +21,7 @@
 #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(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"), ___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 ___C(a,b) CXL_MEM_COMMAND_ID_ ##a
 enum {
   CXL_CMDS
@@ -30,7 +30,7 @@
 #define ___C(a,b) { b }
 static const struct {
   const char * name;
-} cxl_command_names[] = {
+} cxl_command_names[] __attribute__((__unused__)) = {
   CXL_CMDS
 };
 #undef ___C
diff --git a/libc/kernel/uapi/linux/cyclades.h b/libc/kernel/uapi/linux/cyclades.h
index 60bc4af..c0aa7aa 100644
--- a/libc/kernel/uapi/linux/cyclades.h
+++ b/libc/kernel/uapi/linux/cyclades.h
@@ -18,24 +18,14 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_CYCLADES_H
 #define _UAPI_LINUX_CYCLADES_H
-#include <linux/types.h>
+#warning "Support for features provided by this header has been removed"
+#warning "Please consider updating your code"
 struct cyclades_monitor {
   unsigned long int_count;
   unsigned long char_count;
   unsigned long char_max;
   unsigned long char_last;
 };
-struct cyclades_idle_stats {
-  __kernel_old_time_t in_use;
-  __kernel_old_time_t recv_idle;
-  __kernel_old_time_t xmit_idle;
-  unsigned long recv_bytes;
-  unsigned long xmit_bytes;
-  unsigned long overruns;
-  unsigned long frame_errs;
-  unsigned long parity_errs;
-};
-#define CYCLADES_MAGIC 0x4359
 #define CYGETMON 0x435901
 #define CYGETTHRESH 0x435902
 #define CYSETTHRESH 0x435903
@@ -54,253 +44,4 @@
 #define CYGETCD1400VER 0x435910
 #define CYSETWAIT 0x435912
 #define CYGETWAIT 0x435913
-#define CZIOC ('M' << 8)
-#define CZ_NBOARDS (CZIOC | 0xfa)
-#define CZ_BOOT_START (CZIOC | 0xfb)
-#define CZ_BOOT_DATA (CZIOC | 0xfc)
-#define CZ_BOOT_END (CZIOC | 0xfd)
-#define CZ_TEST (CZIOC | 0xfe)
-#define CZ_DEF_POLL (HZ / 25)
-#define MAX_BOARD 4
-#define MAX_DEV 256
-#define CYZ_MAX_SPEED 921600
-#define CYZ_FIFO_SIZE 16
-#define CYZ_BOOT_NWORDS 0x100
-struct CYZ_BOOT_CTRL {
-  unsigned short nboard;
-  int status[MAX_BOARD];
-  int nchannel[MAX_BOARD];
-  int fw_rev[MAX_BOARD];
-  unsigned long offset;
-  unsigned long data[CYZ_BOOT_NWORDS];
-};
-#ifndef DP_WINDOW_SIZE
-#define DP_WINDOW_SIZE (0x00080000)
-#define ZE_DP_WINDOW_SIZE (0x00100000)
-#define CTRL_WINDOW_SIZE (0x00000080)
-struct CUSTOM_REG {
-  __u32 fpga_id;
-  __u32 fpga_version;
-  __u32 cpu_start;
-  __u32 cpu_stop;
-  __u32 misc_reg;
-  __u32 idt_mode;
-  __u32 uart_irq_status;
-  __u32 clear_timer0_irq;
-  __u32 clear_timer1_irq;
-  __u32 clear_timer2_irq;
-  __u32 test_register;
-  __u32 test_count;
-  __u32 timer_select;
-  __u32 pr_uart_irq_status;
-  __u32 ram_wait_state;
-  __u32 uart_wait_state;
-  __u32 timer_wait_state;
-  __u32 ack_wait_state;
-};
-struct RUNTIME_9060 {
-  __u32 loc_addr_range;
-  __u32 loc_addr_base;
-  __u32 loc_arbitr;
-  __u32 endian_descr;
-  __u32 loc_rom_range;
-  __u32 loc_rom_base;
-  __u32 loc_bus_descr;
-  __u32 loc_range_mst;
-  __u32 loc_base_mst;
-  __u32 loc_range_io;
-  __u32 pci_base_mst;
-  __u32 pci_conf_io;
-  __u32 filler1;
-  __u32 filler2;
-  __u32 filler3;
-  __u32 filler4;
-  __u32 mail_box_0;
-  __u32 mail_box_1;
-  __u32 mail_box_2;
-  __u32 mail_box_3;
-  __u32 filler5;
-  __u32 filler6;
-  __u32 filler7;
-  __u32 filler8;
-  __u32 pci_doorbell;
-  __u32 loc_doorbell;
-  __u32 intr_ctrl_stat;
-  __u32 init_ctrl;
-};
-#define WIN_RAM 0x00000001L
-#define WIN_CREG 0x14000001L
-#define TIMER_BY_1M 0x00
-#define TIMER_BY_256K 0x01
-#define TIMER_BY_128K 0x02
-#define TIMER_BY_32K 0x03
-#endif
-#ifndef ZFIRM_ID
-#define MAX_CHAN 64
-#define ID_ADDRESS 0x00000180L
-#define ZFIRM_ID 0x5557465AL
-#define ZFIRM_HLT 0x59505B5CL
-#define ZFIRM_RST 0x56040674L
-#define ZF_TINACT_DEF 1000
-#define ZF_TINACT ZF_TINACT_DEF
-struct FIRM_ID {
-  __u32 signature;
-  __u32 zfwctrl_addr;
-};
-#define C_OS_LINUX 0x00000030
-#define C_CH_DISABLE 0x00000000
-#define C_CH_TXENABLE 0x00000001
-#define C_CH_RXENABLE 0x00000002
-#define C_CH_ENABLE 0x00000003
-#define C_CH_LOOPBACK 0x00000004
-#define C_PR_NONE 0x00000000
-#define C_PR_ODD 0x00000001
-#define C_PR_EVEN 0x00000002
-#define C_PR_MARK 0x00000004
-#define C_PR_SPACE 0x00000008
-#define C_PR_PARITY 0x000000ff
-#define C_PR_DISCARD 0x00000100
-#define C_PR_IGNORE 0x00000200
-#define C_DL_CS5 0x00000001
-#define C_DL_CS6 0x00000002
-#define C_DL_CS7 0x00000004
-#define C_DL_CS8 0x00000008
-#define C_DL_CS 0x0000000f
-#define C_DL_1STOP 0x00000010
-#define C_DL_15STOP 0x00000020
-#define C_DL_2STOP 0x00000040
-#define C_DL_STOP 0x000000f0
-#define C_IN_DISABLE 0x00000000
-#define C_IN_TXBEMPTY 0x00000001
-#define C_IN_TXLOWWM 0x00000002
-#define C_IN_RXHIWM 0x00000010
-#define C_IN_RXNNDT 0x00000020
-#define C_IN_MDCD 0x00000100
-#define C_IN_MDSR 0x00000200
-#define C_IN_MRI 0x00000400
-#define C_IN_MCTS 0x00000800
-#define C_IN_RXBRK 0x00001000
-#define C_IN_PR_ERROR 0x00002000
-#define C_IN_FR_ERROR 0x00004000
-#define C_IN_OVR_ERROR 0x00008000
-#define C_IN_RXOFL 0x00010000
-#define C_IN_IOCTLW 0x00020000
-#define C_IN_MRTS 0x00040000
-#define C_IN_ICHAR 0x00080000
-#define C_FL_OXX 0x00000001
-#define C_FL_IXX 0x00000002
-#define C_FL_OIXANY 0x00000004
-#define C_FL_SWFLOW 0x0000000f
-#define C_FS_TXIDLE 0x00000000
-#define C_FS_SENDING 0x00000001
-#define C_FS_SWFLOW 0x00000002
-#define C_RS_PARAM 0x80000000
-#define C_RS_RTS 0x00000001
-#define C_RS_DTR 0x00000004
-#define C_RS_DCD 0x00000100
-#define C_RS_DSR 0x00000200
-#define C_RS_RI 0x00000400
-#define C_RS_CTS 0x00000800
-#define C_CM_RESET 0x01
-#define C_CM_IOCTL 0x02
-#define C_CM_IOCTLW 0x03
-#define C_CM_IOCTLM 0x04
-#define C_CM_SENDXOFF 0x10
-#define C_CM_SENDXON 0x11
-#define C_CM_CLFLOW 0x12
-#define C_CM_SENDBRK 0x41
-#define C_CM_INTBACK 0x42
-#define C_CM_SET_BREAK 0x43
-#define C_CM_CLR_BREAK 0x44
-#define C_CM_CMD_DONE 0x45
-#define C_CM_INTBACK2 0x46
-#define C_CM_TINACT 0x51
-#define C_CM_IRQ_ENBL 0x52
-#define C_CM_IRQ_DSBL 0x53
-#define C_CM_ACK_ENBL 0x54
-#define C_CM_ACK_DSBL 0x55
-#define C_CM_FLUSH_RX 0x56
-#define C_CM_FLUSH_TX 0x57
-#define C_CM_Q_ENABLE 0x58
-#define C_CM_Q_DISABLE 0x59
-#define C_CM_TXBEMPTY 0x60
-#define C_CM_TXLOWWM 0x61
-#define C_CM_RXHIWM 0x62
-#define C_CM_RXNNDT 0x63
-#define C_CM_TXFEMPTY 0x64
-#define C_CM_ICHAR 0x65
-#define C_CM_MDCD 0x70
-#define C_CM_MDSR 0x71
-#define C_CM_MRI 0x72
-#define C_CM_MCTS 0x73
-#define C_CM_MRTS 0x74
-#define C_CM_RXBRK 0x84
-#define C_CM_PR_ERROR 0x85
-#define C_CM_FR_ERROR 0x86
-#define C_CM_OVR_ERROR 0x87
-#define C_CM_RXOFL 0x88
-#define C_CM_CMDERROR 0x90
-#define C_CM_FATAL 0x91
-#define C_CM_HW_RESET 0x92
-struct CH_CTRL {
-  __u32 op_mode;
-  __u32 intr_enable;
-  __u32 sw_flow;
-  __u32 flow_status;
-  __u32 comm_baud;
-  __u32 comm_parity;
-  __u32 comm_data_l;
-  __u32 comm_flags;
-  __u32 hw_flow;
-  __u32 rs_control;
-  __u32 rs_status;
-  __u32 flow_xon;
-  __u32 flow_xoff;
-  __u32 hw_overflow;
-  __u32 sw_overflow;
-  __u32 comm_error;
-  __u32 ichar;
-  __u32 filler[7];
-};
-struct BUF_CTRL {
-  __u32 flag_dma;
-  __u32 tx_bufaddr;
-  __u32 tx_bufsize;
-  __u32 tx_threshold;
-  __u32 tx_get;
-  __u32 tx_put;
-  __u32 rx_bufaddr;
-  __u32 rx_bufsize;
-  __u32 rx_threshold;
-  __u32 rx_get;
-  __u32 rx_put;
-  __u32 filler[5];
-};
-struct BOARD_CTRL {
-  __u32 n_channel;
-  __u32 fw_version;
-  __u32 op_system;
-  __u32 dr_version;
-  __u32 inactivity;
-  __u32 hcmd_channel;
-  __u32 hcmd_param;
-  __u32 fwcmd_channel;
-  __u32 fwcmd_param;
-  __u32 zf_int_queue_addr;
-  __u32 filler[6];
-};
-#define QUEUE_SIZE (10 * MAX_CHAN)
-struct INT_QUEUE {
-  unsigned char intr_code[QUEUE_SIZE];
-  unsigned long channel[QUEUE_SIZE];
-  unsigned long param[QUEUE_SIZE];
-  unsigned long put;
-  unsigned long get;
-};
-struct ZFW_CTRL {
-  struct BOARD_CTRL board_ctrl;
-  struct CH_CTRL ch_ctrl[MAX_CHAN];
-  struct BUF_CTRL buf_ctrl[MAX_CHAN];
-};
-#endif
 #endif
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index e6e006f..a809306 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -99,6 +99,10 @@
   DEVLINK_CMD_TRAP_POLICER_NEW,
   DEVLINK_CMD_TRAP_POLICER_DEL,
   DEVLINK_CMD_HEALTH_REPORTER_TEST,
+  DEVLINK_CMD_RATE_GET,
+  DEVLINK_CMD_RATE_SET,
+  DEVLINK_CMD_RATE_NEW,
+  DEVLINK_CMD_RATE_DEL,
   __DEVLINK_CMD_MAX,
   DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
 };
@@ -141,6 +145,10 @@
   DEVLINK_PORT_FLAVOUR_UNUSED,
   DEVLINK_PORT_FLAVOUR_PCI_SF,
 };
+enum devlink_rate_type {
+  DEVLINK_RATE_TYPE_LEAF,
+  DEVLINK_RATE_TYPE_NODE,
+};
 enum devlink_param_cmode {
   DEVLINK_PARAM_CMODE_RUNTIME,
   DEVLINK_PARAM_CMODE_DRIVERINIT,
@@ -370,6 +378,12 @@
   DEVLINK_ATTR_RELOAD_ACTION_INFO,
   DEVLINK_ATTR_RELOAD_ACTION_STATS,
   DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
+  DEVLINK_ATTR_RATE_TYPE,
+  DEVLINK_ATTR_RATE_TX_SHARE,
+  DEVLINK_ATTR_RATE_TX_MAX,
+  DEVLINK_ATTR_RATE_NODE_NAME,
+  DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
+  DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
   __DEVLINK_ATTR_MAX,
   DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/dlm_device.h b/libc/kernel/uapi/linux/dlm_device.h
index 9cf41a8..5e54d2e 100644
--- a/libc/kernel/uapi/linux/dlm_device.h
+++ b/libc/kernel/uapi/linux/dlm_device.h
@@ -39,12 +39,12 @@
   void __user * bastaddr;
   struct dlm_lksb __user * lksb;
   char lvb[DLM_USER_LVB_LEN];
-  char name[0];
+  char name[];
 };
 struct dlm_lspace_params {
   __u32 flags;
   __u32 minor;
-  char name[0];
+  char name[];
 };
 struct dlm_purge_params {
   __u32 nodeid;
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index 4c0a9f0..09f8a98 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -55,6 +55,8 @@
   __u32 next;
   char name[0];
 };
+#define DM_NAME_LIST_FLAG_HAS_UUID 1
+#define DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID 2
 struct dm_target_versions {
   __u32 next;
   __u32 version[3];
@@ -104,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 44
+#define DM_VERSION_MINOR 45
 #define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2021-02-01)"
+#define DM_VERSION_EXTRA "-ioctl(2021-03-22)"
 #define DM_READONLY_FLAG (1 << 0)
 #define DM_SUSPEND_FLAG (1 << 1)
 #define DM_PERSISTENT_DEV_FLAG (1 << 3)
@@ -124,4 +126,5 @@
 #define DM_DATA_OUT_FLAG (1 << 16)
 #define DM_DEFERRED_REMOVE (1 << 17)
 #define DM_INTERNAL_SUSPEND_FLAG (1 << 18)
+#define DM_IMA_MEASUREMENT_FLAG (1 << 19)
 #endif
diff --git a/libc/kernel/uapi/linux/dqblk_xfs.h b/libc/kernel/uapi/linux/dqblk_xfs.h
index db7c7e5..6164991 100644
--- a/libc/kernel/uapi/linux/dqblk_xfs.h
+++ b/libc/kernel/uapi/linux/dqblk_xfs.h
@@ -130,6 +130,9 @@
   __s32 qs_rtbtimelimit;
   __u16 qs_bwarnlimit;
   __u16 qs_iwarnlimit;
-  __u64 qs_pad2[8];
+  __u16 qs_rtbwarnlimit;
+  __u16 qs_pad3;
+  __u32 qs_pad4;
+  __u64 qs_pad2[7];
 };
 #endif
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index f9f122a..7655f12 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -360,6 +360,7 @@
 #define NT_ARM_PACA_KEYS 0x407
 #define NT_ARM_PACG_KEYS 0x408
 #define NT_ARM_TAGGED_ADDR_CTRL 0x409
+#define NT_ARM_PAC_ENABLED_KEYS 0x40a
 #define NT_ARC_V2 0x600
 #define NT_VMCOREDD 0x700
 #define NT_MIPS_DSP 0x800
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 021a69b..741ea2a 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -78,6 +78,7 @@
   ETHTOOL_RX_COPYBREAK,
   ETHTOOL_TX_COPYBREAK,
   ETHTOOL_PFC_PREVENTION_TOUT,
+  ETHTOOL_TX_COPYBREAK_BUF_SIZE,
   __ETHTOOL_TUNABLE_COUNT,
 };
 enum tunable_type_id {
@@ -207,6 +208,7 @@
   ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE,
   ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED,
   ETHTOOL_LINK_EXT_STATE_OVERHEAT,
+  ETHTOOL_LINK_EXT_STATE_MODULE,
 };
 enum ethtool_link_ext_substate_autoneg {
   ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED = 1,
@@ -232,11 +234,16 @@
 enum ethtool_link_ext_substate_bad_signal_integrity {
   ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 1,
   ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE,
+  ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_REFERENCE_CLOCK_LOST,
+  ETHTOOL_LINK_EXT_SUBSTATE_BSI_SERDES_ALOS,
 };
 enum ethtool_link_ext_substate_cable_issue {
   ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE = 1,
   ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE,
 };
+enum ethtool_link_ext_substate_module {
+  ETHTOOL_LINK_EXT_SUBSTATE_MODULE_CMIS_NOT_READY = 1,
+};
 #define ETH_GSTRING_LEN 32
 enum ethtool_stringset {
   ETH_SS_TEST = 0,
@@ -255,8 +262,21 @@
   ETH_SS_TS_TX_TYPES,
   ETH_SS_TS_RX_FILTERS,
   ETH_SS_UDP_TUNNEL_TYPES,
+  ETH_SS_STATS_STD,
+  ETH_SS_STATS_ETH_PHY,
+  ETH_SS_STATS_ETH_MAC,
+  ETH_SS_STATS_ETH_CTRL,
+  ETH_SS_STATS_RMON,
   ETH_SS_COUNT
 };
+enum ethtool_module_power_mode_policy {
+  ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH = 1,
+  ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO,
+};
+enum ethtool_module_power_mode {
+  ETHTOOL_MODULE_POWER_MODE_LOW = 1,
+  ETHTOOL_MODULE_POWER_MODE_HIGH,
+};
 struct ethtool_gstrings {
   __u32 cmd;
   __u32 string_set;
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index 67091a1..7dcae22 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -49,6 +49,13 @@
   ETHTOOL_MSG_CABLE_TEST_ACT,
   ETHTOOL_MSG_CABLE_TEST_TDR_ACT,
   ETHTOOL_MSG_TUNNEL_INFO_GET,
+  ETHTOOL_MSG_FEC_GET,
+  ETHTOOL_MSG_FEC_SET,
+  ETHTOOL_MSG_MODULE_EEPROM_GET,
+  ETHTOOL_MSG_STATS_GET,
+  ETHTOOL_MSG_PHC_VCLOCKS_GET,
+  ETHTOOL_MSG_MODULE_GET,
+  ETHTOOL_MSG_MODULE_SET,
   __ETHTOOL_MSG_USER_CNT,
   ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
 };
@@ -83,6 +90,13 @@
   ETHTOOL_MSG_CABLE_TEST_NTF,
   ETHTOOL_MSG_CABLE_TEST_TDR_NTF,
   ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY,
+  ETHTOOL_MSG_FEC_GET_REPLY,
+  ETHTOOL_MSG_FEC_NTF,
+  ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY,
+  ETHTOOL_MSG_STATS_GET_REPLY,
+  ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY,
+  ETHTOOL_MSG_MODULE_GET_REPLY,
+  ETHTOOL_MSG_MODULE_NTF,
   __ETHTOOL_MSG_KERNEL_CNT,
   ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
 };
@@ -236,6 +250,7 @@
   ETHTOOL_A_RINGS_RX_MINI,
   ETHTOOL_A_RINGS_RX_JUMBO,
   ETHTOOL_A_RINGS_TX,
+  ETHTOOL_A_RINGS_RX_BUF_LEN,
   __ETHTOOL_A_RINGS_CNT,
   ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
 };
@@ -278,6 +293,8 @@
   ETHTOOL_A_COALESCE_TX_USECS_HIGH,
   ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH,
   ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,
+  ETHTOOL_A_COALESCE_USE_CQE_MODE_TX,
+  ETHTOOL_A_COALESCE_USE_CQE_MODE_RX,
   __ETHTOOL_A_COALESCE_CNT,
   ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1)
 };
@@ -322,6 +339,14 @@
   ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
 };
 enum {
+  ETHTOOL_A_PHC_VCLOCKS_UNSPEC,
+  ETHTOOL_A_PHC_VCLOCKS_HEADER,
+  ETHTOOL_A_PHC_VCLOCKS_NUM,
+  ETHTOOL_A_PHC_VCLOCKS_INDEX,
+  __ETHTOOL_A_PHC_VCLOCKS_CNT,
+  ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1)
+};
+enum {
   ETHTOOL_A_CABLE_TEST_UNSPEC,
   ETHTOOL_A_CABLE_TEST_HEADER,
   __ETHTOOL_A_CABLE_TEST_CNT,
@@ -461,6 +486,121 @@
   __ETHTOOL_A_TUNNEL_INFO_CNT,
   ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1)
 };
+enum {
+  ETHTOOL_A_FEC_UNSPEC,
+  ETHTOOL_A_FEC_HEADER,
+  ETHTOOL_A_FEC_MODES,
+  ETHTOOL_A_FEC_AUTO,
+  ETHTOOL_A_FEC_ACTIVE,
+  ETHTOOL_A_FEC_STATS,
+  __ETHTOOL_A_FEC_CNT,
+  ETHTOOL_A_FEC_MAX = (__ETHTOOL_A_FEC_CNT - 1)
+};
+enum {
+  ETHTOOL_A_FEC_STAT_UNSPEC,
+  ETHTOOL_A_FEC_STAT_PAD,
+  ETHTOOL_A_FEC_STAT_CORRECTED,
+  ETHTOOL_A_FEC_STAT_UNCORR,
+  ETHTOOL_A_FEC_STAT_CORR_BITS,
+  __ETHTOOL_A_FEC_STAT_CNT,
+  ETHTOOL_A_FEC_STAT_MAX = (__ETHTOOL_A_FEC_STAT_CNT - 1)
+};
+enum {
+  ETHTOOL_A_MODULE_EEPROM_UNSPEC,
+  ETHTOOL_A_MODULE_EEPROM_HEADER,
+  ETHTOOL_A_MODULE_EEPROM_OFFSET,
+  ETHTOOL_A_MODULE_EEPROM_LENGTH,
+  ETHTOOL_A_MODULE_EEPROM_PAGE,
+  ETHTOOL_A_MODULE_EEPROM_BANK,
+  ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS,
+  ETHTOOL_A_MODULE_EEPROM_DATA,
+  __ETHTOOL_A_MODULE_EEPROM_CNT,
+  ETHTOOL_A_MODULE_EEPROM_MAX = (__ETHTOOL_A_MODULE_EEPROM_CNT - 1)
+};
+enum {
+  ETHTOOL_A_STATS_UNSPEC,
+  ETHTOOL_A_STATS_PAD,
+  ETHTOOL_A_STATS_HEADER,
+  ETHTOOL_A_STATS_GROUPS,
+  ETHTOOL_A_STATS_GRP,
+  __ETHTOOL_A_STATS_CNT,
+  ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1)
+};
+enum {
+  ETHTOOL_STATS_ETH_PHY,
+  ETHTOOL_STATS_ETH_MAC,
+  ETHTOOL_STATS_ETH_CTRL,
+  ETHTOOL_STATS_RMON,
+  __ETHTOOL_STATS_CNT
+};
+enum {
+  ETHTOOL_A_STATS_GRP_UNSPEC,
+  ETHTOOL_A_STATS_GRP_PAD,
+  ETHTOOL_A_STATS_GRP_ID,
+  ETHTOOL_A_STATS_GRP_SS_ID,
+  ETHTOOL_A_STATS_GRP_STAT,
+  ETHTOOL_A_STATS_GRP_HIST_RX,
+  ETHTOOL_A_STATS_GRP_HIST_TX,
+  ETHTOOL_A_STATS_GRP_HIST_BKT_LOW,
+  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)
+};
+enum {
+  ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR,
+  __ETHTOOL_A_STATS_ETH_PHY_CNT,
+  ETHTOOL_A_STATS_ETH_PHY_MAX = (__ETHTOOL_A_STATS_ETH_PHY_CNT - 1)
+};
+enum {
+  ETHTOOL_A_STATS_ETH_MAC_2_TX_PKT,
+  ETHTOOL_A_STATS_ETH_MAC_3_SINGLE_COL,
+  ETHTOOL_A_STATS_ETH_MAC_4_MULTI_COL,
+  ETHTOOL_A_STATS_ETH_MAC_5_RX_PKT,
+  ETHTOOL_A_STATS_ETH_MAC_6_FCS_ERR,
+  ETHTOOL_A_STATS_ETH_MAC_7_ALIGN_ERR,
+  ETHTOOL_A_STATS_ETH_MAC_8_TX_BYTES,
+  ETHTOOL_A_STATS_ETH_MAC_9_TX_DEFER,
+  ETHTOOL_A_STATS_ETH_MAC_10_LATE_COL,
+  ETHTOOL_A_STATS_ETH_MAC_11_XS_COL,
+  ETHTOOL_A_STATS_ETH_MAC_12_TX_INT_ERR,
+  ETHTOOL_A_STATS_ETH_MAC_13_CS_ERR,
+  ETHTOOL_A_STATS_ETH_MAC_14_RX_BYTES,
+  ETHTOOL_A_STATS_ETH_MAC_15_RX_INT_ERR,
+  ETHTOOL_A_STATS_ETH_MAC_18_TX_MCAST,
+  ETHTOOL_A_STATS_ETH_MAC_19_TX_BCAST,
+  ETHTOOL_A_STATS_ETH_MAC_20_XS_DEFER,
+  ETHTOOL_A_STATS_ETH_MAC_21_RX_MCAST,
+  ETHTOOL_A_STATS_ETH_MAC_22_RX_BCAST,
+  ETHTOOL_A_STATS_ETH_MAC_23_IR_LEN_ERR,
+  ETHTOOL_A_STATS_ETH_MAC_24_OOR_LEN,
+  ETHTOOL_A_STATS_ETH_MAC_25_TOO_LONG_ERR,
+  __ETHTOOL_A_STATS_ETH_MAC_CNT,
+  ETHTOOL_A_STATS_ETH_MAC_MAX = (__ETHTOOL_A_STATS_ETH_MAC_CNT - 1)
+};
+enum {
+  ETHTOOL_A_STATS_ETH_CTRL_3_TX,
+  ETHTOOL_A_STATS_ETH_CTRL_4_RX,
+  ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP,
+  __ETHTOOL_A_STATS_ETH_CTRL_CNT,
+  ETHTOOL_A_STATS_ETH_CTRL_MAX = (__ETHTOOL_A_STATS_ETH_CTRL_CNT - 1)
+};
+enum {
+  ETHTOOL_A_STATS_RMON_UNDERSIZE,
+  ETHTOOL_A_STATS_RMON_OVERSIZE,
+  ETHTOOL_A_STATS_RMON_FRAG,
+  ETHTOOL_A_STATS_RMON_JABBER,
+  __ETHTOOL_A_STATS_RMON_CNT,
+  ETHTOOL_A_STATS_RMON_MAX = (__ETHTOOL_A_STATS_RMON_CNT - 1)
+};
+enum {
+  ETHTOOL_A_MODULE_UNSPEC,
+  ETHTOOL_A_MODULE_HEADER,
+  ETHTOOL_A_MODULE_POWER_MODE_POLICY,
+  ETHTOOL_A_MODULE_POWER_MODE,
+  __ETHTOOL_A_MODULE_CNT,
+  ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1)
+};
 #define ETHTOOL_GENL_NAME "ethtool"
 #define ETHTOOL_GENL_VERSION 1
 #define ETHTOOL_MCGRP_MONITOR_NAME "monitor"
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index c63d058..6249292 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -33,10 +33,12 @@
 #define FAN_MOVE_SELF 0x00000800
 #define FAN_OPEN_EXEC 0x00001000
 #define FAN_Q_OVERFLOW 0x00004000
+#define FAN_FS_ERROR 0x00008000
 #define FAN_OPEN_PERM 0x00010000
 #define FAN_ACCESS_PERM 0x00020000
 #define FAN_OPEN_EXEC_PERM 0x00040000
 #define FAN_EVENT_ON_CHILD 0x08000000
+#define FAN_RENAME 0x10000000
 #define FAN_ONDIR 0x40000000
 #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
 #define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO)
@@ -49,11 +51,14 @@
 #define FAN_UNLIMITED_QUEUE 0x00000010
 #define FAN_UNLIMITED_MARKS 0x00000020
 #define FAN_ENABLE_AUDIT 0x00000040
+#define FAN_REPORT_PIDFD 0x00000080
 #define FAN_REPORT_TID 0x00000100
 #define FAN_REPORT_FID 0x00000200
 #define FAN_REPORT_DIR_FID 0x00000400
 #define FAN_REPORT_NAME 0x00000800
+#define FAN_REPORT_TARGET_FID 0x00001000
 #define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)
+#define FAN_REPORT_DFID_NAME_TARGET (FAN_REPORT_DFID_NAME | FAN_REPORT_FID | FAN_REPORT_TARGET_FID)
 #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
 #define FAN_MARK_ADD 0x00000001
 #define FAN_MARK_REMOVE 0x00000002
@@ -82,6 +87,10 @@
 #define FAN_EVENT_INFO_TYPE_FID 1
 #define FAN_EVENT_INFO_TYPE_DFID_NAME 2
 #define FAN_EVENT_INFO_TYPE_DFID 3
+#define FAN_EVENT_INFO_TYPE_PIDFD 4
+#define FAN_EVENT_INFO_TYPE_ERROR 5
+#define FAN_EVENT_INFO_TYPE_OLD_DFID_NAME 10
+#define FAN_EVENT_INFO_TYPE_NEW_DFID_NAME 12
 struct fanotify_event_info_header {
   __u8 info_type;
   __u8 pad;
@@ -92,6 +101,15 @@
   __kernel_fsid_t fsid;
   unsigned char handle[0];
 };
+struct fanotify_event_info_pidfd {
+  struct fanotify_event_info_header hdr;
+  __s32 pidfd;
+};
+struct fanotify_event_info_error {
+  struct fanotify_event_info_header hdr;
+  __s32 error;
+  __u32 error_count;
+};
 struct fanotify_response {
   __s32 fd;
   __u32 response;
@@ -100,6 +118,8 @@
 #define FAN_DENY 0x02
 #define FAN_AUDIT 0x10
 #define FAN_NOFD - 1
+#define FAN_NOPIDFD FAN_NOFD
+#define FAN_EPIDFD - 2
 #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
 #define FAN_EVENT_NEXT(meta,len) ((len) -= (meta)->event_len, (struct fanotify_event_metadata *) (((char *) (meta)) + (meta)->event_len))
 #define FAN_EVENT_OK(meta,len) ((long) (len) >= (long) FAN_EVENT_METADATA_LEN && (long) (meta)->event_len >= (long) FAN_EVENT_METADATA_LEN && (long) (meta)->event_len <= (long) (len))
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 0601768..3bb4183 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -129,6 +129,7 @@
 #define BLKSECDISCARD _IO(0x12, 125)
 #define BLKROTATIONAL _IO(0x12, 126)
 #define BLKZEROOUT _IO(0x12, 127)
+#define BLKGETDISKSEQ _IOR(0x12, 128, __u64)
 #define BMAP_IOCTL 1
 #define FIBMAP _IO(0x00, 1)
 #define FIGETBSZ _IO(0x00, 2)
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index efb5424..144e960 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -20,7 +20,7 @@
 #define _LINUX_FUSE_H
 #include <stdint.h>
 #define FUSE_KERNEL_VERSION 7
-#define FUSE_KERNEL_MINOR_VERSION 33
+#define FUSE_KERNEL_MINOR_VERSION 36
 #define FUSE_ROOT_ID 1
 struct fuse_attr {
   uint64_t ino;
@@ -75,6 +75,7 @@
 #define FOPEN_NONSEEKABLE (1 << 2)
 #define FOPEN_CACHE_DIR (1 << 3)
 #define FOPEN_STREAM (1 << 4)
+#define FOPEN_NOFLUSH (1 << 5)
 #define FUSE_ASYNC_READ (1 << 0)
 #define FUSE_POSIX_LOCKS (1 << 1)
 #define FUSE_FILE_OPS (1 << 2)
@@ -104,7 +105,16 @@
 #define FUSE_MAP_ALIGNMENT (1 << 26)
 #define FUSE_SUBMOUNTS (1 << 27)
 #define FUSE_HANDLE_KILLPRIV_V2 (1 << 28)
+#define FUSE_SETXATTR_EXT (1 << 29)
+#define FUSE_INIT_EXT (1 << 30)
+#define FUSE_INIT_RESERVED (1 << 31)
+#define FUSE_SECURITY_CTX (1ULL << 32)
+#define FUSE_HAS_INODE_DAX (1ULL << 33)
+#if FUSE_KERNEL_VERSION > 7 || FUSE_KERNEL_VERSION == 7 && FUSE_KERNEL_MINOR_VERSION >= 36
+#define FUSE_PASSTHROUGH (1ULL << 63)
+#else
 #define FUSE_PASSTHROUGH (1 << 31)
+#endif
 #define CUSE_UNRESTRICTED_IOCTL (1 << 0)
 #define FUSE_RELEASE_FLUSH (1 << 0)
 #define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
@@ -125,7 +135,9 @@
 #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0)
 #define FUSE_FSYNC_FDATASYNC (1 << 0)
 #define FUSE_ATTR_SUBMOUNT (1 << 0)
+#define FUSE_ATTR_DAX (1 << 1)
 #define FUSE_OPEN_KILL_SUIDGID (1 << 0)
+#define FUSE_SETXATTR_ACL_KILL_SGID (1 << 0)
 enum fuse_opcode {
   FUSE_LOOKUP = 1,
   FUSE_FORGET = 2,
@@ -174,6 +186,7 @@
   FUSE_COPY_FILE_RANGE = 47,
   FUSE_SETUPMAPPING = 48,
   FUSE_REMOVEMAPPING = 49,
+  FUSE_SYNCFS = 50,
   FUSE_CANONICAL_PATH = 2016,
   CUSE_INIT = 4096,
   CUSE_INIT_BSWAP_RESERVED = 1048576,
@@ -321,9 +334,12 @@
   uint32_t fsync_flags;
   uint32_t padding;
 };
+#define FUSE_COMPAT_SETXATTR_IN_SIZE 8
 struct fuse_setxattr_in {
   uint32_t size;
   uint32_t flags;
+  uint32_t setxattr_flags;
+  uint32_t padding;
 };
 struct fuse_getxattr_in {
   uint32_t size;
@@ -352,6 +368,8 @@
   uint32_t minor;
   uint32_t max_readahead;
   uint32_t flags;
+  uint32_t flags2;
+  uint32_t unused[11];
 };
 #define FUSE_COMPAT_INIT_OUT_SIZE 8
 #define FUSE_COMPAT_22_INIT_OUT_SIZE 24
@@ -366,7 +384,8 @@
   uint32_t time_gran;
   uint16_t max_pages;
   uint16_t map_alignment;
-  uint32_t unused[8];
+  uint32_t flags2;
+  uint32_t unused[7];
 };
 #define CUSE_INIT_INFO_MAX 4096
 struct cuse_init_in {
@@ -445,11 +464,6 @@
   uint32_t pid;
   uint32_t padding;
 };
-struct fuse_passthrough_out {
-  uint32_t fd;
-  uint32_t len;
-  void * vec;
-};
 struct fuse_out_header {
   uint32_t len;
   int32_t error;
@@ -462,8 +476,9 @@
   uint32_t type;
   char name[];
 };
+#define FUSE_REC_ALIGN(x) (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))
 #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
-#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1))
+#define FUSE_DIRENT_ALIGN(x) FUSE_REC_ALIGN(x)
 #define FUSE_DIRENT_SIZE(d) FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
 struct fuse_direntplus {
   struct fuse_entry_out entry_out;
@@ -510,7 +525,7 @@
 };
 #define FUSE_DEV_IOC_MAGIC 229
 #define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t)
-#define FUSE_DEV_IOC_PASSTHROUGH_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 127, struct fuse_passthrough_out)
+#define FUSE_DEV_IOC_PASSTHROUGH_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 126, uint32_t)
 struct fuse_lseek_in {
   uint64_t fh;
   uint64_t offset;
@@ -546,4 +561,15 @@
   uint64_t len;
 };
 #define FUSE_REMOVEMAPPING_MAX_ENTRY (PAGE_SIZE / sizeof(struct fuse_removemapping_one))
+struct fuse_syncfs_in {
+  uint64_t padding;
+};
+struct fuse_secctx {
+  uint32_t size;
+  uint32_t padding;
+};
+struct fuse_secctx_header {
+  uint32_t size;
+  uint32_t nr_secctx;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/futex.h b/libc/kernel/uapi/linux/futex.h
index 6176f38..c80b90c 100644
--- a/libc/kernel/uapi/linux/futex.h
+++ b/libc/kernel/uapi/linux/futex.h
@@ -33,6 +33,7 @@
 #define FUTEX_WAKE_BITSET 10
 #define FUTEX_WAIT_REQUEUE_PI 11
 #define FUTEX_CMP_REQUEUE_PI 12
+#define FUTEX_LOCK_PI2 13
 #define FUTEX_PRIVATE_FLAG 128
 #define FUTEX_CLOCK_REALTIME 256
 #define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
@@ -42,12 +43,21 @@
 #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
 #define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
 #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_LOCK_PI2_PRIVATE (FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG)
 #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
 #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
 #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
 #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
 #define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
 #define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | FUTEX_PRIVATE_FLAG)
+#define FUTEX_32 2
+#define FUTEX_WAITV_MAX 128
+struct futex_waitv {
+  __u64 val;
+  __u64 uaddr;
+  __u32 flags;
+  __u32 __reserved;
+};
 struct robust_list {
   struct robust_list __user * next;
 };
diff --git a/libc/kernel/uapi/linux/hyperv.h b/libc/kernel/uapi/linux/hyperv.h
index daa8fc7..4790bbf 100644
--- a/libc/kernel/uapi/linux/hyperv.h
+++ b/libc/kernel/uapi/linux/hyperv.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef _UAPI_HYPERV_H
 #define _UAPI_HYPERV_H
-#include <linux/uuid.h>
+#include <linux/types.h>
 #define UTIL_FW_MINOR 0
 #define UTIL_WS2K8_FW_MAJOR 1
 #define UTIL_WS2K8_FW_VERSION (UTIL_WS2K8_FW_MAJOR << 16 | UTIL_FW_MINOR)
diff --git a/libc/kernel/uapi/linux/icmp.h b/libc/kernel/uapi/linux/icmp.h
index 5892d12..8847a48 100644
--- a/libc/kernel/uapi/linux/icmp.h
+++ b/libc/kernel/uapi/linux/icmp.h
@@ -20,6 +20,8 @@
 #define _UAPI_LINUX_ICMP_H
 #include <linux/types.h>
 #include <asm/byteorder.h>
+#include <linux/if.h>
+#include <linux/in6.h>
 #define ICMP_ECHOREPLY 0
 #define ICMP_DEST_UNREACH 3
 #define ICMP_SOURCE_QUENCH 4
@@ -57,6 +59,20 @@
 #define ICMP_REDIR_HOSTTOS 3
 #define ICMP_EXC_TTL 0
 #define ICMP_EXC_FRAGTIME 1
+#define ICMP_EXT_ECHO 42
+#define ICMP_EXT_ECHOREPLY 43
+#define ICMP_EXT_CODE_MAL_QUERY 1
+#define ICMP_EXT_CODE_NO_IF 2
+#define ICMP_EXT_CODE_NO_TABLE_ENT 3
+#define ICMP_EXT_CODE_MULT_IFS 4
+#define ICMP_EXT_ECHOREPLY_ACTIVE (1 << 2)
+#define ICMP_EXT_ECHOREPLY_IPV4 (1 << 1)
+#define ICMP_EXT_ECHOREPLY_IPV6 1
+#define ICMP_EXT_ECHO_CTYPE_NAME 1
+#define ICMP_EXT_ECHO_CTYPE_INDEX 2
+#define ICMP_EXT_ECHO_CTYPE_ADDR 3
+#define ICMP_AFI_IP 1
+#define ICMP_AFI_IP6 2
 struct icmphdr {
   __u8 type;
   __u8 code;
@@ -94,4 +110,23 @@
   __u8 class_num;
   __u8 class_type;
 };
+struct icmp_ext_echo_ctype3_hdr {
+  __be16 afi;
+  __u8 addrlen;
+  __u8 reserved;
+};
+struct icmp_ext_echo_iio {
+  struct icmp_extobj_hdr extobj_hdr;
+  union {
+    char name[IFNAMSIZ];
+    __be32 ifindex;
+    struct {
+      struct icmp_ext_echo_ctype3_hdr ctype3_hdr;
+      union {
+        __be32 ipv4_addr;
+        struct in6_addr ipv6_addr;
+      } ip_addr;
+    } addr;
+  } ident;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/icmpv6.h b/libc/kernel/uapi/linux/icmpv6.h
index e23fbb4..5285698 100644
--- a/libc/kernel/uapi/linux/icmpv6.h
+++ b/libc/kernel/uapi/linux/icmpv6.h
@@ -107,6 +107,8 @@
 #define ICMPV6_UNK_NEXTHDR 1
 #define ICMPV6_UNK_OPTION 2
 #define ICMPV6_HDR_INCOMP 3
+#define ICMPV6_EXT_ECHO_REQUEST 160
+#define ICMPV6_EXT_ECHO_REPLY 161
 #define ICMPV6_FILTER 1
 #define ICMPV6_FILTER_BLOCK 1
 #define ICMPV6_FILTER_PASS 2
diff --git a/libc/kernel/uapi/linux/idxd.h b/libc/kernel/uapi/linux/idxd.h
index 4f1282e..ad9ed48 100644
--- a/libc/kernel/uapi/linux/idxd.h
+++ b/libc/kernel/uapi/linux/idxd.h
@@ -19,6 +19,28 @@
 #ifndef _USR_IDXD_H_
 #define _USR_IDXD_H_
 #include <stdint.h>
+enum idxd_scmd_stat {
+  IDXD_SCMD_DEV_ENABLED = 0x80000010,
+  IDXD_SCMD_DEV_NOT_ENABLED = 0x80000020,
+  IDXD_SCMD_WQ_ENABLED = 0x80000021,
+  IDXD_SCMD_DEV_DMA_ERR = 0x80020000,
+  IDXD_SCMD_WQ_NO_GRP = 0x80030000,
+  IDXD_SCMD_WQ_NO_NAME = 0x80040000,
+  IDXD_SCMD_WQ_NO_SVM = 0x80050000,
+  IDXD_SCMD_WQ_NO_THRESH = 0x80060000,
+  IDXD_SCMD_WQ_PORTAL_ERR = 0x80070000,
+  IDXD_SCMD_WQ_RES_ALLOC_ERR = 0x80080000,
+  IDXD_SCMD_PERCPU_ERR = 0x80090000,
+  IDXD_SCMD_DMA_CHAN_ERR = 0x800a0000,
+  IDXD_SCMD_CDEV_ERR = 0x800b0000,
+  IDXD_SCMD_WQ_NO_SWQ_SUPPORT = 0x800c0000,
+  IDXD_SCMD_WQ_NONE_CONFIGURED = 0x800d0000,
+  IDXD_SCMD_WQ_NO_SIZE = 0x800e0000,
+  IDXD_SCMD_WQ_NO_PRIV = 0x800f0000,
+  IDXD_SCMD_WQ_IRQ_ERR = 0x80100000,
+};
+#define IDXD_SCMD_SOFTERR_MASK 0x80000000
+#define IDXD_SCMD_SOFTERR_SHIFT 16
 #define IDXD_OP_FLAG_FENCE 0x0001
 #define IDXD_OP_FLAG_BOF 0x0002
 #define IDXD_OP_FLAG_CRAV 0x0004
diff --git a/libc/kernel/uapi/linux/if_arp.h b/libc/kernel/uapi/linux/if_arp.h
index eda888f..1cd23ef 100644
--- a/libc/kernel/uapi/linux/if_arp.h
+++ b/libc/kernel/uapi/linux/if_arp.h
@@ -44,6 +44,7 @@
 #define ARPHRD_X25 271
 #define ARPHRD_HWX25 272
 #define ARPHRD_CAN 280
+#define ARPHRD_MCTP 290
 #define ARPHRD_PPP 512
 #define ARPHRD_CISCO 513
 #define ARPHRD_HDLC ARPHRD_CISCO
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 570c09e..2054fb3 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -405,9 +405,11 @@
 };
 #define BRIDGE_VLANDB_DUMP_MAX (__BRIDGE_VLANDB_DUMP_MAX - 1)
 #define BRIDGE_VLANDB_DUMPF_STATS (1 << 0)
+#define BRIDGE_VLANDB_DUMPF_GLOBAL (1 << 1)
 enum {
   BRIDGE_VLANDB_UNSPEC,
   BRIDGE_VLANDB_ENTRY,
+  BRIDGE_VLANDB_GLOBAL_OPTIONS,
   __BRIDGE_VLANDB_MAX,
 };
 #define BRIDGE_VLANDB_MAX (__BRIDGE_VLANDB_MAX - 1)
@@ -418,6 +420,7 @@
   BRIDGE_VLANDB_ENTRY_STATE,
   BRIDGE_VLANDB_ENTRY_TUNNEL_INFO,
   BRIDGE_VLANDB_ENTRY_STATS,
+  BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
   __BRIDGE_VLANDB_ENTRY_MAX,
 };
 #define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
@@ -439,6 +442,28 @@
 };
 #define BRIDGE_VLANDB_STATS_MAX (__BRIDGE_VLANDB_STATS_MAX - 1)
 enum {
+  BRIDGE_VLANDB_GOPTS_UNSPEC,
+  BRIDGE_VLANDB_GOPTS_ID,
+  BRIDGE_VLANDB_GOPTS_RANGE,
+  BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING,
+  BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION,
+  BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
+  BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
+  BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
+  BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL,
+  BRIDGE_VLANDB_GOPTS_PAD,
+  BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL,
+  BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL,
+  BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL,
+  BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
+  BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
+  BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
+  BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS,
+  BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE,
+  __BRIDGE_VLANDB_GOPTS_MAX
+};
+#define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1)
+enum {
   MDBA_UNSPEC,
   MDBA_MDB,
   MDBA_ROUTER,
@@ -496,6 +521,9 @@
   MDBA_ROUTER_PATTR_UNSPEC,
   MDBA_ROUTER_PATTR_TIMER,
   MDBA_ROUTER_PATTR_TYPE,
+  MDBA_ROUTER_PATTR_INET_TIMER,
+  MDBA_ROUTER_PATTR_INET6_TIMER,
+  MDBA_ROUTER_PATTR_VID,
   __MDBA_ROUTER_PATTR_MAX
 };
 #define MDBA_ROUTER_PATTR_MAX (__MDBA_ROUTER_PATTR_MAX - 1)
@@ -570,10 +598,23 @@
 };
 enum br_boolopt_id {
   BR_BOOLOPT_NO_LL_LEARN,
+  BR_BOOLOPT_MCAST_VLAN_SNOOPING,
   BR_BOOLOPT_MAX
 };
 struct br_boolopt_multi {
   __u32 optval;
   __u32 optmask;
 };
+enum {
+  BRIDGE_QUERIER_UNSPEC,
+  BRIDGE_QUERIER_IP_ADDRESS,
+  BRIDGE_QUERIER_IP_PORT,
+  BRIDGE_QUERIER_IP_OTHER_TIMER,
+  BRIDGE_QUERIER_PAD,
+  BRIDGE_QUERIER_IPV6_ADDRESS,
+  BRIDGE_QUERIER_IPV6_PORT,
+  BRIDGE_QUERIER_IPV6_OTHER_TIMER,
+  __BRIDGE_QUERIER_MAX
+};
+#define BRIDGE_QUERIER_MAX (__BRIDGE_QUERIER_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index 8405653..1f7f8f2 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -67,6 +67,7 @@
 #define ETH_P_LINK_CTL 0x886c
 #define ETH_P_ATMFATE 0x8884
 #define ETH_P_PAE 0x888E
+#define ETH_P_REALTEK 0x8899
 #define ETH_P_AOE 0x88A2
 #define ETH_P_8021AD 0x88A8
 #define ETH_P_802_EX1 0x88B5
@@ -123,6 +124,7 @@
 #define ETH_P_CAIF 0x00F7
 #define ETH_P_XDSA 0x00F8
 #define ETH_P_MAP 0x00F9
+#define ETH_P_MCTP 0x00FA
 #ifndef __UAPI_DEF_ETHHDR
 #define __UAPI_DEF_ETHHDR 1
 #endif
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 2a5ba5a..7e413ae 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -148,6 +148,9 @@
   IFLA_ALT_IFNAME,
   IFLA_PERM_ADDRESS,
   IFLA_PROTO_DOWN_REASON,
+  IFLA_PARENT_DEV_NAME,
+  IFLA_PARENT_DEV_BUS_NAME,
+  IFLA_GRO_MAX_SIZE,
   __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
@@ -176,6 +179,7 @@
   IFLA_INET6_ICMP6STATS,
   IFLA_INET6_TOKEN,
   IFLA_INET6_ADDR_GEN_MODE,
+  IFLA_INET6_RA_MTU,
   __IFLA_INET6_MAX
 };
 #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
@@ -233,6 +237,7 @@
   IFLA_BR_MCAST_MLD_VERSION,
   IFLA_BR_VLAN_STATS_PER_PORT,
   IFLA_BR_MULTI_BOOLOPT,
+  IFLA_BR_MCAST_QUERIER_STATE,
   __IFLA_BR_MAX,
 };
 #define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
@@ -354,6 +359,7 @@
   MACVLAN_MACADDR_SET,
 };
 #define MACVLAN_FLAG_NOPROMISC 1
+#define MACVLAN_FLAG_NODST 2
 enum {
   IFLA_VRF_UNSPEC,
   IFLA_VRF_TABLE,
@@ -550,6 +556,8 @@
   IFLA_BOND_AD_ACTOR_SYSTEM,
   IFLA_BOND_TLB_DYNAMIC_LB,
   IFLA_BOND_PEER_NOTIF_DELAY,
+  IFLA_BOND_AD_LACP_ACTIVE,
+  IFLA_BOND_MISSED_MAX,
   __IFLA_BOND_MAX,
 };
 #define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
@@ -835,6 +843,8 @@
 #define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1)
 #define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2)
 #define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3)
+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV5 (1U << 4)
+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV5 (1U << 5)
 enum {
   IFLA_RMNET_UNSPEC,
   IFLA_RMNET_MUX_ID,
@@ -846,4 +856,10 @@
   __u32 flags;
   __u32 mask;
 };
+enum {
+  IFLA_MCTP_UNSPEC,
+  IFLA_MCTP_NET,
+  __IFLA_MCTP_MAX,
+};
+#define IFLA_MCTP_MAX (__IFLA_MCTP_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/iio/buffer.h
similarity index 80%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/iio/buffer.h
index bb45c3d..ba2f5e3 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/iio/buffer.h
@@ -16,14 +16,7 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
-#include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
-};
+#ifndef _UAPI_IIO_BUFFER_H_
+#define _UAPI_IIO_BUFFER_H_
+#define IIO_BUFFER_GET_FD_IOCTL _IOWR('i', 0x91, int)
 #endif
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index e5437ca..d4060e7 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -155,21 +155,32 @@
 #define IP_MSFILTER_SIZE(numsrc) (sizeof(struct ip_msfilter) - sizeof(__u32) + (numsrc) * sizeof(__u32))
 struct group_req {
   __u32 gr_interface;
-  struct sockaddr_storage gr_group;
+  struct __kernel_sockaddr_storage gr_group;
 };
 struct group_source_req {
   __u32 gsr_interface;
-  struct sockaddr_storage gsr_group;
-  struct sockaddr_storage gsr_source;
+  struct __kernel_sockaddr_storage gsr_group;
+  struct __kernel_sockaddr_storage gsr_source;
 };
 struct group_filter {
-  __u32 gf_interface;
-  struct sockaddr_storage gf_group;
-  __u32 gf_fmode;
-  __u32 gf_numsrc;
-  struct sockaddr_storage gf_slist[1];
+  union {
+    struct {
+      __u32 gf_interface_aux;
+      struct __kernel_sockaddr_storage gf_group_aux;
+      __u32 gf_fmode_aux;
+      __u32 gf_numsrc_aux;
+      struct __kernel_sockaddr_storage gf_slist[1];
+    };
+    struct {
+      __u32 gf_interface;
+      struct __kernel_sockaddr_storage gf_group;
+      __u32 gf_fmode;
+      __u32 gf_numsrc;
+      struct __kernel_sockaddr_storage gf_slist_flex[];
+    };
+  };
 };
-#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) + (numsrc) * sizeof(struct sockaddr_storage))
+#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
 #endif
 #if __UAPI_DEF_IN_PKTINFO
 struct in_pktinfo {
@@ -214,6 +225,7 @@
 #define INADDR_ANY ((unsigned long int) 0x00000000)
 #define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
 #define INADDR_NONE ((unsigned long int) 0xffffffff)
+#define INADDR_DUMMY ((unsigned long int) 0xc0000008)
 #define IN_LOOPBACKNET 127
 #define INADDR_LOOPBACK 0x7f000001
 #define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
diff --git a/libc/kernel/uapi/linux/in6.h b/libc/kernel/uapi/linux/in6.h
index 8dd3238..49efe3c 100644
--- a/libc/kernel/uapi/linux/in6.h
+++ b/libc/kernel/uapi/linux/in6.h
@@ -105,6 +105,7 @@
 #define IPV6_TLV_PADN 1
 #define IPV6_TLV_ROUTERALERT 5
 #define IPV6_TLV_CALIPSO 7
+#define IPV6_TLV_IOAM 49
 #define IPV6_TLV_JUMBO 194
 #define IPV6_TLV_HAO 201
 #if __UAPI_DEF_IPV6_OPTIONS
diff --git a/libc/kernel/uapi/linux/incrementalfs.h b/libc/kernel/uapi/linux/incrementalfs.h
index 622a998..0804cc2 100644
--- a/libc/kernel/uapi/linux/incrementalfs.h
+++ b/libc/kernel/uapi/linux/incrementalfs.h
@@ -171,6 +171,8 @@
   __u64 time_us_out;
   __u32 page_out;
   __u32 errno_out;
-  __u64 reserved;
+  __u32 uid_out;
+  __u32 reserved1;
+  __u64 reserved2;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 732e9b7..34cd23c 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -248,7 +248,8 @@
 #define KEY_PAUSECD 201
 #define KEY_PROG3 202
 #define KEY_PROG4 203
-#define KEY_DASHBOARD 204
+#define KEY_ALL_APPLICATIONS 204
+#define KEY_DASHBOARD KEY_ALL_APPLICATIONS
 #define KEY_SUSPEND 205
 #define KEY_CLOSE 206
 #define KEY_PLAY 207
@@ -548,6 +549,8 @@
 #define KEY_VOICECOMMAND 0x246
 #define KEY_ASSISTANT 0x247
 #define KEY_KBD_LAYOUT_NEXT 0x248
+#define KEY_EMOJI_PICKER 0x249
+#define KEY_DICTATE 0x24a
 #define KEY_BRIGHTNESS_MIN 0x250
 #define KEY_BRIGHTNESS_MAX 0x251
 #define KEY_KBDINPUTASSIST_PREV 0x260
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index fa59d39..96944f8 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -50,19 +50,19 @@
     __u32 splice_flags;
     __u32 rename_flags;
     __u32 unlink_flags;
+    __u32 hardlink_flags;
   };
   __u64 user_data;
   union {
-    struct {
-      union {
-        __u16 buf_index;
-        __u16 buf_group;
-      } __attribute__((packed));
-      __u16 personality;
-      __s32 splice_fd_in;
-    };
-    __u64 __pad2[3];
+    __u16 buf_index;
+    __u16 buf_group;
+  } __attribute__((packed));
+  __u16 personality;
+  union {
+    __s32 splice_fd_in;
+    __u32 file_index;
   };
+  __u64 __pad2[2];
 };
 enum {
   IOSQE_FIXED_FILE_BIT,
@@ -71,6 +71,7 @@
   IOSQE_IO_HARDLINK_BIT,
   IOSQE_ASYNC_BIT,
   IOSQE_BUFFER_SELECT_BIT,
+  IOSQE_CQE_SKIP_SUCCESS_BIT,
 };
 #define IOSQE_FIXED_FILE (1U << IOSQE_FIXED_FILE_BIT)
 #define IOSQE_IO_DRAIN (1U << IOSQE_IO_DRAIN_BIT)
@@ -78,6 +79,7 @@
 #define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT)
 #define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT)
 #define IOSQE_BUFFER_SELECT (1U << IOSQE_BUFFER_SELECT_BIT)
+#define IOSQE_CQE_SKIP_SUCCESS (1U << IOSQE_CQE_SKIP_SUCCESS_BIT)
 #define IORING_SETUP_IOPOLL (1U << 0)
 #define IORING_SETUP_SQPOLL (1U << 1)
 #define IORING_SETUP_SQ_AFF (1U << 2)
@@ -123,18 +125,31 @@
   IORING_OP_SHUTDOWN,
   IORING_OP_RENAMEAT,
   IORING_OP_UNLINKAT,
+  IORING_OP_MKDIRAT,
+  IORING_OP_SYMLINKAT,
+  IORING_OP_LINKAT,
   IORING_OP_LAST,
 };
 #define IORING_FSYNC_DATASYNC (1U << 0)
 #define IORING_TIMEOUT_ABS (1U << 0)
 #define IORING_TIMEOUT_UPDATE (1U << 1)
+#define IORING_TIMEOUT_BOOTTIME (1U << 2)
+#define IORING_TIMEOUT_REALTIME (1U << 3)
+#define IORING_LINK_TIMEOUT_UPDATE (1U << 4)
+#define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5)
+#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)
+#define IORING_POLL_ADD_MULTI (1U << 0)
+#define IORING_POLL_UPDATE_EVENTS (1U << 1)
+#define IORING_POLL_UPDATE_USER_DATA (1U << 2)
 struct io_uring_cqe {
   __u64 user_data;
   __s32 res;
   __u32 flags;
 };
 #define IORING_CQE_F_BUFFER (1U << 0)
+#define IORING_CQE_F_MORE (1U << 1)
 enum {
   IORING_CQE_BUFFER_SHIFT = 16,
 };
@@ -192,6 +207,8 @@
 #define IORING_FEAT_SQPOLL_NONFIXED (1U << 7)
 #define IORING_FEAT_EXT_ARG (1U << 8)
 #define IORING_FEAT_NATIVE_WORKERS (1U << 9)
+#define IORING_FEAT_RSRC_TAGS (1U << 10)
+#define IORING_FEAT_CQE_SKIP (1U << 11)
 enum {
   IORING_REGISTER_BUFFERS = 0,
   IORING_UNREGISTER_BUFFERS = 1,
@@ -206,18 +223,44 @@
   IORING_UNREGISTER_PERSONALITY = 10,
   IORING_REGISTER_RESTRICTIONS = 11,
   IORING_REGISTER_ENABLE_RINGS = 12,
+  IORING_REGISTER_FILES2 = 13,
+  IORING_REGISTER_FILES_UPDATE2 = 14,
+  IORING_REGISTER_BUFFERS2 = 15,
+  IORING_REGISTER_BUFFERS_UPDATE = 16,
+  IORING_REGISTER_IOWQ_AFF = 17,
+  IORING_UNREGISTER_IOWQ_AFF = 18,
+  IORING_REGISTER_IOWQ_MAX_WORKERS = 19,
   IORING_REGISTER_LAST
 };
+enum {
+  IO_WQ_BOUND,
+  IO_WQ_UNBOUND,
+};
 struct io_uring_files_update {
   __u32 offset;
   __u32 resv;
   __aligned_u64 fds;
 };
+struct io_uring_rsrc_register {
+  __u32 nr;
+  __u32 resv;
+  __u64 resv2;
+  __aligned_u64 data;
+  __aligned_u64 tags;
+};
 struct io_uring_rsrc_update {
   __u32 offset;
   __u32 resv;
   __aligned_u64 data;
 };
+struct io_uring_rsrc_update2 {
+  __u32 offset;
+  __u32 resv;
+  __aligned_u64 data;
+  __aligned_u64 tags;
+  __u32 nr;
+  __u32 resv2;
+};
 #define IORING_REGISTER_FILES_SKIP (- 2)
 #define IO_URING_OP_SUPPORTED (1U << 0)
 struct io_uring_probe_op {
diff --git a/libc/kernel/uapi/linux/ioam6.h b/libc/kernel/uapi/linux/ioam6.h
new file mode 100644
index 0000000..e32c8e9
--- /dev/null
+++ b/libc/kernel/uapi/linux/ioam6.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_IOAM6_H
+#define _UAPI_LINUX_IOAM6_H
+#include <asm/byteorder.h>
+#include <linux/types.h>
+#define IOAM6_U16_UNAVAILABLE U16_MAX
+#define IOAM6_U32_UNAVAILABLE U32_MAX
+#define IOAM6_U64_UNAVAILABLE U64_MAX
+#define IOAM6_DEFAULT_ID (IOAM6_U32_UNAVAILABLE >> 8)
+#define IOAM6_DEFAULT_ID_WIDE (IOAM6_U64_UNAVAILABLE >> 8)
+#define IOAM6_DEFAULT_IF_ID IOAM6_U16_UNAVAILABLE
+#define IOAM6_DEFAULT_IF_ID_WIDE IOAM6_U32_UNAVAILABLE
+struct ioam6_hdr {
+  __u8 opt_type;
+  __u8 opt_len;
+  __u8 : 8;
+#define IOAM6_TYPE_PREALLOC 0
+  __u8 type;
+} __attribute__((packed));
+struct ioam6_trace_hdr {
+  __be16 namespace_id;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  __u8 : 1, : 1, overflow : 1, nodelen : 5;
+  __u8 remlen : 7, : 1;
+  union {
+    __be32 type_be32;
+    struct {
+      __u32 bit7 : 1, bit6 : 1, bit5 : 1, bit4 : 1, bit3 : 1, bit2 : 1, bit1 : 1, bit0 : 1, bit15 : 1, bit14 : 1, bit13 : 1, bit12 : 1, bit11 : 1, bit10 : 1, bit9 : 1, bit8 : 1, bit23 : 1, bit22 : 1, bit21 : 1, bit20 : 1, bit19 : 1, bit18 : 1, bit17 : 1, bit16 : 1, : 8;
+    } type;
+  };
+#elif defined(__BIG_ENDIAN_BITFIELD)
+  __u8 nodelen : 5, overflow : 1, : 1, : 1;
+  __u8 : 1, remlen : 7;
+  union {
+    __be32 type_be32;
+    struct {
+      __u32 bit0 : 1, bit1 : 1, bit2 : 1, bit3 : 1, bit4 : 1, bit5 : 1, bit6 : 1, bit7 : 1, bit8 : 1, bit9 : 1, bit10 : 1, bit11 : 1, bit12 : 1, bit13 : 1, bit14 : 1, bit15 : 1, bit16 : 1, bit17 : 1, bit18 : 1, bit19 : 1, bit20 : 1, bit21 : 1, bit22 : 1, bit23 : 1, : 8;
+    } type;
+  };
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+#define IOAM6_TRACE_DATA_SIZE_MAX 244
+  __u8 data[0];
+} __attribute__((packed));
+#endif
diff --git a/libc/kernel/uapi/linux/ioam6_genl.h b/libc/kernel/uapi/linux/ioam6_genl.h
new file mode 100644
index 0000000..1d00c47
--- /dev/null
+++ b/libc/kernel/uapi/linux/ioam6_genl.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_IOAM6_GENL_H
+#define _UAPI_LINUX_IOAM6_GENL_H
+#define IOAM6_GENL_NAME "IOAM6"
+#define IOAM6_GENL_VERSION 0x1
+enum {
+  IOAM6_ATTR_UNSPEC,
+  IOAM6_ATTR_NS_ID,
+  IOAM6_ATTR_NS_DATA,
+  IOAM6_ATTR_NS_DATA_WIDE,
+#define IOAM6_MAX_SCHEMA_DATA_LEN (255 * 4)
+  IOAM6_ATTR_SC_ID,
+  IOAM6_ATTR_SC_DATA,
+  IOAM6_ATTR_SC_NONE,
+  IOAM6_ATTR_PAD,
+  __IOAM6_ATTR_MAX,
+};
+#define IOAM6_ATTR_MAX (__IOAM6_ATTR_MAX - 1)
+enum {
+  IOAM6_CMD_UNSPEC,
+  IOAM6_CMD_ADD_NAMESPACE,
+  IOAM6_CMD_DEL_NAMESPACE,
+  IOAM6_CMD_DUMP_NAMESPACES,
+  IOAM6_CMD_ADD_SCHEMA,
+  IOAM6_CMD_DEL_SCHEMA,
+  IOAM6_CMD_DUMP_SCHEMAS,
+  IOAM6_CMD_NS_SET_SCHEMA,
+  __IOAM6_CMD_MAX,
+};
+#define IOAM6_CMD_MAX (__IOAM6_CMD_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/ioam6_iptunnel.h
similarity index 64%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/ioam6_iptunnel.h
index bb45c3d..7426225 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/ioam6_iptunnel.h
@@ -16,14 +16,23 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
-#include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
+#ifndef _UAPI_LINUX_IOAM6_IPTUNNEL_H
+#define _UAPI_LINUX_IOAM6_IPTUNNEL_H
+enum {
+  __IOAM6_IPTUNNEL_MODE_MIN,
+  IOAM6_IPTUNNEL_MODE_INLINE,
+  IOAM6_IPTUNNEL_MODE_ENCAP,
+  IOAM6_IPTUNNEL_MODE_AUTO,
+  __IOAM6_IPTUNNEL_MODE_MAX,
 };
+#define IOAM6_IPTUNNEL_MODE_MIN (__IOAM6_IPTUNNEL_MODE_MIN + 1)
+#define IOAM6_IPTUNNEL_MODE_MAX (__IOAM6_IPTUNNEL_MODE_MAX - 1)
+enum {
+  IOAM6_IPTUNNEL_UNSPEC,
+  IOAM6_IPTUNNEL_MODE,
+  IOAM6_IPTUNNEL_DST,
+  IOAM6_IPTUNNEL_TRACE,
+  __IOAM6_IPTUNNEL_MAX,
+};
+#define IOAM6_IPTUNNEL_MAX (__IOAM6_IPTUNNEL_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/iommu.h b/libc/kernel/uapi/linux/iommu.h
index 1802fb4..0a0af92 100644
--- a/libc/kernel/uapi/linux/iommu.h
+++ b/libc/kernel/uapi/linux/iommu.h
@@ -132,7 +132,8 @@
 #define IOMMU_SVA_VTD_GPASID_PWT (1 << 3)
 #define IOMMU_SVA_VTD_GPASID_EMTE (1 << 4)
 #define IOMMU_SVA_VTD_GPASID_CD (1 << 5)
-#define IOMMU_SVA_VTD_GPASID_LAST (1 << 6)
+#define IOMMU_SVA_VTD_GPASID_WPE (1 << 6)
+#define IOMMU_SVA_VTD_GPASID_LAST (1 << 7)
   __u64 flags;
   __u32 pat;
   __u32 emt;
diff --git a/libc/kernel/uapi/linux/ioprio.h b/libc/kernel/uapi/linux/ioprio.h
new file mode 100644
index 0000000..7a90d87
--- /dev/null
+++ b/libc/kernel/uapi/linux/ioprio.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_IOPRIO_H
+#define _UAPI_LINUX_IOPRIO_H
+#define IOPRIO_CLASS_SHIFT 13
+#define IOPRIO_CLASS_MASK 0x07
+#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,
+};
+#define IOPRIO_NR_LEVELS 8
+#define IOPRIO_BE_NR IOPRIO_NR_LEVELS
+enum {
+  IOPRIO_WHO_PROCESS = 1,
+  IOPRIO_WHO_PGRP,
+  IOPRIO_WHO_USER,
+};
+#define IOPRIO_NORM 4
+#define IOPRIO_BE_NORM IOPRIO_NORM
+#endif
diff --git a/libc/kernel/uapi/linux/ip.h b/libc/kernel/uapi/linux/ip.h
index 564fd8d..9571cac 100644
--- a/libc/kernel/uapi/linux/ip.h
+++ b/libc/kernel/uapi/linux/ip.h
@@ -146,6 +146,7 @@
   IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
   IPV4_DEVCONF_DROP_GRATUITOUS_ARP,
   IPV4_DEVCONF_BC_FORWARDING,
+  IPV4_DEVCONF_ARP_EVICT_NOCARRIER,
   __IPV4_DEVCONF_MAX
 };
 #define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1)
diff --git a/libc/kernel/uapi/linux/ipmi.h b/libc/kernel/uapi/linux/ipmi.h
index cf9928f..dd88f2f 100644
--- a/libc/kernel/uapi/linux/ipmi.h
+++ b/libc/kernel/uapi/linux/ipmi.h
@@ -40,6 +40,14 @@
   unsigned char slave_addr;
   unsigned char lun;
 };
+#define IPMI_IPMB_DIRECT_ADDR_TYPE 0x81
+struct ipmi_ipmb_direct_addr {
+  int addr_type;
+  short channel;
+  unsigned char slave_addr;
+  unsigned char rs_lun;
+  unsigned char rq_lun;
+};
 #define IPMI_LAN_ADDR_TYPE 0x04
 struct ipmi_lan_addr {
   int addr_type;
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index 438cacc..b3db9ce 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -144,6 +144,10 @@
   DEVCONF_NDISC_TCLASS,
   DEVCONF_RPL_SEG_ENABLED,
   DEVCONF_RA_DEFRTR_METRIC,
+  DEVCONF_IOAM6_ENABLED,
+  DEVCONF_IOAM6_ID,
+  DEVCONF_IOAM6_ID_WIDE,
+  DEVCONF_NDISC_EVICT_NOCARRIER,
   DEVCONF_MAX
 };
 #endif
diff --git a/libc/kernel/uapi/linux/ipx.h b/libc/kernel/uapi/linux/ipx.h
deleted file mode 100644
index d8a5424..0000000
--- a/libc/kernel/uapi/linux/ipx.h
+++ /dev/null
@@ -1,90 +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 _IPX_H_
-#define _IPX_H_
-#include <linux/libc-compat.h>
-#include <linux/types.h>
-#include <linux/sockios.h>
-#include <linux/socket.h>
-#define IPX_NODE_LEN 6
-#define IPX_MTU 576
-#if __UAPI_DEF_SOCKADDR_IPX
-struct sockaddr_ipx {
-  __kernel_sa_family_t sipx_family;
-  __be16 sipx_port;
-  __be32 sipx_network;
-  unsigned char sipx_node[IPX_NODE_LEN];
-  __u8 sipx_type;
-  unsigned char sipx_zero;
-};
-#endif
-#define sipx_special sipx_port
-#define sipx_action sipx_zero
-#define IPX_DLTITF 0
-#define IPX_CRTITF 1
-#if __UAPI_DEF_IPX_ROUTE_DEFINITION
-struct ipx_route_definition {
-  __be32 ipx_network;
-  __be32 ipx_router_network;
-  unsigned char ipx_router_node[IPX_NODE_LEN];
-};
-#endif
-#if __UAPI_DEF_IPX_INTERFACE_DEFINITION
-struct ipx_interface_definition {
-  __be32 ipx_network;
-  unsigned char ipx_device[16];
-  unsigned char ipx_dlink_type;
-#define IPX_FRAME_NONE 0
-#define IPX_FRAME_SNAP 1
-#define IPX_FRAME_8022 2
-#define IPX_FRAME_ETHERII 3
-#define IPX_FRAME_8023 4
-#define IPX_FRAME_TR_8022 5
-  unsigned char ipx_special;
-#define IPX_SPECIAL_NONE 0
-#define IPX_PRIMARY 1
-#define IPX_INTERNAL 2
-  unsigned char ipx_node[IPX_NODE_LEN];
-};
-#endif
-#if __UAPI_DEF_IPX_CONFIG_DATA
-struct ipx_config_data {
-  unsigned char ipxcfg_auto_select_primary;
-  unsigned char ipxcfg_auto_create_interfaces;
-};
-#endif
-#if __UAPI_DEF_IPX_ROUTE_DEF
-struct ipx_route_def {
-  __be32 ipx_network;
-  __be32 ipx_router_network;
-#define IPX_ROUTE_NO_ROUTER 0
-  unsigned char ipx_router_node[IPX_NODE_LEN];
-  unsigned char ipx_device[16];
-  unsigned short ipx_flags;
-#define IPX_RT_SNAP 8
-#define IPX_RT_8022 4
-#define IPX_RT_BLUEBOOK 2
-#define IPX_RT_ROUTED 1
-};
-#endif
-#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
-#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
-#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
-#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE + 3)
-#endif
diff --git a/libc/kernel/uapi/linux/kexec.h b/libc/kernel/uapi/linux/kexec.h
index b2dc88f..2e3bd0c 100644
--- a/libc/kernel/uapi/linux/kexec.h
+++ b/libc/kernel/uapi/linux/kexec.h
@@ -39,6 +39,7 @@
 #define KEXEC_ARCH_MIPS_LE (10 << 16)
 #define KEXEC_ARCH_MIPS (8 << 16)
 #define KEXEC_ARCH_AARCH64 (183 << 16)
+#define KEXEC_ARCH_RISCV (243 << 16)
 #define KEXEC_SEGMENT_MAX 16
 struct kexec_segment {
   const void * buf;
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 73ef5de..c52ac64 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 3
+#define KFD_IOCTL_MINOR_VERSION 6
 struct kfd_ioctl_get_version_args {
   __u32 major_version;
   __u32 minor_version;
@@ -244,6 +244,7 @@
 #define KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE (1 << 28)
 #define KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM (1 << 27)
 #define KFD_IOC_ALLOC_MEM_FLAGS_COHERENT (1 << 26)
+#define KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED (1 << 25)
 struct kfd_ioctl_alloc_memory_of_gpu_args {
   __u64 va_addr;
   __u64 size;
@@ -303,6 +304,44 @@
   KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL = 0,
   KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL = 4,
 };
+#define KFD_IOCTL_SVM_FLAG_HOST_ACCESS 0x00000001
+#define KFD_IOCTL_SVM_FLAG_COHERENT 0x00000002
+#define KFD_IOCTL_SVM_FLAG_HIVE_LOCAL 0x00000004
+#define KFD_IOCTL_SVM_FLAG_GPU_RO 0x00000008
+#define KFD_IOCTL_SVM_FLAG_GPU_EXEC 0x00000010
+#define KFD_IOCTL_SVM_FLAG_GPU_READ_MOSTLY 0x00000020
+enum kfd_ioctl_svm_op {
+  KFD_IOCTL_SVM_OP_SET_ATTR,
+  KFD_IOCTL_SVM_OP_GET_ATTR
+};
+enum kfd_ioctl_svm_location {
+  KFD_IOCTL_SVM_LOCATION_SYSMEM = 0,
+  KFD_IOCTL_SVM_LOCATION_UNDEFINED = 0xffffffff
+};
+enum kfd_ioctl_svm_attr_type {
+  KFD_IOCTL_SVM_ATTR_PREFERRED_LOC,
+  KFD_IOCTL_SVM_ATTR_PREFETCH_LOC,
+  KFD_IOCTL_SVM_ATTR_ACCESS,
+  KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE,
+  KFD_IOCTL_SVM_ATTR_NO_ACCESS,
+  KFD_IOCTL_SVM_ATTR_SET_FLAGS,
+  KFD_IOCTL_SVM_ATTR_CLR_FLAGS,
+  KFD_IOCTL_SVM_ATTR_GRANULARITY
+};
+struct kfd_ioctl_svm_attribute {
+  __u32 type;
+  __u32 value;
+};
+struct kfd_ioctl_svm_args {
+  __u64 start_addr;
+  __u64 size;
+  __u32 op;
+  __u32 nattr;
+  struct kfd_ioctl_svm_attribute attrs[0];
+};
+struct kfd_ioctl_set_xnack_mode_args {
+  __s32 xnack_enabled;
+};
 #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)
@@ -339,6 +378,8 @@
 #define AMDKFD_IOC_IMPORT_DMABUF AMDKFD_IOWR(0x1D, struct kfd_ioctl_import_dmabuf_args)
 #define AMDKFD_IOC_ALLOC_QUEUE_GWS AMDKFD_IOWR(0x1E, struct kfd_ioctl_alloc_queue_gws_args)
 #define AMDKFD_IOC_SMI_EVENTS AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args)
+#define AMDKFD_IOC_SVM AMDKFD_IOWR(0x20, struct kfd_ioctl_svm_args)
+#define AMDKFD_IOC_SET_XNACK_MODE AMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args)
 #define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x20
+#define AMDKFD_COMMAND_END 0x22
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_sysfs.h b/libc/kernel/uapi/linux/kfd_sysfs.h
new file mode 100644
index 0000000..9604b03
--- /dev/null
+++ b/libc/kernel/uapi/linux/kfd_sysfs.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 KFD_SYSFS_H_INCLUDED
+#define KFD_SYSFS_H_INCLUDED
+#define HSA_CAP_HOT_PLUGGABLE 0x00000001
+#define HSA_CAP_ATS_PRESENT 0x00000002
+#define HSA_CAP_SHARED_WITH_GRAPHICS 0x00000004
+#define HSA_CAP_QUEUE_SIZE_POW2 0x00000008
+#define HSA_CAP_QUEUE_SIZE_32BIT 0x00000010
+#define HSA_CAP_QUEUE_IDLE_EVENT 0x00000020
+#define HSA_CAP_VA_LIMIT 0x00000040
+#define HSA_CAP_WATCH_POINTS_SUPPORTED 0x00000080
+#define HSA_CAP_WATCH_POINTS_TOTALBITS_MASK 0x00000f00
+#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8
+#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_MASK 0x00003000
+#define HSA_CAP_DOORBELL_TYPE_TOTALBITS_SHIFT 12
+#define HSA_CAP_DOORBELL_TYPE_PRE_1_0 0x0
+#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_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000
+#define HSA_CAP_MEM_EDCSUPPORTED 0x00100000
+#define HSA_CAP_RASEVENTNOTIFY 0x00200000
+#define HSA_CAP_ASIC_REVISION_MASK 0x03c00000
+#define HSA_CAP_ASIC_REVISION_SHIFT 22
+#define HSA_CAP_SRAM_EDCSUPPORTED 0x04000000
+#define HSA_CAP_SVMAPI_SUPPORTED 0x08000000
+#define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000
+#define HSA_CAP_RESERVED 0xe00f8000
+#define HSA_MEM_HEAP_TYPE_SYSTEM 0
+#define HSA_MEM_HEAP_TYPE_FB_PUBLIC 1
+#define HSA_MEM_HEAP_TYPE_FB_PRIVATE 2
+#define HSA_MEM_HEAP_TYPE_GPU_GDS 3
+#define HSA_MEM_HEAP_TYPE_GPU_LDS 4
+#define HSA_MEM_HEAP_TYPE_GPU_SCRATCH 5
+#define HSA_MEM_FLAGS_HOT_PLUGGABLE 0x00000001
+#define HSA_MEM_FLAGS_NON_VOLATILE 0x00000002
+#define HSA_MEM_FLAGS_RESERVED 0xfffffffc
+#define HSA_CACHE_TYPE_DATA 0x00000001
+#define HSA_CACHE_TYPE_INSTRUCTION 0x00000002
+#define HSA_CACHE_TYPE_CPU 0x00000004
+#define HSA_CACHE_TYPE_HSACU 0x00000008
+#define HSA_CACHE_TYPE_RESERVED 0xfffffff0
+#define HSA_IOLINK_TYPE_UNDEFINED 0
+#define HSA_IOLINK_TYPE_HYPERTRANSPORT 1
+#define HSA_IOLINK_TYPE_PCIEXPRESS 2
+#define HSA_IOLINK_TYPE_AMBA 3
+#define HSA_IOLINK_TYPE_MIPI 4
+#define HSA_IOLINK_TYPE_QPI_1_1 5
+#define HSA_IOLINK_TYPE_RESERVED1 6
+#define HSA_IOLINK_TYPE_RESERVED2 7
+#define HSA_IOLINK_TYPE_RAPID_IO 8
+#define HSA_IOLINK_TYPE_INFINIBAND 9
+#define HSA_IOLINK_TYPE_RESERVED3 10
+#define HSA_IOLINK_TYPE_XGMI 11
+#define HSA_IOLINK_TYPE_XGOP 12
+#define HSA_IOLINK_TYPE_GZ 13
+#define HSA_IOLINK_TYPE_ETHERNET_RDMA 14
+#define HSA_IOLINK_TYPE_RDMA_OTHER 15
+#define HSA_IOLINK_TYPE_OTHER 16
+#define HSA_IOLINK_FLAGS_ENABLED (1 << 0)
+#define HSA_IOLINK_FLAGS_NON_COHERENT (1 << 1)
+#define HSA_IOLINK_FLAGS_NO_ATOMICS_32_BIT (1 << 2)
+#define HSA_IOLINK_FLAGS_NO_ATOMICS_64_BIT (1 << 3)
+#define HSA_IOLINK_FLAGS_NO_PEER_TO_PEER_DMA (1 << 4)
+#define HSA_IOLINK_FLAGS_RESERVED 0xffffffe0
+#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 81fa779..1cf7182 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef __LINUX_KVM_H
 #define __LINUX_KVM_H
+#include <linux/const.h>
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/ioctl.h>
@@ -214,10 +215,12 @@
 #define KVM_EXIT_AP_RESET_HOLD 32
 #define KVM_EXIT_X86_BUS_LOCK 33
 #define KVM_EXIT_XEN 34
+#define KVM_EXIT_RISCV_SBI 35
 #define KVM_INTERNAL_ERROR_EMULATION 1
 #define KVM_INTERNAL_ERROR_SIMUL_EX 2
 #define KVM_INTERNAL_ERROR_DELIVERY_EV 3
 #define KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON 4
+#define KVM_INTERNAL_ERROR_EMULATION_FLAG_INSTRUCTION_BYTES (1ULL << 0)
 struct kvm_run {
   __u8 request_interrupt_window;
   __u8 immediate_exit;
@@ -300,6 +303,17 @@
       __u64 data[16];
     } internal;
     struct {
+      __u32 suberror;
+      __u32 ndata;
+      __u64 flags;
+      union {
+        struct {
+          __u8 insn_size;
+          __u8 insn_bytes[15];
+        };
+      };
+    } emulation_failure;
+    struct {
       __u64 gprs[32];
     } osi;
     struct {
@@ -352,6 +366,12 @@
       __u64 data;
     } msr;
     struct kvm_xen_exit xen;
+    struct {
+      unsigned long extension_id;
+      unsigned long function_id;
+      unsigned long args[6];
+      unsigned long ret[2];
+    } riscv_sbi;
     char padding[256];
   };
 #define SYNC_REGS_SIZE_BYTES 2048
@@ -854,6 +874,22 @@
 #define KVM_CAP_DIRTY_LOG_RING 192
 #define KVM_CAP_X86_BUS_LOCK_EXIT 193
 #define KVM_CAP_PPC_DAWR1 194
+#define KVM_CAP_SET_GUEST_DEBUG2 195
+#define KVM_CAP_SGX_ATTRIBUTE 196
+#define KVM_CAP_VM_COPY_ENC_CONTEXT_FROM 197
+#define KVM_CAP_PTP_KVM 198
+#define KVM_CAP_HYPERV_ENFORCE_CPUID 199
+#define KVM_CAP_SREGS2 200
+#define KVM_CAP_EXIT_HYPERCALL 201
+#define KVM_CAP_PPC_RPT_INVALIDATE 202
+#define KVM_CAP_BINARY_STATS_FD 203
+#define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
+#define KVM_CAP_ARM_MTE 205
+#define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
+#define KVM_CAP_VM_GPA_BITS 207
+#define KVM_CAP_XSAVE2 208
+#define KVM_CAP_SYS_ATTRIBUTES 209
+#define KVM_CAP_PPC_AIL_MODE_3 210
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -879,10 +915,17 @@
   __u32 vcpu;
   __u32 sint;
 };
+struct kvm_irq_routing_xen_evtchn {
+  __u32 port;
+  __u32 vcpu;
+  __u32 priority;
+};
+#define KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL ((__u32) (- 1))
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 #define KVM_IRQ_ROUTING_HV_SINT 4
+#define KVM_IRQ_ROUTING_XEN_EVTCHN 5
 struct kvm_irq_routing_entry {
   __u32 gsi;
   __u32 type;
@@ -893,6 +936,7 @@
     struct kvm_irq_routing_msi msi;
     struct kvm_irq_routing_s390_adapter adapter;
     struct kvm_irq_routing_hv_sint hv_sint;
+    struct kvm_irq_routing_xen_evtchn xen_evtchn;
     __u32 pad[8];
   } u;
 };
@@ -918,6 +962,7 @@
 #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
 #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
 #define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
 struct kvm_xen_hvm_config {
   __u32 flags;
   __u32 msr;
@@ -938,10 +983,15 @@
   __u8 pad[16];
 };
 #define KVM_CLOCK_TSC_STABLE 2
+#define KVM_CLOCK_REALTIME (1 << 2)
+#define KVM_CLOCK_HOST_TSC (1 << 3)
 struct kvm_clock_data {
   __u64 clock;
   __u32 flags;
-  __u32 pad[9];
+  __u32 pad0;
+  __u64 realtime;
+  __u64 host_tsc;
+  __u32 pad[4];
 };
 #define KVM_MMU_FSL_BOOKE_NOHV 0
 #define KVM_MMU_FSL_BOOKE_HV 1
@@ -1105,6 +1155,7 @@
 #define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)
 #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_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)
@@ -1230,6 +1281,8 @@
 #define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
 #define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr)
 #define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr)
+#define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2)
+#define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2)
 struct kvm_xen_vcpu_attr {
   __u16 type;
   __u16 pad[3];
@@ -1274,6 +1327,7 @@
   KVM_SEV_DBG_ENCRYPT,
   KVM_SEV_CERT_EXPORT,
   KVM_SEV_GET_ATTESTATION_REPORT,
+  KVM_SEV_SEND_CANCEL,
   KVM_SEV_NR_MAX,
 };
 struct kvm_sev_cmd {
@@ -1321,6 +1375,41 @@
   __u64 uaddr;
   __u32 len;
 };
+struct kvm_sev_send_start {
+  __u32 policy;
+  __u64 pdh_cert_uaddr;
+  __u32 pdh_cert_len;
+  __u64 plat_certs_uaddr;
+  __u32 plat_certs_len;
+  __u64 amd_certs_uaddr;
+  __u32 amd_certs_len;
+  __u64 session_uaddr;
+  __u32 session_len;
+};
+struct kvm_sev_send_update_data {
+  __u64 hdr_uaddr;
+  __u32 hdr_len;
+  __u64 guest_uaddr;
+  __u32 guest_len;
+  __u64 trans_uaddr;
+  __u32 trans_len;
+};
+struct kvm_sev_receive_start {
+  __u32 handle;
+  __u32 policy;
+  __u64 pdh_uaddr;
+  __u32 pdh_len;
+  __u64 session_uaddr;
+  __u32 session_len;
+};
+struct kvm_sev_receive_update_data {
+  __u64 hdr_uaddr;
+  __u32 hdr_len;
+  __u64 guest_uaddr;
+  __u32 guest_len;
+  __u64 trans_uaddr;
+  __u32 trans_len;
+};
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
 #define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
@@ -1381,8 +1470,8 @@
 #ifndef KVM_DIRTY_LOG_PAGE_OFFSET
 #define KVM_DIRTY_LOG_PAGE_OFFSET 0
 #endif
-#define KVM_DIRTY_GFN_F_DIRTY BIT(0)
-#define KVM_DIRTY_GFN_F_RESET BIT(1)
+#define KVM_DIRTY_GFN_F_DIRTY _BITUL(0)
+#define KVM_DIRTY_GFN_F_RESET _BITUL(1)
 #define KVM_DIRTY_GFN_F_MASK 0x3
 struct kvm_dirty_gfn {
   __u32 flags;
@@ -1391,4 +1480,42 @@
 };
 #define KVM_BUS_LOCK_DETECTION_OFF (1 << 0)
 #define KVM_BUS_LOCK_DETECTION_EXIT (1 << 1)
+struct kvm_stats_header {
+  __u32 flags;
+  __u32 name_size;
+  __u32 num_desc;
+  __u32 id_offset;
+  __u32 desc_offset;
+  __u32 data_offset;
+};
+#define KVM_STATS_TYPE_SHIFT 0
+#define KVM_STATS_TYPE_MASK (0xF << KVM_STATS_TYPE_SHIFT)
+#define KVM_STATS_TYPE_CUMULATIVE (0x0 << KVM_STATS_TYPE_SHIFT)
+#define KVM_STATS_TYPE_INSTANT (0x1 << KVM_STATS_TYPE_SHIFT)
+#define KVM_STATS_TYPE_PEAK (0x2 << KVM_STATS_TYPE_SHIFT)
+#define KVM_STATS_TYPE_LINEAR_HIST (0x3 << KVM_STATS_TYPE_SHIFT)
+#define KVM_STATS_TYPE_LOG_HIST (0x4 << KVM_STATS_TYPE_SHIFT)
+#define KVM_STATS_TYPE_MAX KVM_STATS_TYPE_LOG_HIST
+#define KVM_STATS_UNIT_SHIFT 4
+#define KVM_STATS_UNIT_MASK (0xF << KVM_STATS_UNIT_SHIFT)
+#define KVM_STATS_UNIT_NONE (0x0 << KVM_STATS_UNIT_SHIFT)
+#define KVM_STATS_UNIT_BYTES (0x1 << KVM_STATS_UNIT_SHIFT)
+#define KVM_STATS_UNIT_SECONDS (0x2 << KVM_STATS_UNIT_SHIFT)
+#define KVM_STATS_UNIT_CYCLES (0x3 << KVM_STATS_UNIT_SHIFT)
+#define KVM_STATS_UNIT_MAX KVM_STATS_UNIT_CYCLES
+#define KVM_STATS_BASE_SHIFT 8
+#define KVM_STATS_BASE_MASK (0xF << KVM_STATS_BASE_SHIFT)
+#define KVM_STATS_BASE_POW10 (0x0 << KVM_STATS_BASE_SHIFT)
+#define KVM_STATS_BASE_POW2 (0x1 << KVM_STATS_BASE_SHIFT)
+#define KVM_STATS_BASE_MAX KVM_STATS_BASE_POW2
+struct kvm_stats_desc {
+  __u32 flags;
+  __s16 exponent;
+  __u16 size;
+  __u32 offset;
+  __u32 bucket_size;
+  char name[];
+};
+#define KVM_GET_STATS_FD _IO(KVMIO, 0xce)
+#define KVM_GET_XSAVE2 _IOR(KVMIO, 0xcf, struct kvm_xsave)
 #endif
diff --git a/libc/kernel/uapi/linux/kvm_para.h b/libc/kernel/uapi/linux/kvm_para.h
index 9a4dd29..85084c2 100644
--- a/libc/kernel/uapi/linux/kvm_para.h
+++ b/libc/kernel/uapi/linux/kvm_para.h
@@ -35,5 +35,6 @@
 #define KVM_HC_CLOCK_PAIRING 9
 #define KVM_HC_SEND_IPI 10
 #define KVM_HC_SCHED_YIELD 11
+#define KVM_HC_MAP_GPA_RANGE 12
 #include <asm/kvm_para.h>
 #endif
diff --git a/libc/kernel/uapi/linux/landlock.h b/libc/kernel/uapi/linux/landlock.h
new file mode 100644
index 0000000..50d79d8
--- /dev/null
+++ b/libc/kernel/uapi/linux/landlock.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_LANDLOCK_H
+#define _UAPI_LINUX_LANDLOCK_H
+#include <linux/types.h>
+struct landlock_ruleset_attr {
+  __u64 handled_access_fs;
+};
+#define LANDLOCK_CREATE_RULESET_VERSION (1U << 0)
+enum landlock_rule_type {
+  LANDLOCK_RULE_PATH_BENEATH = 1,
+};
+struct landlock_path_beneath_attr {
+  __u64 allowed_access;
+  __s32 parent_fd;
+} __attribute__((packed));
+#define LANDLOCK_ACCESS_FS_EXECUTE (1ULL << 0)
+#define LANDLOCK_ACCESS_FS_WRITE_FILE (1ULL << 1)
+#define LANDLOCK_ACCESS_FS_READ_FILE (1ULL << 2)
+#define LANDLOCK_ACCESS_FS_READ_DIR (1ULL << 3)
+#define LANDLOCK_ACCESS_FS_REMOVE_DIR (1ULL << 4)
+#define LANDLOCK_ACCESS_FS_REMOVE_FILE (1ULL << 5)
+#define LANDLOCK_ACCESS_FS_MAKE_CHAR (1ULL << 6)
+#define LANDLOCK_ACCESS_FS_MAKE_DIR (1ULL << 7)
+#define LANDLOCK_ACCESS_FS_MAKE_REG (1ULL << 8)
+#define LANDLOCK_ACCESS_FS_MAKE_SOCK (1ULL << 9)
+#define LANDLOCK_ACCESS_FS_MAKE_FIFO (1ULL << 10)
+#define LANDLOCK_ACCESS_FS_MAKE_BLOCK (1ULL << 11)
+#define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12)
+#endif
diff --git a/libc/kernel/uapi/linux/lightnvm.h b/libc/kernel/uapi/linux/lightnvm.h
deleted file mode 100644
index b3ac317..0000000
--- a/libc/kernel/uapi/linux/lightnvm.h
+++ /dev/null
@@ -1,167 +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_LINUX_LIGHTNVM_H
-#define _UAPI_LINUX_LIGHTNVM_H
-#include <stdio.h>
-#include <sys/ioctl.h>
-#define DISK_NAME_LEN 32
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#define NVM_TTYPE_NAME_MAX 48
-#define NVM_TTYPE_MAX 63
-#define NVM_MMTYPE_LEN 8
-#define NVM_CTRL_FILE "/dev/lightnvm/control"
-struct nvm_ioctl_info_tgt {
-  __u32 version[3];
-  __u32 reserved;
-  char tgtname[NVM_TTYPE_NAME_MAX];
-};
-struct nvm_ioctl_info {
-  __u32 version[3];
-  __u16 tgtsize;
-  __u16 reserved16;
-  __u32 reserved[12];
-  struct nvm_ioctl_info_tgt tgts[NVM_TTYPE_MAX];
-};
-enum {
-  NVM_DEVICE_ACTIVE = 1 << 0,
-};
-struct nvm_ioctl_device_info {
-  char devname[DISK_NAME_LEN];
-  char bmname[NVM_TTYPE_NAME_MAX];
-  __u32 bmversion[3];
-  __u32 flags;
-  __u32 reserved[8];
-};
-struct nvm_ioctl_get_devices {
-  __u32 nr_devices;
-  __u32 reserved[31];
-  struct nvm_ioctl_device_info info[31];
-};
-struct nvm_ioctl_create_simple {
-  __u32 lun_begin;
-  __u32 lun_end;
-};
-struct nvm_ioctl_create_extended {
-  __u16 lun_begin;
-  __u16 lun_end;
-  __u16 op;
-  __u16 rsv;
-};
-enum {
-  NVM_CONFIG_TYPE_SIMPLE = 0,
-  NVM_CONFIG_TYPE_EXTENDED = 1,
-};
-struct nvm_ioctl_create_conf {
-  __u32 type;
-  union {
-    struct nvm_ioctl_create_simple s;
-    struct nvm_ioctl_create_extended e;
-  };
-};
-enum {
-  NVM_TARGET_FACTORY = 1 << 0,
-};
-struct nvm_ioctl_create {
-  char dev[DISK_NAME_LEN];
-  char tgttype[NVM_TTYPE_NAME_MAX];
-  char tgtname[DISK_NAME_LEN];
-  __u32 flags;
-  struct nvm_ioctl_create_conf conf;
-};
-struct nvm_ioctl_remove {
-  char tgtname[DISK_NAME_LEN];
-  __u32 flags;
-};
-struct nvm_ioctl_dev_init {
-  char dev[DISK_NAME_LEN];
-  char mmtype[NVM_MMTYPE_LEN];
-  __u32 flags;
-};
-enum {
-  NVM_FACTORY_ERASE_ONLY_USER = 1 << 0,
-  NVM_FACTORY_RESET_HOST_BLKS = 1 << 1,
-  NVM_FACTORY_RESET_GRWN_BBLKS = 1 << 2,
-  NVM_FACTORY_NR_BITS = 1 << 3,
-};
-struct nvm_ioctl_dev_factory {
-  char dev[DISK_NAME_LEN];
-  __u32 flags;
-};
-struct nvm_user_vio {
-  __u8 opcode;
-  __u8 flags;
-  __u16 control;
-  __u16 nppas;
-  __u16 rsvd;
-  __u64 metadata;
-  __u64 addr;
-  __u64 ppa_list;
-  __u32 metadata_len;
-  __u32 data_len;
-  __u64 status;
-  __u32 result;
-  __u32 rsvd3[3];
-};
-struct nvm_passthru_vio {
-  __u8 opcode;
-  __u8 flags;
-  __u8 rsvd[2];
-  __u32 nsid;
-  __u32 cdw2;
-  __u32 cdw3;
-  __u64 metadata;
-  __u64 addr;
-  __u32 metadata_len;
-  __u32 data_len;
-  __u64 ppa_list;
-  __u16 nppas;
-  __u16 control;
-  __u32 cdw13;
-  __u32 cdw14;
-  __u32 cdw15;
-  __u64 status;
-  __u32 result;
-  __u32 timeout_ms;
-};
-enum {
-  NVM_INFO_CMD = 0x20,
-  NVM_GET_DEVICES_CMD,
-  NVM_DEV_CREATE_CMD,
-  NVM_DEV_REMOVE_CMD,
-  NVM_DEV_INIT_CMD,
-  NVM_DEV_FACTORY_CMD,
-  NVM_DEV_VIO_ADMIN_CMD = 0x41,
-  NVM_DEV_VIO_CMD = 0x42,
-  NVM_DEV_VIO_USER_CMD = 0x43,
-};
-#define NVM_IOCTL 'L'
-#define NVM_INFO _IOWR(NVM_IOCTL, NVM_INFO_CMD, struct nvm_ioctl_info)
-#define NVM_GET_DEVICES _IOR(NVM_IOCTL, NVM_GET_DEVICES_CMD, struct nvm_ioctl_get_devices)
-#define NVM_DEV_CREATE _IOW(NVM_IOCTL, NVM_DEV_CREATE_CMD, struct nvm_ioctl_create)
-#define NVM_DEV_REMOVE _IOW(NVM_IOCTL, NVM_DEV_REMOVE_CMD, struct nvm_ioctl_remove)
-#define NVM_DEV_INIT _IOW(NVM_IOCTL, NVM_DEV_INIT_CMD, struct nvm_ioctl_dev_init)
-#define NVM_DEV_FACTORY _IOW(NVM_IOCTL, NVM_DEV_FACTORY_CMD, struct nvm_ioctl_dev_factory)
-#define NVME_NVM_IOCTL_IO_VIO _IOWR(NVM_IOCTL, NVM_DEV_VIO_USER_CMD, struct nvm_passthru_vio)
-#define NVME_NVM_IOCTL_ADMIN_VIO _IOWR(NVM_IOCTL, NVM_DEV_VIO_ADMIN_CMD, struct nvm_passthru_vio)
-#define NVME_NVM_IOCTL_SUBMIT_VIO _IOWR(NVM_IOCTL, NVM_DEV_VIO_CMD, struct nvm_user_vio)
-#define NVM_VERSION_MAJOR 1
-#define NVM_VERSION_MINOR 0
-#define NVM_VERSION_PATCHLEVEL 0
-#endif
diff --git a/libc/kernel/uapi/linux/lwtunnel.h b/libc/kernel/uapi/linux/lwtunnel.h
index f472150..e6fb536 100644
--- a/libc/kernel/uapi/linux/lwtunnel.h
+++ b/libc/kernel/uapi/linux/lwtunnel.h
@@ -29,6 +29,7 @@
   LWTUNNEL_ENCAP_BPF,
   LWTUNNEL_ENCAP_SEG6_LOCAL,
   LWTUNNEL_ENCAP_RPL,
+  LWTUNNEL_ENCAP_IOAM6,
   __LWTUNNEL_ENCAP_MAX,
 };
 #define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 479ae81..6563411 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -22,6 +22,7 @@
 #define AFFS_SUPER_MAGIC 0xadff
 #define AFS_SUPER_MAGIC 0x5346414F
 #define AUTOFS_SUPER_MAGIC 0x0187
+#define CEPH_SUPER_MAGIC 0x00c36400
 #define CODA_SUPER_MAGIC 0x73757245
 #define CRAMFS_MAGIC 0x28cd3d45
 #define CRAMFS_MAGIC_WEND 0x453dcd28
@@ -51,12 +52,14 @@
 #define EFIVARFS_MAGIC 0xde5e81e4
 #define HOSTFS_SUPER_MAGIC 0x00c0ffee
 #define OVERLAYFS_SUPER_MAGIC 0x794c7630
+#define FUSE_SUPER_MAGIC 0x65735546
 #define MINIX_SUPER_MAGIC 0x137F
 #define MINIX_SUPER_MAGIC2 0x138F
 #define MINIX2_SUPER_MAGIC 0x2468
 #define MINIX2_SUPER_MAGIC2 0x2478
 #define MINIX3_SUPER_MAGIC 0x4d5a
 #define MSDOS_SUPER_MAGIC 0x4d44
+#define EXFAT_SUPER_MAGIC 0x2011BAB0
 #define NCP_SUPER_MAGIC 0x564c
 #define NFS_SUPER_MAGIC 0x6969
 #define OCFS2_SUPER_MAGIC 0x7461636f
@@ -69,6 +72,8 @@
 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
 #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
 #define SMB_SUPER_MAGIC 0x517B
+#define CIFS_SUPER_MAGIC 0xFF534D42
+#define SMB2_SUPER_MAGIC 0xFE534D42
 #define CGROUP_SUPER_MAGIC 0x27e0eb
 #define CGROUP2_SUPER_MAGIC 0x63677270
 #define RDTGROUP_SUPER_MAGIC 0x7655821
@@ -100,4 +105,5 @@
 #define DEVMEM_MAGIC 0x454d444d
 #define Z3FOLD_MAGIC 0x33
 #define PPC_CMM_MAGIC 0xc7571590
+#define SECRETMEM_MAGIC 0x5345434d
 #endif
diff --git a/libc/kernel/uapi/linux/major.h b/libc/kernel/uapi/linux/major.h
index 7768d7b..f5e2cfb 100644
--- a/libc/kernel/uapi/linux/major.h
+++ b/libc/kernel/uapi/linux/major.h
@@ -45,8 +45,6 @@
 #define GOLDSTAR_CDROM_MAJOR 16
 #define OPTICS_CDROM_MAJOR 17
 #define SANYO_CDROM_MAJOR 18
-#define CYCLADES_MAJOR 19
-#define CYCLADESAUX_MAJOR 20
 #define MITSUMI_X_CDROM_MAJOR 20
 #define MFM_ACORN_MAJOR 21
 #define SCSI_GENERIC_MAJOR 21
diff --git a/libc/kernel/uapi/linux/map_to_14segment.h b/libc/kernel/uapi/linux/map_to_14segment.h
new file mode 100644
index 0000000..657df6c
--- /dev/null
+++ b/libc/kernel/uapi/linux/map_to_14segment.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 MAP_TO_14SEGMENT_H
+#define MAP_TO_14SEGMENT_H
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#define BIT_SEG14_A 0
+#define BIT_SEG14_B 1
+#define BIT_SEG14_C 2
+#define BIT_SEG14_D 3
+#define BIT_SEG14_E 4
+#define BIT_SEG14_F 5
+#define BIT_SEG14_G1 6
+#define BIT_SEG14_G2 7
+#define BIT_SEG14_H 8
+#define BIT_SEG14_I 9
+#define BIT_SEG14_J 10
+#define BIT_SEG14_K 11
+#define BIT_SEG14_L 12
+#define BIT_SEG14_M 13
+#define BIT_SEG14_RESERVED1 14
+#define BIT_SEG14_RESERVED2 15
+struct seg14_conversion_map {
+  __be16 table[128];
+};
+#define SEG14_CONVERSION_MAP(_name,_map) struct seg14_conversion_map _name = {.table = { _map } }
+#define MAP_TO_SEG14_SYSFS_FILE "map_seg14"
+#define _SEG14(sym,a,b,c,d,e,f,g1,g2,h,j,k,l,m,n) __cpu_to_be16(a << BIT_SEG14_A | b << BIT_SEG14_B | c << BIT_SEG14_C | d << BIT_SEG14_D | e << BIT_SEG14_E | f << BIT_SEG14_F | g1 << BIT_SEG14_G1 | g2 << BIT_SEG14_G2 | h << BIT_SEG14_H | j << BIT_SEG14_I | k << BIT_SEG14_J | l << BIT_SEG14_K | m << BIT_SEG14_L | n << BIT_SEG14_M)
+#define _MAP_0_32_ASCII_SEG14_NON_PRINTABLE 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+#define _MAP_33_47_ASCII_SEG14_SYMBOL _SEG14('!', 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('"', 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), _SEG14('#', 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0), _SEG14('$', 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0), _SEG14('%', 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0), _SEG14('&', 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1), _SEG14('\'', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), _SEG14('(', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1), _SEG14(')', 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0), _SEG14('*', 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1), _SEG14('+', 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0), _SEG14(',', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), _SEG14('-', 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), _SEG14('/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0),
+#define _MAP_48_57_ASCII_SEG14_NUMERIC _SEG14('0', 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0), _SEG14('1', 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), _SEG14('2', 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('3', 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), _SEG14('4', 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('5', 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1), _SEG14('6', 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('7', 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0), _SEG14('8', 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('9', 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0),
+#define _MAP_58_64_ASCII_SEG14_SYMBOL _SEG14(':', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0), _SEG14(';', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0), _SEG14('<', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1), _SEG14('=', 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('>', 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0), _SEG14('?', 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0), _SEG14('@', 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0),
+#define _MAP_65_90_ASCII_SEG14_ALPHA_UPPER _SEG14('A', 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('B', 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0), _SEG14('C', 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('D', 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0), _SEG14('E', 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0), _SEG14('F', 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0), _SEG14('G', 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0), _SEG14('H', 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('I', 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0), _SEG14('J', 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('K', 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1), _SEG14('L', 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('M', 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0), _SEG14('N', 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1), _SEG14('O', 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('P', 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('Q', 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1), _SEG14('R', 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1), _SEG14('S', 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('T', 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0), _SEG14('U', 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('V', 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0), _SEG14('W', 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1), _SEG14('X', 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1), _SEG14('Y', 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0), _SEG14('Z', 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0),
+#define _MAP_91_96_ASCII_SEG14_SYMBOL _SEG14('[', 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('\\', 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), _SEG14(']', 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('^', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1), _SEG14('_', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('`', 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0),
+#define _MAP_97_122_ASCII_SEG14_ALPHA_LOWER _SEG14('a', 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0), _SEG14('b', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1), _SEG14('c', 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('d', 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0), _SEG14('e', 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0), _SEG14('f', 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0), _SEG14('g', 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0), _SEG14('h', 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0), _SEG14('i', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0), _SEG14('j', 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0), _SEG14('k', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1), _SEG14('l', 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('m', 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0), _SEG14('n', 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0), _SEG14('o', 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0), _SEG14('p', 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0), _SEG14('q', 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0), _SEG14('r', 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0), _SEG14('s', 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1), _SEG14('t', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0), _SEG14('u', 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), _SEG14('v', 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0), _SEG14('w', 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1), _SEG14('x', 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), _SEG14('y', 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0), _SEG14('z', 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0),
+#define _MAP_123_126_ASCII_SEG14_SYMBOL _SEG14('{', 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0), _SEG14('|', 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0), _SEG14('}', 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1), _SEG14('~', 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0),
+#define MAP_ASCII14SEG_ALPHANUM _MAP_0_32_ASCII_SEG14_NON_PRINTABLE _MAP_33_47_ASCII_SEG14_SYMBOL _MAP_48_57_ASCII_SEG14_NUMERIC _MAP_58_64_ASCII_SEG14_SYMBOL _MAP_65_90_ASCII_SEG14_ALPHA_UPPER _MAP_91_96_ASCII_SEG14_SYMBOL _MAP_97_122_ASCII_SEG14_ALPHA_LOWER _MAP_123_126_ASCII_SEG14_SYMBOL
+#define SEG14_DEFAULT_MAP(_name) SEG14_CONVERSION_MAP(_name, MAP_ASCII14SEG_ALPHANUM)
+#endif
diff --git a/libc/kernel/uapi/linux/mctp.h b/libc/kernel/uapi/linux/mctp.h
new file mode 100644
index 0000000..21a9a14
--- /dev/null
+++ b/libc/kernel/uapi/linux/mctp.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_MCTP_H
+#define __UAPI_MCTP_H
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/netdevice.h>
+typedef __u8 mctp_eid_t;
+struct mctp_addr {
+  mctp_eid_t s_addr;
+};
+struct sockaddr_mctp {
+  __kernel_sa_family_t smctp_family;
+  __u16 __smctp_pad0;
+  unsigned int smctp_network;
+  struct mctp_addr smctp_addr;
+  __u8 smctp_type;
+  __u8 smctp_tag;
+  __u8 __smctp_pad1;
+};
+struct sockaddr_mctp_ext {
+  struct sockaddr_mctp smctp_base;
+  int smctp_ifindex;
+  __u8 smctp_halen;
+  __u8 __smctp_pad0[3];
+  __u8 smctp_haddr[MAX_ADDR_LEN];
+};
+#define MCTP_NET_ANY 0x0
+#define MCTP_ADDR_NULL 0x00
+#define MCTP_ADDR_ANY 0xff
+#define MCTP_TAG_MASK 0x07
+#define MCTP_TAG_OWNER 0x08
+#define MCTP_OPT_ADDR_EXT 1
+#endif
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index a38cbfc..d5c9da8 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -55,9 +55,11 @@
 #define MDIO_AN_EEE_LPABLE 61
 #define MDIO_AN_EEE_ADV2 62
 #define MDIO_AN_EEE_LPABLE2 63
+#define MDIO_AN_CTRL2 64
 #define MDIO_PMA_10GBT_SWAPPOL 130
 #define MDIO_PMA_10GBT_TXPWR 131
 #define MDIO_PMA_10GBT_SNR 133
+#define MDIO_PMA_10GBR_FSRT_CSR 147
 #define MDIO_PMA_10GBR_FECABLE 170
 #define MDIO_PCS_10GBX_STAT1 24
 #define MDIO_PCS_10GBRT_STAT1 32
@@ -104,6 +106,8 @@
 #define MDIO_PMA_SPEED_100 0x0020
 #define MDIO_PMA_SPEED_10 0x0040
 #define MDIO_PCS_SPEED_10P2B 0x0002
+#define MDIO_PCS_SPEED_2_5G 0x0040
+#define MDIO_PCS_SPEED_5G 0x0080
 #define MDIO_DEVS_PRESENT(devad) (1 << (devad))
 #define MDIO_DEVS_C22PRESENT MDIO_DEVS_PRESENT(0)
 #define MDIO_DEVS_PMAPMD MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD)
@@ -197,9 +201,11 @@
 #define MDIO_PMA_10GBT_SNR_MAX 127
 #define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001
 #define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002
+#define MDIO_PMA_10GBR_FSRT_ENABLE 0x0001
 #define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001
 #define MDIO_PCS_10GBRT_STAT2_ERR 0x00ff
 #define MDIO_PCS_10GBRT_STAT2_BER 0x3f00
+#define MDIO_AN_10GBT_CTRL_ADVFSRT2_5G 0x0020
 #define MDIO_AN_10GBT_CTRL_ADV2_5G 0x0080
 #define MDIO_AN_10GBT_CTRL_ADV5G 0x0100
 #define MDIO_AN_10GBT_CTRL_ADV10G 0x1000
@@ -226,6 +232,7 @@
 #define MDIO_EEE_100GR_DS 0x2000
 #define MDIO_EEE_2_5GT 0x0001
 #define MDIO_EEE_5GT 0x0002
+#define MDIO_AN_THP_BP2_5GT 0x0008
 #define MDIO_PMA_NG_EXTABLE_2_5GBT 0x0001
 #define MDIO_PMA_NG_EXTABLE_5GBT 0x0002
 #define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001
diff --git a/libc/kernel/uapi/linux/mempolicy.h b/libc/kernel/uapi/linux/mempolicy.h
index 5425c0e..f92970f 100644
--- a/libc/kernel/uapi/linux/mempolicy.h
+++ b/libc/kernel/uapi/linux/mempolicy.h
@@ -25,6 +25,7 @@
   MPOL_BIND,
   MPOL_INTERLEAVE,
   MPOL_LOCAL,
+  MPOL_PREFERRED_MANY,
   MPOL_MAX,
 };
 #define MPOL_F_STATIC_NODES (1 << 15)
@@ -41,7 +42,9 @@
 #define MPOL_MF_INTERNAL (1 << 4)
 #define MPOL_MF_VALID (MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)
 #define MPOL_F_SHARED (1 << 0)
-#define MPOL_F_LOCAL (1 << 1)
 #define MPOL_F_MOF (1 << 3)
 #define MPOL_F_MORON (1 << 4)
+#define RECLAIM_ZONE (1 << 0)
+#define RECLAIM_WRITE (1 << 1)
+#define RECLAIM_UNMAP (1 << 2)
 #endif
diff --git a/libc/kernel/uapi/linux/module.h b/libc/kernel/uapi/linux/module.h
index f08dc67..34a4c56 100644
--- a/libc/kernel/uapi/linux/module.h
+++ b/libc/kernel/uapi/linux/module.h
@@ -20,4 +20,5 @@
 #define _UAPI_LINUX_MODULE_H
 #define MODULE_INIT_IGNORE_MODVERSIONS 1
 #define MODULE_INIT_IGNORE_VERMAGIC 2
+#define MODULE_INIT_COMPRESSED_FILE 4
 #endif
diff --git a/libc/kernel/uapi/linux/mount.h b/libc/kernel/uapi/linux/mount.h
index 5a112c9..2099b48 100644
--- a/libc/kernel/uapi/linux/mount.h
+++ b/libc/kernel/uapi/linux/mount.h
@@ -62,7 +62,8 @@
 #define MOVE_MOUNT_T_SYMLINKS 0x00000010
 #define MOVE_MOUNT_T_AUTOMOUNTS 0x00000020
 #define MOVE_MOUNT_T_EMPTY_PATH 0x00000040
-#define MOVE_MOUNT__MASK 0x00000077
+#define MOVE_MOUNT_SET_GROUP 0x00000100
+#define MOVE_MOUNT__MASK 0x00000177
 #define FSOPEN_CLOEXEC 0x00000001
 #define FSPICK_CLOEXEC 0x00000001
 #define FSPICK_SYMLINK_NOFOLLOW 0x00000002
@@ -89,6 +90,7 @@
 #define MOUNT_ATTR_STRICTATIME 0x00000020
 #define MOUNT_ATTR_NODIRATIME 0x00000080
 #define MOUNT_ATTR_IDMAP 0x00100000
+#define MOUNT_ATTR_NOSYMFOLLOW 0x00200000
 struct mount_attr {
   __u64 attr_set;
   __u64 attr_clr;
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index b15adf5..67b0ce3 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -20,6 +20,10 @@
 #define _UAPI_MPTCP_H
 #include <linux/const.h>
 #include <linux/types.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/socket.h>
+#include <sys/socket.h>
 #define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0)
 #define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1)
 #define MPTCP_SUBFLOW_FLAG_JOIN_REM _BITUL(2)
@@ -72,6 +76,7 @@
 #define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0)
 #define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
 #define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
+#define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3)
 enum {
   MPTCP_PM_CMD_UNSPEC,
   MPTCP_PM_CMD_ADD_ADDR,
@@ -99,6 +104,7 @@
   __u64 mptcpi_rcv_nxt;
   __u8 mptcpi_local_addr_used;
   __u8 mptcpi_local_addr_max;
+  __u8 mptcpi_csum_enabled;
 };
 enum mptcp_event_type {
   MPTCP_EVENT_UNSPEC = 0,
@@ -128,7 +134,40 @@
   MPTCP_ATTR_FLAGS,
   MPTCP_ATTR_TIMEOUT,
   MPTCP_ATTR_IF_IDX,
+  MPTCP_ATTR_RESET_REASON,
+  MPTCP_ATTR_RESET_FLAGS,
   __MPTCP_ATTR_AFTER_LAST
 };
 #define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1)
+#define MPTCP_RST_EUNSPEC 0
+#define MPTCP_RST_EMPTCP 1
+#define MPTCP_RST_ERESOURCE 2
+#define MPTCP_RST_EPROHIBIT 3
+#define MPTCP_RST_EWQ2BIG 4
+#define MPTCP_RST_EBADPERF 5
+#define MPTCP_RST_EMIDDLEBOX 6
+struct mptcp_subflow_data {
+  __u32 size_subflow_data;
+  __u32 num_subflows;
+  __u32 size_kernel;
+  __u32 size_user;
+} __attribute__((aligned(8)));
+struct mptcp_subflow_addrs {
+  union {
+    __kernel_sa_family_t sa_family;
+    struct sockaddr sa_local;
+    struct sockaddr_in sin_local;
+    struct sockaddr_in6 sin6_local;
+    struct __kernel_sockaddr_storage ss_local;
+  };
+  union {
+    struct sockaddr sa_remote;
+    struct sockaddr_in sin_remote;
+    struct sockaddr_in6 sin6_remote;
+    struct __kernel_sockaddr_storage ss_remote;
+  };
+};
+#define MPTCP_INFO 1
+#define MPTCP_TCPINFO 2
+#define MPTCP_SUBFLOW_ADDRS 3
 #endif
diff --git a/libc/kernel/uapi/linux/n_r3964.h b/libc/kernel/uapi/linux/n_r3964.h
deleted file mode 100644
index 5a7cccc..0000000
--- a/libc/kernel/uapi/linux/n_r3964.h
+++ /dev/null
@@ -1,46 +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__LINUX_N_R3964_H__
-#define _UAPI__LINUX_N_R3964_H__
-#define R3964_ENABLE_SIGNALS 0x5301
-#define R3964_SETPRIORITY 0x5302
-#define R3964_USE_BCC 0x5303
-#define R3964_READ_TELEGRAM 0x5304
-#define R3964_MASTER 0
-#define R3964_SLAVE 1
-#define R3964_SIG_ACK 0x0001
-#define R3964_SIG_DATA 0x0002
-#define R3964_SIG_ALL 0x000f
-#define R3964_SIG_NONE 0x0000
-#define R3964_USE_SIGIO 0x1000
-enum {
-  R3964_MSG_ACK = 1,
-  R3964_MSG_DATA
-};
-#define R3964_MAX_MSG_COUNT 32
-#define R3964_OK 0
-#define R3964_TX_FAIL - 1
-#define R3964_OVERFLOW - 2
-struct r3964_client_message {
-  int msg_id;
-  int arg;
-  int error_code;
-};
-#define R3964_MTU 256
-#endif
diff --git a/libc/kernel/uapi/linux/nbd-netlink.h b/libc/kernel/uapi/linux/nbd-netlink.h
index 9faf689..dffb077 100644
--- a/libc/kernel/uapi/linux/nbd-netlink.h
+++ b/libc/kernel/uapi/linux/nbd-netlink.h
@@ -32,6 +32,7 @@
   NBD_ATTR_SOCKETS,
   NBD_ATTR_DEAD_CONN_TIMEOUT,
   NBD_ATTR_DEVICE_LIST,
+  NBD_ATTR_BACKEND_IDENTIFIER,
   __NBD_ATTR_MAX,
 };
 #define NBD_ATTR_MAX (__NBD_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index e0e84aa..278f7d1 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -45,17 +45,19 @@
   NDA_PROTOCOL,
   NDA_NH_ID,
   NDA_FDB_EXT_ATTRS,
+  NDA_FLAGS_EXT,
   __NDA_MAX
 };
 #define NDA_MAX (__NDA_MAX - 1)
-#define NTF_USE 0x01
-#define NTF_SELF 0x02
-#define NTF_MASTER 0x04
-#define NTF_PROXY 0x08
-#define NTF_EXT_LEARNED 0x10
-#define NTF_OFFLOADED 0x20
-#define NTF_STICKY 0x40
-#define NTF_ROUTER 0x80
+#define NTF_USE (1 << 0)
+#define NTF_SELF (1 << 1)
+#define NTF_MASTER (1 << 2)
+#define NTF_PROXY (1 << 3)
+#define NTF_EXT_LEARNED (1 << 4)
+#define NTF_OFFLOADED (1 << 5)
+#define NTF_STICKY (1 << 6)
+#define NTF_ROUTER (1 << 7)
+#define NTF_EXT_MANAGED (1 << 0)
 #define NUD_INCOMPLETE 0x01
 #define NUD_REACHABLE 0x02
 #define NUD_STALE 0x04
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 373d1bb..510c0da 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -36,15 +36,26 @@
   SOF_TIMESTAMPING_OPT_STATS = (1 << 12),
   SOF_TIMESTAMPING_OPT_PKTINFO = (1 << 13),
   SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
-  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
+  SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
+  SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_BIND_PHC,
   SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
 };
 #define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_ACK)
+struct so_timestamping {
+  int flags;
+  int bind_phc;
+};
 struct hwtstamp_config {
   int flags;
   int tx_type;
   int rx_filter;
 };
+enum hwtstamp_flags {
+  HWTSTAMP_FLAG_BONDED_PHC_INDEX = (1 << 0),
+#define HWTSTAMP_FLAG_BONDED_PHC_INDEX HWTSTAMP_FLAG_BONDED_PHC_INDEX
+  HWTSTAMP_FLAG_LAST = HWTSTAMP_FLAG_BONDED_PHC_INDEX,
+  HWTSTAMP_FLAG_MASK = (HWTSTAMP_FLAG_LAST - 1) | HWTSTAMP_FLAG_LAST
+};
 enum hwtstamp_tx_types {
   HWTSTAMP_TX_OFF,
   HWTSTAMP_TX_ON,
diff --git a/libc/kernel/uapi/linux/netfilter.h b/libc/kernel/uapi/linux/netfilter.h
index 261b979..77b8a91 100644
--- a/libc/kernel/uapi/linux/netfilter.h
+++ b/libc/kernel/uapi/linux/netfilter.h
@@ -47,6 +47,7 @@
 };
 enum nf_dev_hooks {
   NF_NETDEV_INGRESS,
+  NF_NETDEV_EGRESS,
   NF_NETDEV_NUMHOOKS
 };
 enum {
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 0023a94..441cd60 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -223,6 +223,7 @@
 #define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
 enum nft_set_elem_flags {
   NFT_SET_ELEM_INTERVAL_END = 0x1,
+  NFT_SET_ELEM_CATCHALL = 0x2,
 };
 enum nft_set_elem_attributes {
   NFTA_SET_ELEM_UNSPEC,
@@ -385,6 +386,7 @@
   NFT_PAYLOAD_LL_HEADER,
   NFT_PAYLOAD_NETWORK_HEADER,
   NFT_PAYLOAD_TRANSPORT_HEADER,
+  NFT_PAYLOAD_INNER_HEADER,
 };
 enum nft_payload_csum_types {
   NFT_PAYLOAD_CSUM_NONE,
@@ -414,6 +416,7 @@
   NFT_EXTHDR_OP_IPV6,
   NFT_EXTHDR_OP_TCPOPT,
   NFT_EXTHDR_OP_IPV4,
+  NFT_EXTHDR_OP_SCTP,
   __NFT_EXTHDR_OP_MAX
 };
 #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1)
@@ -438,7 +441,8 @@
   NFT_META_OIF,
   NFT_META_IIFNAME,
   NFT_META_OIFNAME,
-  NFT_META_IIFTYPE,
+  NFT_META_IFTYPE,
+#define NFT_META_IIFTYPE NFT_META_IFTYPE
   NFT_META_OIFTYPE,
   NFT_META_SKUID,
   NFT_META_SKGID,
@@ -465,6 +469,7 @@
   NFT_META_TIME_HOUR,
   NFT_META_SDIF,
   NFT_META_SDIFNAME,
+  __NFT_META_IIFTYPE,
 };
 enum nft_rt_keys {
   NFT_RT_CLASSID,
@@ -512,6 +517,7 @@
   NFTA_SOCKET_UNSPEC,
   NFTA_SOCKET_KEY,
   NFTA_SOCKET_DREG,
+  NFTA_SOCKET_LEVEL,
   __NFTA_SOCKET_MAX
 };
 #define NFTA_SOCKET_MAX (__NFTA_SOCKET_MAX - 1)
@@ -519,6 +525,7 @@
   NFT_SOCKET_TRANSPARENT,
   NFT_SOCKET_MARK,
   NFT_SOCKET_WILDCARD,
+  NFT_SOCKET_CGROUPV2,
   __NFT_SOCKET_MAX
 };
 #define NFT_SOCKET_MAX (__NFT_SOCKET_MAX - 1)
@@ -601,6 +608,14 @@
   __NFTA_COUNTER_MAX
 };
 #define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1)
+enum nft_last_attributes {
+  NFTA_LAST_UNSPEC,
+  NFTA_LAST_SET,
+  NFTA_LAST_MSECS,
+  NFTA_LAST_PAD,
+  __NFTA_LAST_MAX
+};
+#define NFTA_LAST_MAX (__NFTA_LAST_MAX - 1)
 enum nft_log_attributes {
   NFTA_LOG_UNSPEC,
   NFTA_LOG_GROUP,
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink.h b/libc/kernel/uapi/linux/netfilter/nfnetlink.h
index 9145552..705de74 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink.h
@@ -64,7 +64,8 @@
 #define NFNL_SUBSYS_CTHELPER 9
 #define NFNL_SUBSYS_NFTABLES 10
 #define NFNL_SUBSYS_NFT_COMPAT 11
-#define NFNL_SUBSYS_COUNT 12
+#define NFNL_SUBSYS_HOOK 12
+#define NFNL_SUBSYS_COUNT 13
 #define NFNL_MSG_BATCH_BEGIN NLMSG_MIN_TYPE
 #define NFNL_MSG_BATCH_END NLMSG_MIN_TYPE + 1
 enum nfnl_batch_attributes {
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
index 4501e53..200f1a0 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
@@ -67,6 +67,7 @@
   CTA_LABELS_MASK,
   CTA_SYNPROXY,
   CTA_FILTER,
+  CTA_STATUS_MASK,
   __CTA_MAX
 };
 #define CTA_MAX (__CTA_MAX - 1)
@@ -249,6 +250,7 @@
   CTA_STATS_ERROR,
   CTA_STATS_SEARCH_RESTART,
   CTA_STATS_CLASH_RESOLVE,
+  CTA_STATS_CHAIN_TOOLONG,
   __CTA_STATS_MAX,
 };
 #define CTA_STATS_MAX (__CTA_STATS_MAX - 1)
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
new file mode 100644
index 0000000..ce1692c
--- /dev/null
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _NFNL_HOOK_H_
+#define _NFNL_HOOK_H_
+enum nfnl_hook_msg_types {
+  NFNL_MSG_HOOK_GET,
+  NFNL_MSG_HOOK_MAX,
+};
+enum nfnl_hook_attributes {
+  NFNLA_HOOK_UNSPEC,
+  NFNLA_HOOK_HOOKNUM,
+  NFNLA_HOOK_PRIORITY,
+  NFNLA_HOOK_DEV,
+  NFNLA_HOOK_FUNCTION_NAME,
+  NFNLA_HOOK_MODULE_NAME,
+  NFNLA_HOOK_CHAIN_INFO,
+  __NFNLA_HOOK_MAX
+};
+#define NFNLA_HOOK_MAX (__NFNLA_HOOK_MAX - 1)
+enum nfnl_hook_chain_info_attributes {
+  NFNLA_HOOK_INFO_UNSPEC,
+  NFNLA_HOOK_INFO_DESC,
+  NFNLA_HOOK_INFO_TYPE,
+  __NFNLA_HOOK_INFO_MAX,
+};
+#define NFNLA_HOOK_INFO_MAX (__NFNLA_HOOK_INFO_MAX - 1)
+enum nfnl_hook_chain_desc_attributes {
+  NFNLA_CHAIN_UNSPEC,
+  NFNLA_CHAIN_TABLE,
+  NFNLA_CHAIN_FAMILY,
+  NFNLA_CHAIN_NAME,
+  __NFNLA_CHAIN_MAX,
+};
+#define NFNLA_CHAIN_MAX (__NFNLA_CHAIN_MAX - 1)
+enum nfnl_hook_chaintype {
+  NFNL_HOOK_TYPE_NFTABLES = 0x1,
+};
+#endif
diff --git a/libc/kernel/uapi/linux/netfilter/xt_SECMARK.h b/libc/kernel/uapi/linux/netfilter/xt_SECMARK.h
index 23606df..6dd8dbc 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_SECMARK.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_SECMARK.h
@@ -26,4 +26,9 @@
   __u32 secid;
   char secctx[SECMARK_SECCTX_MAX];
 };
+struct xt_secmark_target_info_v1 {
+  __u8 mode;
+  char secctx[SECMARK_SECCTX_MAX];
+  __u32 secid;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index da6a46b..77825cc 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -80,7 +80,7 @@
 #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
 #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
 #define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
-#define NLMSG_DATA(nlh) ((void *) (((char *) nlh) + NLMSG_LENGTH(0)))
+#define NLMSG_DATA(nlh) ((void *) (((char *) nlh) + NLMSG_HDRLEN))
 #define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), (struct nlmsghdr *) (((char *) (nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
 #define NLMSG_OK(nlh,len) ((len) >= (int) sizeof(struct nlmsghdr) && (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && (nlh)->nlmsg_len <= (len))
 #define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
diff --git a/libc/kernel/uapi/linux/nexthop.h b/libc/kernel/uapi/linux/nexthop.h
index f99a074..4bc9ff0 100644
--- a/libc/kernel/uapi/linux/nexthop.h
+++ b/libc/kernel/uapi/linux/nexthop.h
@@ -34,6 +34,7 @@
 };
 enum {
   NEXTHOP_GRP_TYPE_MPATH,
+  NEXTHOP_GRP_TYPE_RES,
   __NEXTHOP_GRP_TYPE_MAX,
 };
 #define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
@@ -50,7 +51,28 @@
   NHA_GROUPS,
   NHA_MASTER,
   NHA_FDB,
+  NHA_RES_GROUP,
+  NHA_RES_BUCKET,
   __NHA_MAX,
 };
 #define NHA_MAX (__NHA_MAX - 1)
+enum {
+  NHA_RES_GROUP_UNSPEC,
+  NHA_RES_GROUP_PAD = NHA_RES_GROUP_UNSPEC,
+  NHA_RES_GROUP_BUCKETS,
+  NHA_RES_GROUP_IDLE_TIMER,
+  NHA_RES_GROUP_UNBALANCED_TIMER,
+  NHA_RES_GROUP_UNBALANCED_TIME,
+  __NHA_RES_GROUP_MAX,
+};
+#define NHA_RES_GROUP_MAX (__NHA_RES_GROUP_MAX - 1)
+enum {
+  NHA_RES_BUCKET_UNSPEC,
+  NHA_RES_BUCKET_PAD = NHA_RES_BUCKET_UNSPEC,
+  NHA_RES_BUCKET_INDEX,
+  NHA_RES_BUCKET_IDLE_TIME,
+  NHA_RES_BUCKET_NH_ID,
+  __NHA_RES_BUCKET_MAX,
+};
+#define NHA_RES_BUCKET_MAX (__NHA_RES_BUCKET_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/nfc.h b/libc/kernel/uapi/linux/nfc.h
index 72e3520..ff980f4 100644
--- a/libc/kernel/uapi/linux/nfc.h
+++ b/libc/kernel/uapi/linux/nfc.h
@@ -139,14 +139,14 @@
 #define NFC_SE_DISABLED 0x0
 #define NFC_SE_ENABLED 0x1
 struct sockaddr_nfc {
-  sa_family_t sa_family;
+  __kernel_sa_family_t sa_family;
   __u32 dev_idx;
   __u32 target_idx;
   __u32 nfc_protocol;
 };
 #define NFC_LLCP_MAX_SERVICE_NAME 63
 struct sockaddr_nfc_llcp {
-  sa_family_t sa_family;
+  __kernel_sa_family_t sa_family;
   __u32 dev_idx;
   __u32 target_idx;
   __u32 nfc_protocol;
@@ -154,7 +154,7 @@
   __u8 ssap;
   char service_name[NFC_LLCP_MAX_SERVICE_NAME];
 ;
-  size_t service_name_len;
+  __kernel_size_t service_name_len;
 };
 #define NFC_SOCKPROTO_RAW 0
 #define NFC_SOCKPROTO_LLCP 1
diff --git a/libc/kernel/uapi/linux/nfsd/nfsfh.h b/libc/kernel/uapi/linux/nfsd/nfsfh.h
deleted file mode 100644
index 1a805c3..0000000
--- a/libc/kernel/uapi/linux/nfsd/nfsfh.h
+++ /dev/null
@@ -1,63 +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_LINUX_NFSD_FH_H
-#define _UAPI_LINUX_NFSD_FH_H
-#include <linux/types.h>
-#include <linux/nfs.h>
-#include <linux/nfs2.h>
-#include <linux/nfs3.h>
-#include <linux/nfs4.h>
-struct nfs_fhbase_old {
-  __u32 fb_dcookie;
-  __u32 fb_ino;
-  __u32 fb_dirino;
-  __u32 fb_dev;
-  __u32 fb_xdev;
-  __u32 fb_xino;
-  __u32 fb_generation;
-};
-struct nfs_fhbase_new {
-  __u8 fb_version;
-  __u8 fb_auth_type;
-  __u8 fb_fsid_type;
-  __u8 fb_fileid_type;
-  __u32 fb_auth[1];
-};
-struct knfsd_fh {
-  unsigned int fh_size;
-  union {
-    struct nfs_fhbase_old fh_old;
-    __u32 fh_pad[NFS4_FHSIZE / 4];
-    struct nfs_fhbase_new fh_new;
-  } fh_base;
-};
-#define ofh_dcookie fh_base.fh_old.fb_dcookie
-#define ofh_ino fh_base.fh_old.fb_ino
-#define ofh_dirino fh_base.fh_old.fb_dirino
-#define ofh_dev fh_base.fh_old.fb_dev
-#define ofh_xdev fh_base.fh_old.fb_xdev
-#define ofh_xino fh_base.fh_old.fb_xino
-#define ofh_generation fh_base.fh_old.fb_generation
-#define fh_version fh_base.fh_new.fb_version
-#define fh_fsid_type fh_base.fh_new.fb_fsid_type
-#define fh_auth_type fh_base.fh_new.fb_auth_type
-#define fh_fileid_type fh_base.fh_new.fb_fileid_type
-#define fh_fsid fh_base.fh_new.fb_auth
-#define fh_auth fh_base.fh_new.fb_auth
-#endif
diff --git a/libc/kernel/uapi/linux/nl80211-vnd-intel.h b/libc/kernel/uapi/linux/nl80211-vnd-intel.h
new file mode 100644
index 0000000..9ade75a
--- /dev/null
+++ b/libc/kernel/uapi/linux/nl80211-vnd-intel.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __VENDOR_CMD_INTEL_H__
+#define __VENDOR_CMD_INTEL_H__
+#define INTEL_OUI 0x001735
+enum iwl_mvm_vendor_cmd {
+  IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO = 0x2d,
+  IWL_MVM_VENDOR_CMD_HOST_GET_OWNERSHIP = 0x30,
+  IWL_MVM_VENDOR_CMD_ROAMING_FORBIDDEN_EVENT = 0x32,
+};
+enum iwl_vendor_auth_akm_mode {
+  IWL_VENDOR_AUTH_OPEN,
+  IWL_VENDOR_AUTH_RSNA = 0x6,
+  IWL_VENDOR_AUTH_RSNA_PSK,
+  IWL_VENDOR_AUTH_SAE = 0x9,
+  IWL_VENDOR_AUTH_MAX,
+};
+enum iwl_mvm_vendor_attr {
+  __IWL_MVM_VENDOR_ATTR_INVALID = 0x00,
+  IWL_MVM_VENDOR_ATTR_VIF_ADDR = 0x02,
+  IWL_MVM_VENDOR_ATTR_ADDR = 0x0a,
+  IWL_MVM_VENDOR_ATTR_SSID = 0x3d,
+  IWL_MVM_VENDOR_ATTR_STA_CIPHER = 0x51,
+  IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN = 0x64,
+  IWL_MVM_VENDOR_ATTR_AUTH_MODE = 0x65,
+  IWL_MVM_VENDOR_ATTR_CHANNEL_NUM = 0x66,
+  IWL_MVM_VENDOR_ATTR_BAND = 0x69,
+  IWL_MVM_VENDOR_ATTR_COLLOC_CHANNEL = 0x70,
+  IWL_MVM_VENDOR_ATTR_COLLOC_ADDR = 0x71,
+  NUM_IWL_MVM_VENDOR_ATTR,
+  MAX_IWL_MVM_VENDOR_ATTR = NUM_IWL_MVM_VENDOR_ATTR - 1,
+};
+#endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 5181160..e902178 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -178,6 +178,13 @@
   NL80211_CMD_UNPROT_BEACON,
   NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
   NL80211_CMD_SET_SAR_SPECS,
+  NL80211_CMD_OBSS_COLOR_COLLISION,
+  NL80211_CMD_COLOR_CHANGE_REQUEST,
+  NL80211_CMD_COLOR_CHANGE_STARTED,
+  NL80211_CMD_COLOR_CHANGE_ABORTED,
+  NL80211_CMD_COLOR_CHANGE_COMPLETED,
+  NL80211_CMD_SET_FILS_AAD,
+  NL80211_CMD_ASSOC_COMEBACK,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -496,6 +503,14 @@
   NL80211_ATTR_RECONNECT_REQUESTED,
   NL80211_ATTR_SAR_SPEC,
   NL80211_ATTR_DISABLE_HE,
+  NL80211_ATTR_OBSS_COLOR_BITMAP,
+  NL80211_ATTR_COLOR_CHANGE_COUNT,
+  NL80211_ATTR_COLOR_CHANGE_COLOR,
+  NL80211_ATTR_COLOR_CHANGE_ELEMS,
+  NL80211_ATTR_MBSSID_CONFIG,
+  NL80211_ATTR_MBSSID_ELEMS,
+  NL80211_ATTR_RADAR_BACKGROUND,
+  NL80211_ATTR_AP_SETTINGS_FLAGS,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -738,6 +753,7 @@
   NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
   NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
   NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
+  NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
   __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
   NL80211_BAND_IFTYPE_ATTR_MAX = __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST - 1
 };
@@ -1137,6 +1153,7 @@
   NL80211_BAND_60GHZ,
   NL80211_BAND_6GHZ,
   NL80211_BAND_S1GHZ,
+  NL80211_BAND_LC,
   NUM_NL80211_BANDS,
 };
 enum nl80211_ps_state {
@@ -1359,6 +1376,9 @@
   NL80211_TDLS_ENABLE_LINK,
   NL80211_TDLS_DISABLE_LINK,
 };
+enum nl80211_ap_sme_features {
+  NL80211_AP_SME_SA_QUERY_OFFLOAD = 1 << 0,
+};
 enum nl80211_feature_flags {
   NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
   NL80211_FEATURE_HT_IBSS = 1 << 1,
@@ -1449,6 +1469,12 @@
   NL80211_EXT_FEATURE_FILS_DISCOVERY,
   NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
   NL80211_EXT_FEATURE_BEACON_RATE_HE,
+  NL80211_EXT_FEATURE_SECURE_LTF,
+  NL80211_EXT_FEATURE_SECURE_RTT,
+  NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
+  NL80211_EXT_FEATURE_BSS_COLOR,
+  NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
+  NL80211_EXT_FEATURE_RADAR_BACKGROUND,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
@@ -1533,6 +1559,7 @@
   NL80211_TDLS_PEER_HT = 1 << 0,
   NL80211_TDLS_PEER_VHT = 1 << 1,
   NL80211_TDLS_PEER_WMM = 1 << 2,
+  NL80211_TDLS_PEER_HE = 1 << 3,
 };
 enum nl80211_sched_scan_plan {
   __NL80211_SCHED_SCAN_PLAN_INVALID,
@@ -1720,6 +1747,8 @@
   NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
   NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
   NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
+  NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK,
+  NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR,
   NUM_NL80211_PMSR_FTM_REQ_ATTR,
   NL80211_PMSR_FTM_REQ_ATTR_MAX = NUM_NL80211_PMSR_FTM_REQ_ATTR - 1
 };
@@ -1827,4 +1856,18 @@
   __NL80211_SAR_ATTR_SPECS_LAST,
   NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1,
 };
+enum nl80211_mbssid_config_attributes {
+  __NL80211_MBSSID_CONFIG_ATTR_INVALID,
+  NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES,
+  NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY,
+  NL80211_MBSSID_CONFIG_ATTR_INDEX,
+  NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX,
+  NL80211_MBSSID_CONFIG_ATTR_EMA,
+  __NL80211_MBSSID_CONFIG_ATTR_LAST,
+  NL80211_MBSSID_CONFIG_ATTR_MAX = __NL80211_MBSSID_CONFIG_ATTR_LAST - 1,
+};
+enum nl80211_ap_settings_flags {
+  NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = 1 << 0,
+  NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 7db5cd5..1f8ae17 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -43,6 +43,7 @@
   OVS_DP_ATTR_USER_FEATURES,
   OVS_DP_ATTR_PAD,
   OVS_DP_ATTR_MASKS_CACHE_SIZE,
+  OVS_DP_ATTR_PER_CPU_PIDS,
   __OVS_DP_ATTR_MAX
 };
 #define OVS_DP_ATTR_MAX (__OVS_DP_ATTR_MAX - 1)
@@ -72,6 +73,7 @@
 #define OVS_DP_F_UNALIGNED (1 << 0)
 #define OVS_DP_F_VPORT_PIDS (1 << 1)
 #define OVS_DP_F_TC_RECIRC_SHARING (1 << 2)
+#define OVS_DP_F_DISPATCH_UPCALL_PER_CPU (1 << 3)
 #define OVSP_LOCAL ((__u32) 0)
 #define OVS_PACKET_FAMILY "ovs_packet"
 #define OVS_PACKET_VERSION 0x1
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index 81450a7..46612da 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -245,21 +245,21 @@
 #define PCI_SID_ESR_NSLOTS 0x1f
 #define PCI_SID_ESR_FIC 0x20
 #define PCI_SID_CHASSIS_NR 3
-#define PCI_MSI_FLAGS 2
+#define PCI_MSI_FLAGS 0x02
 #define PCI_MSI_FLAGS_ENABLE 0x0001
 #define PCI_MSI_FLAGS_QMASK 0x000e
 #define PCI_MSI_FLAGS_QSIZE 0x0070
 #define PCI_MSI_FLAGS_64BIT 0x0080
 #define PCI_MSI_FLAGS_MASKBIT 0x0100
 #define PCI_MSI_RFU 3
-#define PCI_MSI_ADDRESS_LO 4
-#define PCI_MSI_ADDRESS_HI 8
-#define PCI_MSI_DATA_32 8
-#define PCI_MSI_MASK_32 12
-#define PCI_MSI_PENDING_32 16
-#define PCI_MSI_DATA_64 12
-#define PCI_MSI_MASK_64 16
-#define PCI_MSI_PENDING_64 20
+#define PCI_MSI_ADDRESS_LO 0x04
+#define PCI_MSI_ADDRESS_HI 0x08
+#define PCI_MSI_DATA_32 0x08
+#define PCI_MSI_MASK_32 0x0c
+#define PCI_MSI_PENDING_32 0x10
+#define PCI_MSI_DATA_64 0x0c
+#define PCI_MSI_MASK_64 0x10
+#define PCI_MSI_PENDING_64 0x14
 #define PCI_MSIX_FLAGS 2
 #define PCI_MSIX_FLAGS_QSIZE 0x07FF
 #define PCI_MSIX_FLAGS_MASKALL 0x4000
@@ -273,10 +273,10 @@
 #define PCI_MSIX_FLAGS_BIRMASK PCI_MSIX_PBA_BIR
 #define PCI_CAP_MSIX_SIZEOF 12
 #define PCI_MSIX_ENTRY_SIZE 16
-#define PCI_MSIX_ENTRY_LOWER_ADDR 0
-#define PCI_MSIX_ENTRY_UPPER_ADDR 4
-#define PCI_MSIX_ENTRY_DATA 8
-#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
+#define PCI_MSIX_ENTRY_LOWER_ADDR 0x0
+#define PCI_MSIX_ENTRY_UPPER_ADDR 0x4
+#define PCI_MSIX_ENTRY_DATA 0x8
+#define PCI_MSIX_ENTRY_VECTOR_CTRL 0xc
 #define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001
 #define PCI_CHSWP_CSR 2
 #define PCI_CHSWP_DHA 0x01
@@ -379,7 +379,7 @@
 #define PCI_X_BRIDGE_STATUS 4
 #define PCI_SSVID_VENDOR_ID 4
 #define PCI_SSVID_DEVICE_ID 6
-#define PCI_EXP_FLAGS 2
+#define PCI_EXP_FLAGS 0x02
 #define PCI_EXP_FLAGS_VERS 0x000f
 #define PCI_EXP_FLAGS_TYPE 0x00f0
 #define PCI_EXP_TYPE_ENDPOINT 0x0
@@ -393,7 +393,7 @@
 #define PCI_EXP_TYPE_RC_EC 0xa
 #define PCI_EXP_FLAGS_SLOT 0x0100
 #define PCI_EXP_FLAGS_IRQ 0x3e00
-#define PCI_EXP_DEVCAP 4
+#define PCI_EXP_DEVCAP 0x04
 #define PCI_EXP_DEVCAP_PAYLOAD 0x00000007
 #define PCI_EXP_DEVCAP_PHANTOM 0x00000018
 #define PCI_EXP_DEVCAP_EXT_TAG 0x00000020
@@ -406,13 +406,19 @@
 #define PCI_EXP_DEVCAP_PWR_VAL 0x03fc0000
 #define PCI_EXP_DEVCAP_PWR_SCL 0x0c000000
 #define PCI_EXP_DEVCAP_FLR 0x10000000
-#define PCI_EXP_DEVCTL 8
+#define PCI_EXP_DEVCTL 0x08
 #define PCI_EXP_DEVCTL_CERE 0x0001
 #define PCI_EXP_DEVCTL_NFERE 0x0002
 #define PCI_EXP_DEVCTL_FERE 0x0004
 #define PCI_EXP_DEVCTL_URRE 0x0008
 #define PCI_EXP_DEVCTL_RELAX_EN 0x0010
 #define PCI_EXP_DEVCTL_PAYLOAD 0x00e0
+#define PCI_EXP_DEVCTL_PAYLOAD_128B 0x0000
+#define PCI_EXP_DEVCTL_PAYLOAD_256B 0x0020
+#define PCI_EXP_DEVCTL_PAYLOAD_512B 0x0040
+#define PCI_EXP_DEVCTL_PAYLOAD_1024B 0x0060
+#define PCI_EXP_DEVCTL_PAYLOAD_2048B 0x0080
+#define PCI_EXP_DEVCTL_PAYLOAD_4096B 0x00a0
 #define PCI_EXP_DEVCTL_EXT_TAG 0x0100
 #define PCI_EXP_DEVCTL_PHANTOM 0x0200
 #define PCI_EXP_DEVCTL_AUX_PME 0x0400
@@ -425,7 +431,7 @@
 #define PCI_EXP_DEVCTL_READRQ_2048B 0x4000
 #define PCI_EXP_DEVCTL_READRQ_4096B 0x5000
 #define PCI_EXP_DEVCTL_BCR_FLR 0x8000
-#define PCI_EXP_DEVSTA 10
+#define PCI_EXP_DEVSTA 0x0a
 #define PCI_EXP_DEVSTA_CED 0x0001
 #define PCI_EXP_DEVSTA_NFED 0x0002
 #define PCI_EXP_DEVSTA_FED 0x0004
@@ -433,7 +439,7 @@
 #define PCI_EXP_DEVSTA_AUXPD 0x0010
 #define PCI_EXP_DEVSTA_TRPND 0x0020
 #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V1 12
-#define PCI_EXP_LNKCAP 12
+#define PCI_EXP_LNKCAP 0x0c
 #define PCI_EXP_LNKCAP_SLS 0x0000000f
 #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001
 #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002
@@ -452,7 +458,7 @@
 #define PCI_EXP_LNKCAP_DLLLARC 0x00100000
 #define PCI_EXP_LNKCAP_LBNC 0x00200000
 #define PCI_EXP_LNKCAP_PN 0xff000000
-#define PCI_EXP_LNKCTL 16
+#define PCI_EXP_LNKCTL 0x10
 #define PCI_EXP_LNKCTL_ASPMC 0x0003
 #define PCI_EXP_LNKCTL_ASPM_L0S 0x0001
 #define PCI_EXP_LNKCTL_ASPM_L1 0x0002
@@ -465,7 +471,7 @@
 #define PCI_EXP_LNKCTL_HAWD 0x0200
 #define PCI_EXP_LNKCTL_LBMIE 0x0400
 #define PCI_EXP_LNKCTL_LABIE 0x0800
-#define PCI_EXP_LNKSTA 18
+#define PCI_EXP_LNKSTA 0x12
 #define PCI_EXP_LNKSTA_CLS 0x000f
 #define PCI_EXP_LNKSTA_CLS_2_5GB 0x0001
 #define PCI_EXP_LNKSTA_CLS_5_0GB 0x0002
@@ -485,7 +491,7 @@
 #define PCI_EXP_LNKSTA_LBMS 0x4000
 #define PCI_EXP_LNKSTA_LABS 0x8000
 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V1 20
-#define PCI_EXP_SLTCAP 20
+#define PCI_EXP_SLTCAP 0x14
 #define PCI_EXP_SLTCAP_ABP 0x00000001
 #define PCI_EXP_SLTCAP_PCP 0x00000002
 #define PCI_EXP_SLTCAP_MRLSP 0x00000004
@@ -498,7 +504,7 @@
 #define PCI_EXP_SLTCAP_EIP 0x00020000
 #define PCI_EXP_SLTCAP_NCCS 0x00040000
 #define PCI_EXP_SLTCAP_PSN 0xfff80000
-#define PCI_EXP_SLTCTL 24
+#define PCI_EXP_SLTCTL 0x18
 #define PCI_EXP_SLTCTL_ABPE 0x0001
 #define PCI_EXP_SLTCTL_PFDE 0x0002
 #define PCI_EXP_SLTCTL_MRLSCE 0x0004
@@ -520,7 +526,7 @@
 #define PCI_EXP_SLTCTL_EIC 0x0800
 #define PCI_EXP_SLTCTL_DLLSCE 0x1000
 #define PCI_EXP_SLTCTL_IBPD_DISABLE 0x4000
-#define PCI_EXP_SLTSTA 26
+#define PCI_EXP_SLTSTA 0x1a
 #define PCI_EXP_SLTSTA_ABP 0x0001
 #define PCI_EXP_SLTSTA_PFD 0x0002
 #define PCI_EXP_SLTSTA_MRLSC 0x0004
@@ -530,18 +536,18 @@
 #define PCI_EXP_SLTSTA_PDS 0x0040
 #define PCI_EXP_SLTSTA_EIS 0x0080
 #define PCI_EXP_SLTSTA_DLLSC 0x0100
-#define PCI_EXP_RTCTL 28
+#define PCI_EXP_RTCTL 0x1c
 #define PCI_EXP_RTCTL_SECEE 0x0001
 #define PCI_EXP_RTCTL_SENFEE 0x0002
 #define PCI_EXP_RTCTL_SEFEE 0x0004
 #define PCI_EXP_RTCTL_PMEIE 0x0008
 #define PCI_EXP_RTCTL_CRSSVE 0x0010
-#define PCI_EXP_RTCAP 30
+#define PCI_EXP_RTCAP 0x1e
 #define PCI_EXP_RTCAP_CRSVIS 0x0001
-#define PCI_EXP_RTSTA 32
+#define PCI_EXP_RTSTA 0x20
 #define PCI_EXP_RTSTA_PME 0x00010000
 #define PCI_EXP_RTSTA_PENDING 0x00020000
-#define PCI_EXP_DEVCAP2 36
+#define PCI_EXP_DEVCAP2 0x24
 #define PCI_EXP_DEVCAP2_COMP_TMOUT_DIS 0x00000010
 #define PCI_EXP_DEVCAP2_ARI 0x00000020
 #define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040
@@ -553,7 +559,7 @@
 #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000
 #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000
 #define PCI_EXP_DEVCAP2_EE_PREFIX 0x00200000
-#define PCI_EXP_DEVCTL2 40
+#define PCI_EXP_DEVCTL2 0x28
 #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f
 #define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010
 #define PCI_EXP_DEVCTL2_ARI 0x0020
@@ -565,9 +571,9 @@
 #define PCI_EXP_DEVCTL2_OBFF_MSGA_EN 0x2000
 #define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000
 #define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000
-#define PCI_EXP_DEVSTA2 42
-#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 44
-#define PCI_EXP_LNKCAP2 44
+#define PCI_EXP_DEVSTA2 0x2a
+#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c
+#define PCI_EXP_LNKCAP2 0x2c
 #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002
 #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004
 #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008
@@ -575,7 +581,7 @@
 #define PCI_EXP_LNKCAP2_SLS_32_0GB 0x00000020
 #define PCI_EXP_LNKCAP2_SLS_64_0GB 0x00000040
 #define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100
-#define PCI_EXP_LNKCTL2 48
+#define PCI_EXP_LNKCTL2 0x30
 #define PCI_EXP_LNKCTL2_TLS 0x000f
 #define PCI_EXP_LNKCTL2_TLS_2_5GT 0x0001
 #define PCI_EXP_LNKCTL2_TLS_5_0GT 0x0002
@@ -586,12 +592,12 @@
 #define PCI_EXP_LNKCTL2_ENTER_COMP 0x0010
 #define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380
 #define PCI_EXP_LNKCTL2_HASD 0x0020
-#define PCI_EXP_LNKSTA2 50
-#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52
-#define PCI_EXP_SLTCAP2 52
+#define PCI_EXP_LNKSTA2 0x32
+#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32
+#define PCI_EXP_SLTCAP2 0x34
 #define PCI_EXP_SLTCAP2_IBPD 0x00000001
-#define PCI_EXP_SLTCTL2 56
-#define PCI_EXP_SLTSTA2 58
+#define PCI_EXP_SLTCTL2 0x38
+#define PCI_EXP_SLTSTA2 0x3a
 #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
 #define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
 #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
@@ -631,7 +637,7 @@
 #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_16GT
 #define PCI_EXT_CAP_DSN_SIZEOF 12
 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
-#define PCI_ERR_UNCOR_STATUS 4
+#define PCI_ERR_UNCOR_STATUS 0x04
 #define PCI_ERR_UNC_UND 0x00000001
 #define PCI_ERR_UNC_DLP 0x00000010
 #define PCI_ERR_UNC_SURPDN 0x00000020
@@ -649,9 +655,9 @@
 #define PCI_ERR_UNC_MCBTLP 0x00800000
 #define PCI_ERR_UNC_ATOMEG 0x01000000
 #define PCI_ERR_UNC_TLPPRE 0x02000000
-#define PCI_ERR_UNCOR_MASK 8
-#define PCI_ERR_UNCOR_SEVER 12
-#define PCI_ERR_COR_STATUS 16
+#define PCI_ERR_UNCOR_MASK 0x08
+#define PCI_ERR_UNCOR_SEVER 0x0c
+#define PCI_ERR_COR_STATUS 0x10
 #define PCI_ERR_COR_RCVR 0x00000001
 #define PCI_ERR_COR_BAD_TLP 0x00000040
 #define PCI_ERR_COR_BAD_DLLP 0x00000080
@@ -660,19 +666,19 @@
 #define PCI_ERR_COR_ADV_NFAT 0x00002000
 #define PCI_ERR_COR_INTERNAL 0x00004000
 #define PCI_ERR_COR_LOG_OVER 0x00008000
-#define PCI_ERR_COR_MASK 20
-#define PCI_ERR_CAP 24
-#define PCI_ERR_CAP_FEP(x) ((x) & 31)
+#define PCI_ERR_COR_MASK 0x14
+#define PCI_ERR_CAP 0x18
+#define PCI_ERR_CAP_FEP(x) ((x) & 0x1f)
 #define PCI_ERR_CAP_ECRC_GENC 0x00000020
 #define PCI_ERR_CAP_ECRC_GENE 0x00000040
 #define PCI_ERR_CAP_ECRC_CHKC 0x00000080
 #define PCI_ERR_CAP_ECRC_CHKE 0x00000100
-#define PCI_ERR_HEADER_LOG 28
-#define PCI_ERR_ROOT_COMMAND 44
+#define PCI_ERR_HEADER_LOG 0x1c
+#define PCI_ERR_ROOT_COMMAND 0x2c
 #define PCI_ERR_ROOT_CMD_COR_EN 0x00000001
 #define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002
 #define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004
-#define PCI_ERR_ROOT_STATUS 48
+#define PCI_ERR_ROOT_STATUS 0x30
 #define PCI_ERR_ROOT_COR_RCV 0x00000001
 #define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002
 #define PCI_ERR_ROOT_UNCOR_RCV 0x00000004
@@ -681,48 +687,48 @@
 #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020
 #define PCI_ERR_ROOT_FATAL_RCV 0x00000040
 #define PCI_ERR_ROOT_AER_IRQ 0xf8000000
-#define PCI_ERR_ROOT_ERR_SRC 52
-#define PCI_VC_PORT_CAP1 4
+#define PCI_ERR_ROOT_ERR_SRC 0x34
+#define PCI_VC_PORT_CAP1 0x04
 #define PCI_VC_CAP1_EVCC 0x00000007
 #define PCI_VC_CAP1_LPEVCC 0x00000070
 #define PCI_VC_CAP1_ARB_SIZE 0x00000c00
-#define PCI_VC_PORT_CAP2 8
+#define PCI_VC_PORT_CAP2 0x08
 #define PCI_VC_CAP2_32_PHASE 0x00000002
 #define PCI_VC_CAP2_64_PHASE 0x00000004
 #define PCI_VC_CAP2_128_PHASE 0x00000008
 #define PCI_VC_CAP2_ARB_OFF 0xff000000
-#define PCI_VC_PORT_CTRL 12
+#define PCI_VC_PORT_CTRL 0x0c
 #define PCI_VC_PORT_CTRL_LOAD_TABLE 0x00000001
-#define PCI_VC_PORT_STATUS 14
+#define PCI_VC_PORT_STATUS 0x0e
 #define PCI_VC_PORT_STATUS_TABLE 0x00000001
-#define PCI_VC_RES_CAP 16
+#define PCI_VC_RES_CAP 0x10
 #define PCI_VC_RES_CAP_32_PHASE 0x00000002
 #define PCI_VC_RES_CAP_64_PHASE 0x00000004
 #define PCI_VC_RES_CAP_128_PHASE 0x00000008
 #define PCI_VC_RES_CAP_128_PHASE_TB 0x00000010
 #define PCI_VC_RES_CAP_256_PHASE 0x00000020
 #define PCI_VC_RES_CAP_ARB_OFF 0xff000000
-#define PCI_VC_RES_CTRL 20
+#define PCI_VC_RES_CTRL 0x14
 #define PCI_VC_RES_CTRL_LOAD_TABLE 0x00010000
 #define PCI_VC_RES_CTRL_ARB_SELECT 0x000e0000
 #define PCI_VC_RES_CTRL_ID 0x07000000
 #define PCI_VC_RES_CTRL_ENABLE 0x80000000
-#define PCI_VC_RES_STATUS 26
+#define PCI_VC_RES_STATUS 0x1a
 #define PCI_VC_RES_STATUS_TABLE 0x00000001
 #define PCI_VC_RES_STATUS_NEGO 0x00000002
 #define PCI_CAP_VC_BASE_SIZEOF 0x10
-#define PCI_CAP_VC_PER_VC_SIZEOF 0x0C
-#define PCI_PWR_DSR 4
-#define PCI_PWR_DATA 8
+#define PCI_CAP_VC_PER_VC_SIZEOF 0x0c
+#define PCI_PWR_DSR 0x04
+#define PCI_PWR_DATA 0x08
 #define PCI_PWR_DATA_BASE(x) ((x) & 0xff)
 #define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3)
 #define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7)
 #define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3)
 #define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7)
 #define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7)
-#define PCI_PWR_CAP 12
+#define PCI_PWR_CAP 0x0c
 #define PCI_PWR_CAP_BUDGET(x) ((x) & 1)
-#define PCI_EXT_CAP_PWR_SIZEOF 16
+#define PCI_EXT_CAP_PWR_SIZEOF 0x10
 #define PCI_RCEC_RCIEP_BITMAP 4
 #define PCI_RCEC_BUSN 8
 #define PCI_RCEC_BUSN_REG_VER 0x02
@@ -822,7 +828,7 @@
 #define PCI_SRIOV_VFM_MI 0x1
 #define PCI_SRIOV_VFM_MO 0x2
 #define PCI_SRIOV_VFM_AV 0x3
-#define PCI_EXT_CAP_SRIOV_SIZEOF 64
+#define PCI_EXT_CAP_SRIOV_SIZEOF 0x40
 #define PCI_LTR_MAX_SNOOP_LAT 0x4
 #define PCI_LTR_MAX_NOSNOOP_LAT 0x6
 #define PCI_LTR_VALUE_MASK 0x000003ff
@@ -865,25 +871,25 @@
 #define PCI_TPH_LOC_MSIX 0x400
 #define PCI_TPH_CAP_ST_MASK 0x07FF0000
 #define PCI_TPH_CAP_ST_SHIFT 16
-#define PCI_TPH_BASE_SIZEOF 12
-#define PCI_EXP_DPC_CAP 4
+#define PCI_TPH_BASE_SIZEOF 0xc
+#define PCI_EXP_DPC_CAP 0x04
 #define PCI_EXP_DPC_IRQ 0x001F
 #define PCI_EXP_DPC_CAP_RP_EXT 0x0020
 #define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040
 #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080
 #define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00
 #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000
-#define PCI_EXP_DPC_CTL 6
+#define PCI_EXP_DPC_CTL 0x06
 #define PCI_EXP_DPC_CTL_EN_FATAL 0x0001
 #define PCI_EXP_DPC_CTL_EN_NONFATAL 0x0002
 #define PCI_EXP_DPC_CTL_INT_EN 0x0008
-#define PCI_EXP_DPC_STATUS 8
+#define PCI_EXP_DPC_STATUS 0x08
 #define PCI_EXP_DPC_STATUS_TRIGGER 0x0001
 #define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006
 #define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008
 #define PCI_EXP_DPC_RP_BUSY 0x0010
 #define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060
-#define PCI_EXP_DPC_SOURCE_ID 10
+#define PCI_EXP_DPC_SOURCE_ID 0x0A
 #define PCI_EXP_DPC_RP_PIO_STATUS 0x0C
 #define PCI_EXP_DPC_RP_PIO_MASK 0x10
 #define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14
@@ -920,7 +926,11 @@
 #define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000
 #define PCI_L1SS_CTL2 0x0c
 #define PCI_DVSEC_HEADER1 0x4
+#define PCI_DVSEC_HEADER1_VID(x) ((x) & 0xffff)
+#define PCI_DVSEC_HEADER1_REV(x) (((x) >> 16) & 0xf)
+#define PCI_DVSEC_HEADER1_LEN(x) (((x) >> 20) & 0xfff)
 #define PCI_DVSEC_HEADER2 0x8
+#define PCI_DVSEC_HEADER2_ID(x) ((x) & 0xffff)
 #define PCI_DLF_CAP 0x04
 #define PCI_DLF_EXCHANGE_ENABLE 0x80000000
 #define PCI_PL_16GT_LE_CTRL 0x20
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index b09c5d8..b022586 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -30,6 +30,8 @@
   PERF_TYPE_BREAKPOINT = 5,
   PERF_TYPE_MAX,
 };
+#define PERF_PMU_TYPE_SHIFT 32
+#define PERF_HW_EVENT_MASK 0xffffffff
 enum perf_hw_id {
   PERF_COUNT_HW_CPU_CYCLES = 0,
   PERF_COUNT_HW_INSTRUCTIONS = 1,
@@ -76,6 +78,7 @@
   PERF_COUNT_SW_EMULATION_FAULTS = 8,
   PERF_COUNT_SW_DUMMY = 9,
   PERF_COUNT_SW_BPF_OUTPUT = 10,
+  PERF_COUNT_SW_CGROUP_SWITCHES = 11,
   PERF_COUNT_SW_MAX,
 };
 enum perf_event_sample_format {
@@ -197,6 +200,7 @@
 #define PERF_ATTR_SIZE_VER4 104
 #define PERF_ATTR_SIZE_VER5 112
 #define PERF_ATTR_SIZE_VER6 120
+#define PERF_ATTR_SIZE_VER7 128
 struct perf_event_attr {
   __u32 type;
   __u32 size;
@@ -207,7 +211,7 @@
   };
   __u64 sample_type;
   __u64 read_format;
-  __u64 disabled : 1, inherit : 1, pinned : 1, exclusive : 1, exclude_user : 1, exclude_kernel : 1, exclude_hv : 1, exclude_idle : 1, mmap : 1, comm : 1, freq : 1, inherit_stat : 1, enable_on_exec : 1, task : 1, watermark : 1, precise_ip : 2, mmap_data : 1, sample_id_all : 1, exclude_host : 1, exclude_guest : 1, exclude_callchain_kernel : 1, exclude_callchain_user : 1, mmap2 : 1, comm_exec : 1, use_clockid : 1, context_switch : 1, write_backward : 1, namespaces : 1, ksymbol : 1, bpf_event : 1, aux_output : 1, cgroup : 1, text_poke : 1, build_id : 1, __reserved_1 : 29;
+  __u64 disabled : 1, inherit : 1, pinned : 1, exclusive : 1, exclude_user : 1, exclude_kernel : 1, exclude_hv : 1, exclude_idle : 1, mmap : 1, comm : 1, freq : 1, inherit_stat : 1, enable_on_exec : 1, task : 1, watermark : 1, precise_ip : 2, mmap_data : 1, sample_id_all : 1, exclude_host : 1, exclude_guest : 1, exclude_callchain_kernel : 1, exclude_callchain_user : 1, mmap2 : 1, comm_exec : 1, use_clockid : 1, context_switch : 1, write_backward : 1, namespaces : 1, ksymbol : 1, bpf_event : 1, aux_output : 1, cgroup : 1, text_poke : 1, build_id : 1, inherit_thread : 1, remove_on_exec : 1, sigtrap : 1, __reserved_1 : 26;
   union {
     __u32 wakeup_events;
     __u32 wakeup_watermark;
@@ -235,6 +239,7 @@
   __u16 __reserved_2;
   __u32 aux_sample_size;
   __u32 __reserved_3;
+  __u64 sig_data;
 };
 struct perf_event_query_bpf {
   __u32 ids_len;
@@ -345,6 +350,7 @@
   PERF_RECORD_BPF_EVENT = 18,
   PERF_RECORD_CGROUP = 19,
   PERF_RECORD_TEXT_POKE = 20,
+  PERF_RECORD_AUX_OUTPUT_HW_ID = 21,
   PERF_RECORD_MAX,
 };
 enum perf_record_ksymbol_type {
@@ -375,6 +381,9 @@
 #define PERF_AUX_FLAG_OVERWRITE 0x02
 #define PERF_AUX_FLAG_PARTIAL 0x04
 #define PERF_AUX_FLAG_COLLISION 0x08
+#define PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK 0xff00
+#define PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT 0x0000
+#define PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW 0x0100
 #define PERF_FLAG_FD_NO_GROUP (1UL << 0)
 #define PERF_FLAG_FD_OUTPUT (1UL << 1)
 #define PERF_FLAG_PID_CGROUP (1UL << 2)
@@ -383,14 +392,14 @@
 union perf_mem_data_src {
   __u64 val;
   struct {
-    __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_lvl_num : 4, mem_remote : 1, mem_snoopx : 2, mem_blk : 3, mem_rsvd : 21;
+    __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_lvl_num : 4, mem_remote : 1, mem_snoopx : 2, mem_blk : 3, mem_hops : 3, mem_rsvd : 18;
   };
 };
 #elif defined(__BIG_ENDIAN_BITFIELD)
 union perf_mem_data_src {
   __u64 val;
   struct {
-    __u64 mem_rsvd : 21, mem_blk : 3, mem_snoopx : 2, mem_remote : 1, mem_lvl_num : 4, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
+    __u64 mem_rsvd : 18, mem_hops : 3, mem_blk : 3, mem_snoopx : 2, mem_remote : 1, mem_lvl_num : 4, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
   };
 };
 #else
@@ -452,6 +461,11 @@
 #define PERF_MEM_BLK_DATA 0x02
 #define PERF_MEM_BLK_ADDR 0x04
 #define PERF_MEM_BLK_SHIFT 40
+#define PERF_MEM_HOPS_0 0x01
+#define PERF_MEM_HOPS_1 0x02
+#define PERF_MEM_HOPS_2 0x03
+#define PERF_MEM_HOPS_3 0x04
+#define PERF_MEM_HOPS_SHIFT 43
 #define PERF_MEM_S(a,s) (((__u64) PERF_MEM_ ##a ##_ ##s) << PERF_MEM_ ##a ##_SHIFT)
 struct perf_branch_entry {
   __u64 from;
diff --git a/libc/kernel/uapi/linux/pfkeyv2.h b/libc/kernel/uapi/linux/pfkeyv2.h
index 8f65681..d1e5486 100644
--- a/libc/kernel/uapi/linux/pfkeyv2.h
+++ b/libc/kernel/uapi/linux/pfkeyv2.h
@@ -243,6 +243,7 @@
 #define SADB_X_AALG_SHA2_512HMAC 7
 #define SADB_X_AALG_RIPEMD160HMAC 8
 #define SADB_X_AALG_AES_XCBC_MAC 9
+#define SADB_X_AALG_SM3_256HMAC 10
 #define SADB_X_AALG_NULL 251
 #define SADB_AALG_MAX 251
 #define SADB_EALG_NONE 0
@@ -261,6 +262,7 @@
 #define SADB_X_EALG_AES_GCM_ICV16 20
 #define SADB_X_EALG_CAMELLIACBC 22
 #define SADB_X_EALG_NULL_AES_GMAC 23
+#define SADB_X_EALG_SM4CBC 24
 #define SADB_EALG_MAX 253
 #define SADB_X_EALG_SERPENTCBC 252
 #define SADB_X_EALG_TWOFISHCBC 253
diff --git a/libc/kernel/uapi/linux/pfrut.h b/libc/kernel/uapi/linux/pfrut.h
new file mode 100644
index 0000000..14f713f
--- /dev/null
+++ b/libc/kernel/uapi/linux/pfrut.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __PFRUT_H__
+#define __PFRUT_H__
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define PFRUT_IOCTL_MAGIC 0xEE
+#define PFRU_IOC_SET_REV _IOW(PFRUT_IOCTL_MAGIC, 0x01, unsigned int)
+#define PFRU_IOC_STAGE _IOW(PFRUT_IOCTL_MAGIC, 0x02, unsigned int)
+#define PFRU_IOC_ACTIVATE _IOW(PFRUT_IOCTL_MAGIC, 0x03, unsigned int)
+#define PFRU_IOC_STAGE_ACTIVATE _IOW(PFRUT_IOCTL_MAGIC, 0x04, unsigned int)
+#define PFRU_IOC_QUERY_CAP _IOR(PFRUT_IOCTL_MAGIC, 0x05, struct pfru_update_cap_info)
+struct pfru_payload_hdr {
+  __u32 sig;
+  __u32 hdr_version;
+  __u32 hdr_size;
+  __u32 hw_ver;
+  __u32 rt_ver;
+  __u8 platform_id[16];
+};
+enum pfru_dsm_status {
+  DSM_SUCCEED = 0,
+  DSM_FUNC_NOT_SUPPORT = 1,
+  DSM_INVAL_INPUT = 2,
+  DSM_HARDWARE_ERR = 3,
+  DSM_RETRY_SUGGESTED = 4,
+  DSM_UNKNOWN = 5,
+  DSM_FUNC_SPEC_ERR = 6,
+};
+struct pfru_update_cap_info {
+  __u32 status;
+  __u32 update_cap;
+  __u8 code_type[16];
+  __u32 fw_version;
+  __u32 code_rt_version;
+  __u8 drv_type[16];
+  __u32 drv_rt_version;
+  __u32 drv_svn;
+  __u8 platform_id[16];
+  __u8 oem_id[16];
+  __u32 oem_info_len;
+};
+struct pfru_com_buf_info {
+  __u32 status;
+  __u32 ext_status;
+  __u64 addr_lo;
+  __u64 addr_hi;
+  __u32 buf_size;
+};
+struct pfru_updated_result {
+  __u32 status;
+  __u32 ext_status;
+  __u64 low_auth_time;
+  __u64 high_auth_time;
+  __u64 low_exec_time;
+  __u64 high_exec_time;
+};
+struct pfrt_log_data_info {
+  __u32 status;
+  __u32 ext_status;
+  __u64 chunk1_addr_lo;
+  __u64 chunk1_addr_hi;
+  __u64 chunk2_addr_lo;
+  __u64 chunk2_addr_hi;
+  __u32 max_data_size;
+  __u32 chunk1_size;
+  __u32 chunk2_size;
+  __u32 rollover_cnt;
+  __u32 reset_cnt;
+};
+struct pfrt_log_info {
+  __u32 log_level;
+  __u32 log_type;
+  __u32 log_revid;
+};
+#define PFRT_LOG_IOC_SET_INFO _IOW(PFRUT_IOCTL_MAGIC, 0x06, struct pfrt_log_info)
+#define PFRT_LOG_IOC_GET_INFO _IOR(PFRUT_IOCTL_MAGIC, 0x07, struct pfrt_log_info)
+#define PFRT_LOG_IOC_GET_DATA_INFO _IOR(PFRUT_IOCTL_MAGIC, 0x08, struct pfrt_log_data_info)
+#endif
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index 45dca35..9fd89e0 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -32,9 +32,12 @@
   TCA_ACT_FLAGS,
   TCA_ACT_HW_STATS,
   TCA_ACT_USED_HW_STATS,
+  TCA_ACT_IN_HW_COUNT,
   __TCA_ACT_MAX
 };
-#define TCA_ACT_FLAGS_NO_PERCPU_STATS 1
+#define TCA_ACT_FLAGS_NO_PERCPU_STATS (1 << 0)
+#define TCA_ACT_FLAGS_SKIP_HW (1 << 1)
+#define TCA_ACT_FLAGS_SKIP_SW (1 << 2)
 #define TCA_ACT_HW_STATS_IMMEDIATE (1 << 0)
 #define TCA_ACT_HW_STATS_DELAYED (1 << 1)
 #define TCA_ACT_MAX __TCA_ACT_MAX
@@ -146,6 +149,8 @@
   TCA_POLICE_PAD,
   TCA_POLICE_RATE64,
   TCA_POLICE_PEAKRATE64,
+  TCA_POLICE_PKTRATE64,
+  TCA_POLICE_PKTBURST64,
   __TCA_POLICE_MAX
 #define TCA_POLICE_RESULT TCA_POLICE_RESULT
 };
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index d0541fc..e298b74 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -613,6 +613,7 @@
   __u32 dropping;
   __u32 ce_mark;
 };
+#define FQ_CODEL_QUANTUM_MAX (1 << 20)
 enum {
   TCA_FQ_CODEL_UNSPEC,
   TCA_FQ_CODEL_TARGET,
@@ -624,6 +625,8 @@
   TCA_FQ_CODEL_CE_THRESHOLD,
   TCA_FQ_CODEL_DROP_BATCH_SIZE,
   TCA_FQ_CODEL_MEMORY_LIMIT,
+  TCA_FQ_CODEL_CE_THRESHOLD_SELECTOR,
+  TCA_FQ_CODEL_CE_THRESHOLD_MASK,
   __TCA_FQ_CODEL_MAX
 };
 #define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1)
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 6095881..9b4c695 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -138,6 +138,7 @@
 #define PR_SET_SPECULATION_CTRL 53
 #define PR_SPEC_STORE_BYPASS 0
 #define PR_SPEC_INDIRECT_BRANCH 1
+#define PR_SPEC_L1D_FLUSH 2
 #define PR_SPEC_NOT_AFFECTED 0
 #define PR_SPEC_PRCTL (1UL << 0)
 #define PR_SPEC_ENABLE (1UL << 1)
@@ -153,13 +154,13 @@
 #define PR_SET_TAGGED_ADDR_CTRL 55
 #define PR_GET_TAGGED_ADDR_CTRL 56
 #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
-#define PR_MTE_TCF_SHIFT 1
-#define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
-#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
-#define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
-#define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
+#define PR_MTE_TCF_NONE 0UL
+#define PR_MTE_TCF_SYNC (1UL << 1)
+#define PR_MTE_TCF_ASYNC (1UL << 2)
+#define PR_MTE_TCF_MASK (PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC)
 #define PR_MTE_TAG_SHIFT 3
 #define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
+#define PR_MTE_TCF_SHIFT 1
 #define PR_SET_IO_FLUSHER 57
 #define PR_GET_IO_FLUSHER 58
 #define PR_SET_SYSCALL_USER_DISPATCH 59
@@ -167,6 +168,17 @@
 #define PR_SYS_DISPATCH_ON 1
 #define SYSCALL_DISPATCH_FILTER_ALLOW 0
 #define SYSCALL_DISPATCH_FILTER_BLOCK 1
+#define PR_PAC_SET_ENABLED_KEYS 60
+#define PR_PAC_GET_ENABLED_KEYS 61
+#define PR_SCHED_CORE 62
+#define PR_SCHED_CORE_GET 0
+#define PR_SCHED_CORE_CREATE 1
+#define PR_SCHED_CORE_SHARE_TO 2
+#define PR_SCHED_CORE_SHARE_FROM 3
+#define PR_SCHED_CORE_MAX 4
+#define PR_SCHED_CORE_SCOPE_THREAD 0
+#define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1
+#define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2
 #define PR_SET_VMA 0x53564d41
 #define PR_SET_VMA_ANON_NAME 0
 #endif
diff --git a/libc/kernel/uapi/linux/psample.h b/libc/kernel/uapi/linux/psample.h
index dc67445..efb1c24 100644
--- a/libc/kernel/uapi/linux/psample.h
+++ b/libc/kernel/uapi/linux/psample.h
@@ -28,6 +28,12 @@
   PSAMPLE_ATTR_DATA,
   PSAMPLE_ATTR_GROUP_REFCOUNT,
   PSAMPLE_ATTR_TUNNEL,
+  PSAMPLE_ATTR_PAD,
+  PSAMPLE_ATTR_OUT_TC,
+  PSAMPLE_ATTR_OUT_TC_OCC,
+  PSAMPLE_ATTR_LATENCY,
+  PSAMPLE_ATTR_TIMESTAMP,
+  PSAMPLE_ATTR_PROTO,
   __PSAMPLE_ATTR_MAX
 };
 enum psample_command {
diff --git a/libc/kernel/uapi/linux/ptrace.h b/libc/kernel/uapi/linux/ptrace.h
index 5de0998..4bfa59a 100644
--- a/libc/kernel/uapi/linux/ptrace.h
+++ b/libc/kernel/uapi/linux/ptrace.h
@@ -82,6 +82,14 @@
     } seccomp;
   };
 };
+#define PTRACE_GET_RSEQ_CONFIGURATION 0x420f
+struct ptrace_rseq_configuration {
+  __u64 rseq_abi_pointer;
+  __u32 rseq_abi_size;
+  __u32 signature;
+  __u32 flags;
+  __u32 pad;
+};
 #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/rds.h b/libc/kernel/uapi/linux/rds.h
index bc29233..7006c87 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -217,7 +217,7 @@
   __u64 flags;
 };
 struct rds_get_mr_for_dest_args {
-  struct sockaddr_storage dest_addr;
+  struct __kernel_sockaddr_storage dest_addr;
   struct rds_iovec vec;
   __u64 cookie_addr;
   __u64 flags;
diff --git a/libc/kernel/uapi/linux/resource.h b/libc/kernel/uapi/linux/resource.h
index d76c273..6f531a0 100644
--- a/libc/kernel/uapi/linux/resource.h
+++ b/libc/kernel/uapi/linux/resource.h
@@ -57,6 +57,6 @@
 #define PRIO_PGRP 1
 #define PRIO_USER 2
 #define _STK_LIM (8 * 1024 * 1024)
-#define MLOCK_LIMIT ((PAGE_SIZE > 64 * 1024) ? PAGE_SIZE : 64 * 1024)
+#define MLOCK_LIMIT (8 * 1024 * 1024)
 #include <asm/resource.h>
 #endif
diff --git a/libc/kernel/uapi/linux/rpmsg.h b/libc/kernel/uapi/linux/rpmsg.h
index 77f05e6..c5b5a76 100644
--- a/libc/kernel/uapi/linux/rpmsg.h
+++ b/libc/kernel/uapi/linux/rpmsg.h
@@ -20,6 +20,7 @@
 #define _UAPI_RPMSG_H_
 #include <linux/ioctl.h>
 #include <linux/types.h>
+#define RPMSG_ADDR_ANY 0xFFFFFFFF
 struct rpmsg_endpoint_info {
   char name[32];
   __u32 src;
diff --git a/libc/kernel/uapi/linux/rtc.h b/libc/kernel/uapi/linux/rtc.h
index 7f38483..cf5f22a 100644
--- a/libc/kernel/uapi/linux/rtc.h
+++ b/libc/kernel/uapi/linux/rtc.h
@@ -20,6 +20,7 @@
 #define _UAPI_LINUX_RTC_H_
 #include <linux/const.h>
 #include <linux/ioctl.h>
+#include <linux/types.h>
 struct rtc_time {
   int tm_sec;
   int tm_min;
@@ -45,6 +46,16 @@
   int pll_negmult;
   long pll_clock;
 };
+struct rtc_param {
+  __u64 param;
+  union {
+    __u64 uvalue;
+    __s64 svalue;
+    __u64 ptr;
+  };
+  __u32 index;
+  __u32 __pad;
+};
 #define RTC_AIE_ON _IO('p', 0x01)
 #define RTC_AIE_OFF _IO('p', 0x02)
 #define RTC_UIE_ON _IO('p', 0x03)
@@ -65,6 +76,8 @@
 #define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm)
 #define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info)
 #define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info)
+#define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param)
+#define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param)
 #define RTC_VL_DATA_INVALID _BITUL(0)
 #define RTC_VL_BACKUP_LOW _BITUL(1)
 #define RTC_VL_BACKUP_EMPTY _BITUL(2)
@@ -79,6 +92,17 @@
 #define RTC_FEATURE_ALARM 0
 #define RTC_FEATURE_ALARM_RES_MINUTE 1
 #define RTC_FEATURE_NEED_WEEK_DAY 2
-#define RTC_FEATURE_CNT 3
+#define RTC_FEATURE_ALARM_RES_2S 3
+#define RTC_FEATURE_UPDATE_INTERRUPT 4
+#define RTC_FEATURE_CORRECTION 5
+#define RTC_FEATURE_BACKUP_SWITCH_MODE 6
+#define RTC_FEATURE_CNT 7
+#define RTC_PARAM_FEATURES 0
+#define RTC_PARAM_CORRECTION 1
+#define RTC_PARAM_BACKUP_SWITCH_MODE 2
+#define RTC_BSM_DISABLED 0
+#define RTC_BSM_DIRECT 1
+#define RTC_BSM_LEVEL 2
+#define RTC_BSM_STANDBY 3
 #define RTC_MAX_FREQ 8192
 #endif
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index 22f8f1c..91c3ee4 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -157,6 +157,12 @@
 #define RTM_DELVLAN RTM_DELVLAN
   RTM_GETVLAN,
 #define RTM_GETVLAN RTM_GETVLAN
+  RTM_NEWNEXTHOPBUCKET = 116,
+#define RTM_NEWNEXTHOPBUCKET RTM_NEWNEXTHOPBUCKET
+  RTM_DELNEXTHOPBUCKET,
+#define RTM_DELNEXTHOPBUCKET RTM_DELNEXTHOPBUCKET
+  RTM_GETNEXTHOPBUCKET,
+#define RTM_GETNEXTHOPBUCKET RTM_GETNEXTHOPBUCKET
   __RTM_MAX,
 #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -219,6 +225,7 @@
 #define RTPROT_MROUTED 17
 #define RTPROT_KEEPALIVED 18
 #define RTPROT_BABEL 42
+#define RTPROT_OPENR 99
 #define RTPROT_BGP 186
 #define RTPROT_ISIS 187
 #define RTPROT_OSPF 188
@@ -552,6 +559,8 @@
 #define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
   RTNLGRP_BRVLAN,
 #define RTNLGRP_BRVLAN RTNLGRP_BRVLAN
+  RTNLGRP_MCTP_IFADDR,
+#define RTNLGRP_MCTP_IFADDR RTNLGRP_MCTP_IFADDR
   __RTNLGRP_MAX
 };
 #define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 883920b..765d6c9 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -94,6 +94,7 @@
 #define SCTP_EXPOSE_POTENTIALLY_FAILED_STATE 131
 #define SCTP_EXPOSE_PF_STATE SCTP_EXPOSE_POTENTIALLY_FAILED_STATE
 #define SCTP_REMOTE_UDP_ENCAPS_PORT 132
+#define SCTP_PLPMTUD_PROBE_INTERVAL 133
 #define SCTP_PR_SCTP_NONE 0x0000
 #define SCTP_PR_SCTP_TTL 0x0010
 #define SCTP_PR_SCTP_RTX 0x0020
@@ -710,4 +711,9 @@
   SCTP_SS_RR,
   SCTP_SS_MAX = SCTP_SS_RR
 };
+struct sctp_probeinterval {
+  sctp_assoc_t spi_assoc_id;
+  struct sockaddr_storage spi_address;
+  __u32 spi_interval;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/seccomp.h b/libc/kernel/uapi/linux/seccomp.h
index 0ae0e12..e58b421 100644
--- a/libc/kernel/uapi/linux/seccomp.h
+++ b/libc/kernel/uapi/linux/seccomp.h
@@ -69,6 +69,7 @@
   __u32 flags;
 };
 #define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0)
+#define SECCOMP_ADDFD_FLAG_SEND (1UL << 1)
 struct seccomp_notif_addfd {
   __u64 id;
   __u32 flags;
diff --git a/libc/kernel/uapi/linux/seg6_local.h b/libc/kernel/uapi/linux/seg6_local.h
index 9508eca..61a8d97 100644
--- a/libc/kernel/uapi/linux/seg6_local.h
+++ b/libc/kernel/uapi/linux/seg6_local.h
@@ -30,6 +30,7 @@
   SEG6_LOCAL_OIF,
   SEG6_LOCAL_BPF,
   SEG6_LOCAL_VRFTABLE,
+  SEG6_LOCAL_COUNTERS,
   __SEG6_LOCAL_MAX,
 };
 #define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1)
@@ -50,6 +51,7 @@
   SEG6_LOCAL_ACTION_END_AS = 13,
   SEG6_LOCAL_ACTION_END_AM = 14,
   SEG6_LOCAL_ACTION_END_BPF = 15,
+  SEG6_LOCAL_ACTION_END_DT46 = 16,
   __SEG6_LOCAL_ACTION_MAX,
 };
 #define SEG6_LOCAL_ACTION_MAX (__SEG6_LOCAL_ACTION_MAX - 1)
@@ -60,4 +62,13 @@
   __SEG6_LOCAL_BPF_PROG_MAX,
 };
 #define SEG6_LOCAL_BPF_PROG_MAX (__SEG6_LOCAL_BPF_PROG_MAX - 1)
+enum {
+  SEG6_LOCAL_CNT_UNSPEC,
+  SEG6_LOCAL_CNT_PAD,
+  SEG6_LOCAL_CNT_PACKETS,
+  SEG6_LOCAL_CNT_BYTES,
+  SEG6_LOCAL_CNT_ERRORS,
+  __SEG6_LOCAL_CNT_MAX,
+};
+#define SEG6_LOCAL_CNT_MAX (__SEG6_LOCAL_CNT_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/smc.h b/libc/kernel/uapi/linux/smc.h
index 88eef62..01494da 100644
--- a/libc/kernel/uapi/linux/smc.h
+++ b/libc/kernel/uapi/linux/smc.h
@@ -38,6 +38,9 @@
 #define SMC_GENL_FAMILY_NAME "SMC_GEN_NETLINK"
 #define SMC_GENL_FAMILY_VERSION 1
 #define SMC_PCI_ID_STR_LEN 16
+#define SMC_MAX_HOSTNAME_LEN 32
+#define SMC_MAX_UEID 4
+#define SMC_MAX_EID_LEN 32
 enum {
   SMC_NETLINK_GET_SYS_INFO = 1,
   SMC_NETLINK_GET_LGR_SMCR,
@@ -45,6 +48,15 @@
   SMC_NETLINK_GET_LGR_SMCD,
   SMC_NETLINK_GET_DEV_SMCD,
   SMC_NETLINK_GET_DEV_SMCR,
+  SMC_NETLINK_GET_STATS,
+  SMC_NETLINK_GET_FBACK_STATS,
+  SMC_NETLINK_DUMP_UEID,
+  SMC_NETLINK_ADD_UEID,
+  SMC_NETLINK_REMOVE_UEID,
+  SMC_NETLINK_FLUSH_UEID,
+  SMC_NETLINK_DUMP_SEID,
+  SMC_NETLINK_ENABLE_SEID,
+  SMC_NETLINK_DISABLE_SEID,
 };
 enum {
   SMC_GEN_UNSPEC,
@@ -54,6 +66,8 @@
   SMC_GEN_LGR_SMCD,
   SMC_GEN_DEV_SMCD,
   SMC_GEN_DEV_SMCR,
+  SMC_GEN_STATS,
+  SMC_GEN_FBACK_STATS,
   __SMC_GEN_MAX,
   SMC_GEN_MAX = __SMC_GEN_MAX - 1
 };
@@ -64,6 +78,7 @@
   SMC_NLA_SYS_IS_ISM_V2,
   SMC_NLA_SYS_LOCAL_HOST,
   SMC_NLA_SYS_SEID,
+  SMC_NLA_SYS_IS_SMCR_V2,
   __SMC_NLA_SYS_MAX,
   SMC_NLA_SYS_MAX = __SMC_NLA_SYS_MAX - 1
 };
@@ -73,6 +88,14 @@
   SMC_NLA_LGR_V2_OS,
   SMC_NLA_LGR_V2_NEG_EID,
   SMC_NLA_LGR_V2_PEER_HOST,
+  __SMC_NLA_LGR_V2_MAX,
+  SMC_NLA_LGR_V2_MAX = __SMC_NLA_LGR_V2_MAX - 1
+};
+enum {
+  SMC_NLA_LGR_R_V2_UNSPEC,
+  SMC_NLA_LGR_R_V2_DIRECT,
+  __SMC_NLA_LGR_R_V2_MAX,
+  SMC_NLA_LGR_R_V2_MAX = __SMC_NLA_LGR_R_V2_MAX - 1
 };
 enum {
   SMC_NLA_LGR_R_UNSPEC,
@@ -82,6 +105,10 @@
   SMC_NLA_LGR_R_PNETID,
   SMC_NLA_LGR_R_VLAN_ID,
   SMC_NLA_LGR_R_CONNS_NUM,
+  SMC_NLA_LGR_R_V2_COMMON,
+  SMC_NLA_LGR_R_V2,
+  SMC_NLA_LGR_R_NET_COOKIE,
+  SMC_NLA_LGR_R_PAD,
   __SMC_NLA_LGR_R_MAX,
   SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
 };
@@ -110,7 +137,7 @@
   SMC_NLA_LGR_D_PNETID,
   SMC_NLA_LGR_D_CHID,
   SMC_NLA_LGR_D_PAD,
-  SMC_NLA_LGR_V2,
+  SMC_NLA_LGR_D_V2_COMMON,
   __SMC_NLA_LGR_D_MAX,
   SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
 };
@@ -140,4 +167,86 @@
   __SMC_NLA_DEV_MAX,
   SMC_NLA_DEV_MAX = __SMC_NLA_DEV_MAX - 1
 };
+enum {
+  SMC_NLA_STATS_PLOAD_PAD,
+  SMC_NLA_STATS_PLOAD_8K,
+  SMC_NLA_STATS_PLOAD_16K,
+  SMC_NLA_STATS_PLOAD_32K,
+  SMC_NLA_STATS_PLOAD_64K,
+  SMC_NLA_STATS_PLOAD_128K,
+  SMC_NLA_STATS_PLOAD_256K,
+  SMC_NLA_STATS_PLOAD_512K,
+  SMC_NLA_STATS_PLOAD_1024K,
+  SMC_NLA_STATS_PLOAD_G_1024K,
+  __SMC_NLA_STATS_PLOAD_MAX,
+  SMC_NLA_STATS_PLOAD_MAX = __SMC_NLA_STATS_PLOAD_MAX - 1
+};
+enum {
+  SMC_NLA_STATS_RMB_PAD,
+  SMC_NLA_STATS_RMB_SIZE_SM_PEER_CNT,
+  SMC_NLA_STATS_RMB_SIZE_SM_CNT,
+  SMC_NLA_STATS_RMB_FULL_PEER_CNT,
+  SMC_NLA_STATS_RMB_FULL_CNT,
+  SMC_NLA_STATS_RMB_REUSE_CNT,
+  SMC_NLA_STATS_RMB_ALLOC_CNT,
+  SMC_NLA_STATS_RMB_DGRADE_CNT,
+  __SMC_NLA_STATS_RMB_MAX,
+  SMC_NLA_STATS_RMB_MAX = __SMC_NLA_STATS_RMB_MAX - 1
+};
+enum {
+  SMC_NLA_STATS_T_PAD,
+  SMC_NLA_STATS_T_TX_RMB_SIZE,
+  SMC_NLA_STATS_T_RX_RMB_SIZE,
+  SMC_NLA_STATS_T_TXPLOAD_SIZE,
+  SMC_NLA_STATS_T_RXPLOAD_SIZE,
+  SMC_NLA_STATS_T_TX_RMB_STATS,
+  SMC_NLA_STATS_T_RX_RMB_STATS,
+  SMC_NLA_STATS_T_CLNT_V1_SUCC,
+  SMC_NLA_STATS_T_CLNT_V2_SUCC,
+  SMC_NLA_STATS_T_SRV_V1_SUCC,
+  SMC_NLA_STATS_T_SRV_V2_SUCC,
+  SMC_NLA_STATS_T_SENDPAGE_CNT,
+  SMC_NLA_STATS_T_SPLICE_CNT,
+  SMC_NLA_STATS_T_CORK_CNT,
+  SMC_NLA_STATS_T_NDLY_CNT,
+  SMC_NLA_STATS_T_URG_DATA_CNT,
+  SMC_NLA_STATS_T_RX_BYTES,
+  SMC_NLA_STATS_T_TX_BYTES,
+  SMC_NLA_STATS_T_RX_CNT,
+  SMC_NLA_STATS_T_TX_CNT,
+  __SMC_NLA_STATS_T_MAX,
+  SMC_NLA_STATS_T_MAX = __SMC_NLA_STATS_T_MAX - 1
+};
+enum {
+  SMC_NLA_STATS_PAD,
+  SMC_NLA_STATS_SMCD_TECH,
+  SMC_NLA_STATS_SMCR_TECH,
+  SMC_NLA_STATS_CLNT_HS_ERR_CNT,
+  SMC_NLA_STATS_SRV_HS_ERR_CNT,
+  __SMC_NLA_STATS_MAX,
+  SMC_NLA_STATS_MAX = __SMC_NLA_STATS_MAX - 1
+};
+enum {
+  SMC_NLA_FBACK_STATS_PAD,
+  SMC_NLA_FBACK_STATS_TYPE,
+  SMC_NLA_FBACK_STATS_SRV_CNT,
+  SMC_NLA_FBACK_STATS_CLNT_CNT,
+  SMC_NLA_FBACK_STATS_RSN_CODE,
+  SMC_NLA_FBACK_STATS_RSN_CNT,
+  __SMC_NLA_FBACK_STATS_MAX,
+  SMC_NLA_FBACK_STATS_MAX = __SMC_NLA_FBACK_STATS_MAX - 1
+};
+enum {
+  SMC_NLA_EID_TABLE_UNSPEC,
+  SMC_NLA_EID_TABLE_ENTRY,
+  __SMC_NLA_EID_TABLE_MAX,
+  SMC_NLA_EID_TABLE_MAX = __SMC_NLA_EID_TABLE_MAX - 1
+};
+enum {
+  SMC_NLA_SEID_UNSPEC,
+  SMC_NLA_SEID_ENTRY,
+  SMC_NLA_SEID_ENABLED,
+  __SMC_NLA_SEID_TABLE_MAX,
+  SMC_NLA_SEID_TABLE_MAX = __SMC_NLA_SEID_TABLE_MAX - 1
+};
 #endif
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 40e8fa5..a503a7e 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -257,6 +257,8 @@
   LINUX_MIB_TCPDUPLICATEDATAREHASH,
   LINUX_MIB_TCPDSACKRECVSEGS,
   LINUX_MIB_TCPDSACKIGNOREDDUBIOUS,
+  LINUX_MIB_TCPMIGRATEREQSUCCESS,
+  LINUX_MIB_TCPMIGRATEREQFAILURE,
   __LINUX_MIB_MAX
 };
 enum {
diff --git a/libc/kernel/uapi/linux/socket.h b/libc/kernel/uapi/linux/socket.h
index 608d31f..be16548 100644
--- a/libc/kernel/uapi/linux/socket.h
+++ b/libc/kernel/uapi/linux/socket.h
@@ -20,7 +20,7 @@
 #define _UAPI_LINUX_SOCKET_H
 #define _K_SS_MAXSIZE 128
 typedef unsigned short __kernel_sa_family_t;
-struct sockaddr_storage {
+struct __kernel_sockaddr_storage {
   union {
     struct {
       __kernel_sa_family_t ss_family;
@@ -29,4 +29,7 @@
     void * __align;
   };
 };
+#define SOCK_SNDBUF_LOCK 1
+#define SOCK_RCVBUF_LOCK 2
+#define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK)
 #endif
diff --git a/libc/kernel/uapi/linux/stddef.h b/libc/kernel/uapi/linux/stddef.h
index 2a5fd95..d5cdf80 100644
--- a/libc/kernel/uapi/linux/stddef.h
+++ b/libc/kernel/uapi/linux/stddef.h
@@ -20,3 +20,5 @@
 #ifndef __always_inline
 #define __always_inline inline
 #endif
+#define __struct_group(TAG,NAME,ATTRS,MEMBERS...) union { struct { MEMBERS } ATTRS; struct TAG { MEMBERS } ATTRS NAME; }
+#define __DECLARE_FLEX_ARRAY(TYPE,NAME) struct { struct { } __empty_ ##NAME; TYPE NAME[]; }
diff --git a/libc/kernel/uapi/linux/surface_aggregator/cdev.h b/libc/kernel/uapi/linux/surface_aggregator/cdev.h
index 25bfd8d..2e097f0 100644
--- a/libc/kernel/uapi/linux/surface_aggregator/cdev.h
+++ b/libc/kernel/uapi/linux/surface_aggregator/cdev.h
@@ -42,5 +42,34 @@
     __u8 __pad[6];
   } response;
 } __attribute__((__packed__));
+struct ssam_cdev_notifier_desc {
+  __s32 priority;
+  __u8 target_category;
+} __attribute__((__packed__));
+struct ssam_cdev_event_desc {
+  struct {
+    __u8 target_category;
+    __u8 target_id;
+    __u8 cid_enable;
+    __u8 cid_disable;
+  } reg;
+  struct {
+    __u8 target_category;
+    __u8 instance;
+  } id;
+  __u8 flags;
+} __attribute__((__packed__));
+struct ssam_cdev_event {
+  __u8 target_category;
+  __u8 target_id;
+  __u8 command_id;
+  __u8 instance_id;
+  __u16 length;
+  __u8 data[];
+} __attribute__((__packed__));
 #define SSAM_CDEV_REQUEST _IOWR(0xA5, 1, struct ssam_cdev_request)
+#define SSAM_CDEV_NOTIF_REGISTER _IOW(0xA5, 2, struct ssam_cdev_notifier_desc)
+#define SSAM_CDEV_NOTIF_UNREGISTER _IOW(0xA5, 3, struct ssam_cdev_notifier_desc)
+#define SSAM_CDEV_EVENT_ENABLE _IOW(0xA5, 4, struct ssam_cdev_event_desc)
+#define SSAM_CDEV_EVENT_DISABLE _IOW(0xA5, 5, struct ssam_cdev_event_desc)
 #endif
diff --git a/libc/kernel/uapi/linux/surface_aggregator/dtx.h b/libc/kernel/uapi/linux/surface_aggregator/dtx.h
new file mode 100644
index 0000000..dde5ad3
--- /dev/null
+++ b/libc/kernel/uapi/linux/surface_aggregator/dtx.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_SURFACE_AGGREGATOR_DTX_H
+#define _UAPI_LINUX_SURFACE_AGGREGATOR_DTX_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define SDTX_CATEGORY_STATUS 0x0000
+#define SDTX_CATEGORY_RUNTIME_ERROR 0x1000
+#define SDTX_CATEGORY_HARDWARE_ERROR 0x2000
+#define SDTX_CATEGORY_UNKNOWN 0xf000
+#define SDTX_CATEGORY_MASK 0xf000
+#define SDTX_CATEGORY(value) ((value) & SDTX_CATEGORY_MASK)
+#define SDTX_STATUS(code) ((code) | SDTX_CATEGORY_STATUS)
+#define SDTX_ERR_RT(code) ((code) | SDTX_CATEGORY_RUNTIME_ERROR)
+#define SDTX_ERR_HW(code) ((code) | SDTX_CATEGORY_HARDWARE_ERROR)
+#define SDTX_UNKNOWN(code) ((code) | SDTX_CATEGORY_UNKNOWN)
+#define SDTX_SUCCESS(value) (SDTX_CATEGORY(value) == SDTX_CATEGORY_STATUS)
+#define SDTX_LATCH_CLOSED SDTX_STATUS(0x00)
+#define SDTX_LATCH_OPENED SDTX_STATUS(0x01)
+#define SDTX_BASE_DETACHED SDTX_STATUS(0x00)
+#define SDTX_BASE_ATTACHED SDTX_STATUS(0x01)
+#define SDTX_DETACH_NOT_FEASIBLE SDTX_ERR_RT(0x01)
+#define SDTX_DETACH_TIMEDOUT SDTX_ERR_RT(0x02)
+#define SDTX_ERR_FAILED_TO_OPEN SDTX_ERR_HW(0x01)
+#define SDTX_ERR_FAILED_TO_REMAIN_OPEN SDTX_ERR_HW(0x02)
+#define SDTX_ERR_FAILED_TO_CLOSE SDTX_ERR_HW(0x03)
+#define SDTX_DEVICE_TYPE_HID 0x0100
+#define SDTX_DEVICE_TYPE_SSH 0x0200
+#define SDTX_DEVICE_TYPE_MASK 0x0f00
+#define SDTX_DEVICE_TYPE(value) ((value) & SDTX_DEVICE_TYPE_MASK)
+#define SDTX_BASE_TYPE_HID(id) ((id) | SDTX_DEVICE_TYPE_HID)
+#define SDTX_BASE_TYPE_SSH(id) ((id) | SDTX_DEVICE_TYPE_SSH)
+enum sdtx_device_mode {
+  SDTX_DEVICE_MODE_TABLET = 0x00,
+  SDTX_DEVICE_MODE_LAPTOP = 0x01,
+  SDTX_DEVICE_MODE_STUDIO = 0x02,
+};
+struct sdtx_event {
+  __u16 length;
+  __u16 code;
+  __u8 data[];
+} __attribute__((__packed__));
+enum sdtx_event_code {
+  SDTX_EVENT_REQUEST = 1,
+  SDTX_EVENT_CANCEL = 2,
+  SDTX_EVENT_BASE_CONNECTION = 3,
+  SDTX_EVENT_LATCH_STATUS = 4,
+  SDTX_EVENT_DEVICE_MODE = 5,
+};
+struct sdtx_base_info {
+  __u16 state;
+  __u16 base_id;
+} __attribute__((__packed__));
+#define SDTX_IOCTL_EVENTS_ENABLE _IO(0xa5, 0x21)
+#define SDTX_IOCTL_EVENTS_DISABLE _IO(0xa5, 0x22)
+#define SDTX_IOCTL_LATCH_LOCK _IO(0xa5, 0x23)
+#define SDTX_IOCTL_LATCH_UNLOCK _IO(0xa5, 0x24)
+#define SDTX_IOCTL_LATCH_REQUEST _IO(0xa5, 0x25)
+#define SDTX_IOCTL_LATCH_CONFIRM _IO(0xa5, 0x26)
+#define SDTX_IOCTL_LATCH_HEARTBEAT _IO(0xa5, 0x27)
+#define SDTX_IOCTL_LATCH_CANCEL _IO(0xa5, 0x28)
+#define SDTX_IOCTL_GET_BASE_INFO _IOR(0xa5, 0x29, struct sdtx_base_info)
+#define SDTX_IOCTL_GET_DEVICE_MODE _IOR(0xa5, 0x2a, __u16)
+#define SDTX_IOCTL_GET_LATCH_STATUS _IOR(0xa5, 0x2b, __u16)
+#endif
diff --git a/libc/kernel/uapi/linux/sysctl.h b/libc/kernel/uapi/linux/sysctl.h
index ebaf8a9..ae9c2ba 100644
--- a/libc/kernel/uapi/linux/sysctl.h
+++ b/libc/kernel/uapi/linux/sysctl.h
@@ -407,6 +407,7 @@
   NET_IPV4_CONF_PROMOTE_SECONDARIES = 20,
   NET_IPV4_CONF_ARP_ACCEPT = 21,
   NET_IPV4_CONF_ARP_NOTIFY = 22,
+  NET_IPV4_CONF_ARP_EVICT_NOCARRIER = 23,
 };
 enum {
   NET_IPV4_NF_CONNTRACK_MAX = 1,
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index e0b9f22..dcba00e 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -26,6 +26,7 @@
 #define TCMU_MAILBOX_FLAG_CAP_OOOC (1 << 0)
 #define TCMU_MAILBOX_FLAG_CAP_READ_LEN (1 << 1)
 #define TCMU_MAILBOX_FLAG_CAP_TMR (1 << 2)
+#define TCMU_MAILBOX_FLAG_CAP_KEEP_BUF (1 << 3)
 struct tcmu_mailbox {
   __u16 version;
   __u16 flags;
@@ -45,6 +46,7 @@
   __u8 kflags;
 #define TCMU_UFLAG_UNKNOWN_OP 0x1
 #define TCMU_UFLAG_READ_LEN 0x2
+#define TCMU_UFLAG_KEEP_BUF 0x4
   __u8 uflags;
 } __packed;
 #define TCMU_OP_MASK 0x7
diff --git a/libc/kernel/uapi/linux/taskstats.h b/libc/kernel/uapi/linux/taskstats.h
index 5f9d0cc..efa5b4a 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 10
+#define TASKSTATS_VERSION 11
 #define TS_COMM_LEN 32
 struct taskstats {
   __u16 version;
@@ -69,6 +69,8 @@
   __u64 thrashing_count;
   __u64 thrashing_delay_total;
   __u64 ac_btime64;
+  __u64 compact_count;
+  __u64 compact_delay_total;
 };
 enum {
   TASKSTATS_CMD_UNSPEC = 0,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_skbmod.h b/libc/kernel/uapi/linux/tc_act/tc_skbmod.h
index 0a53b06..f0cd928 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_skbmod.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_skbmod.h
@@ -23,6 +23,7 @@
 #define SKBMOD_F_SMAC 0x2
 #define SKBMOD_F_ETYPE 0x4
 #define SKBMOD_F_SWAPMAC 0x8
+#define SKBMOD_F_ECN 0x10
 struct tc_skbmod {
   tc_gen;
   __u64 flags;
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 99c5bff..c96d695 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -226,7 +226,7 @@
 #define TCP_MD5SIG_FLAG_PREFIX 0x1
 #define TCP_MD5SIG_FLAG_IFINDEX 0x2
 struct tcp_md5sig {
-  struct sockaddr_storage tcpm_addr;
+  struct __kernel_sockaddr_storage tcpm_addr;
   __u8 tcpm_flags;
   __u8 tcpm_prefixlen;
   __u16 tcpm_keylen;
diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h
index c765f30..c98ea0b 100644
--- a/libc/kernel/uapi/linux/tls.h
+++ b/libc/kernel/uapi/linux/tls.h
@@ -54,6 +54,18 @@
 #define TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE 0
 #define TLS_CIPHER_CHACHA20_POLY1305_TAG_SIZE 16
 #define TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE 8
+#define TLS_CIPHER_SM4_GCM 55
+#define TLS_CIPHER_SM4_GCM_IV_SIZE 8
+#define TLS_CIPHER_SM4_GCM_KEY_SIZE 16
+#define TLS_CIPHER_SM4_GCM_SALT_SIZE 4
+#define TLS_CIPHER_SM4_GCM_TAG_SIZE 16
+#define TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE 8
+#define TLS_CIPHER_SM4_CCM 56
+#define TLS_CIPHER_SM4_CCM_IV_SIZE 8
+#define TLS_CIPHER_SM4_CCM_KEY_SIZE 16
+#define TLS_CIPHER_SM4_CCM_SALT_SIZE 4
+#define TLS_CIPHER_SM4_CCM_TAG_SIZE 16
+#define TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE 8
 #define TLS_SET_RECORD_TYPE 1
 #define TLS_GET_RECORD_TYPE 2
 struct tls_crypto_info {
@@ -88,6 +100,20 @@
   unsigned char salt[TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE];
   unsigned char rec_seq[TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE];
 };
+struct tls12_crypto_info_sm4_gcm {
+  struct tls_crypto_info info;
+  unsigned char iv[TLS_CIPHER_SM4_GCM_IV_SIZE];
+  unsigned char key[TLS_CIPHER_SM4_GCM_KEY_SIZE];
+  unsigned char salt[TLS_CIPHER_SM4_GCM_SALT_SIZE];
+  unsigned char rec_seq[TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE];
+};
+struct tls12_crypto_info_sm4_ccm {
+  struct tls_crypto_info info;
+  unsigned char iv[TLS_CIPHER_SM4_CCM_IV_SIZE];
+  unsigned char key[TLS_CIPHER_SM4_CCM_KEY_SIZE];
+  unsigned char salt[TLS_CIPHER_SM4_CCM_SALT_SIZE];
+  unsigned char rec_seq[TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE];
+};
 enum {
   TLS_INFO_UNSPEC,
   TLS_INFO_VERSION,
diff --git a/libc/kernel/uapi/linux/tty.h b/libc/kernel/uapi/linux/tty.h
index 48fa908..dcce572 100644
--- a/libc/kernel/uapi/linux/tty.h
+++ b/libc/kernel/uapi/linux/tty.h
@@ -47,4 +47,5 @@
 #define N_NCI 25
 #define N_SPEAKUP 26
 #define N_NULL 27
+#define N_MCTP 28
 #endif
diff --git a/libc/kernel/uapi/linux/tty_flags.h b/libc/kernel/uapi/linux/tty_flags.h
index fe591e5..b8354cf 100644
--- a/libc/kernel/uapi/linux/tty_flags.h
+++ b/libc/kernel/uapi/linux/tty_flags.h
@@ -36,7 +36,6 @@
 #define ASYNCB_AUTOPROBE 15
 #define ASYNCB_MAGIC_MULTIPLIER 16
 #define ASYNCB_LAST_USER 16
-#ifndef _KERNEL_
 #define ASYNCB_INITIALIZED 31
 #define ASYNCB_SUSPENDED 30
 #define ASYNCB_NORMAL_ACTIVE 29
@@ -47,7 +46,6 @@
 #define ASYNCB_SHARE_IRQ 24
 #define ASYNCB_CONS_FLOW 23
 #define ASYNCB_FIRST_KERNEL 22
-#endif
 #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY)
 #define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED)
 #define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
@@ -67,12 +65,11 @@
 #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE)
 #define ASYNC_MAGIC_MULTIPLIER (1U << ASYNCB_MAGIC_MULTIPLIER)
 #define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1)
-#define ASYNC_DEPRECATED (ASYNC_SESSION_LOCKOUT | ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP | ASYNC_AUTOPROBE)
+#define ASYNC_DEPRECATED (ASYNC_SPLIT_TERMIOS | ASYNC_SESSION_LOCKOUT | ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP | ASYNC_AUTOPROBE)
 #define ASYNC_USR_MASK (ASYNC_SPD_MASK | ASYNC_CALLOUT_NOHUP | ASYNC_LOW_LATENCY)
 #define ASYNC_SPD_CUST (ASYNC_SPD_HI | ASYNC_SPD_VHI)
 #define ASYNC_SPD_WARP (ASYNC_SPD_HI | ASYNC_SPD_SHI)
 #define ASYNC_SPD_MASK (ASYNC_SPD_HI | ASYNC_SPD_VHI | ASYNC_SPD_SHI)
-#ifndef _KERNEL_
 #define ASYNC_INITIALIZED (1U << ASYNCB_INITIALIZED)
 #define ASYNC_NORMAL_ACTIVE (1U << ASYNCB_NORMAL_ACTIVE)
 #define ASYNC_BOOT_AUTOCONF (1U << ASYNCB_BOOT_AUTOCONF)
@@ -83,4 +80,3 @@
 #define ASYNC_CONS_FLOW (1U << ASYNCB_CONS_FLOW)
 #define ASYNC_INTERNAL_FLAGS (~((1U << ASYNCB_FIRST_KERNEL) - 1))
 #endif
-#endif
diff --git a/libc/kernel/uapi/linux/usb/video.h b/libc/kernel/uapi/linux/usb/video.h
index cd2ede9..b45bada 100644
--- a/libc/kernel/uapi/linux/usb/video.h
+++ b/libc/kernel/uapi/linux/usb/video.h
@@ -217,8 +217,9 @@
   __u8 bControlSize;
   __u8 bmControls[2];
   __u8 iProcessing;
+  __u8 bmVideoStandards;
 } __attribute__((__packed__));
-#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9 + (n))
+#define UVC_DT_PROCESSING_UNIT_SIZE(n) (10 + (n))
 struct uvc_extension_unit_descriptor {
   __u8 bLength;
   __u8 bDescriptorType;
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index fc100ae..ca7b7a5 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -20,16 +20,18 @@
 #define _LINUX_USERFAULTFD_H
 #include <linux/types.h>
 #define UFFD_API ((__u64) 0xAA)
-#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)
+#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)
 #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)
-#define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY)
+#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)
 #define _UFFDIO_REGISTER (0x00)
 #define _UFFDIO_UNREGISTER (0x01)
 #define _UFFDIO_WAKE (0x02)
 #define _UFFDIO_COPY (0x03)
 #define _UFFDIO_ZEROPAGE (0x04)
 #define _UFFDIO_WRITEPROTECT (0x06)
+#define _UFFDIO_CONTINUE (0x07)
 #define _UFFDIO_API (0x3F)
 #define UFFDIO 0xAA
 #define UFFDIO_API _IOWR(UFFDIO, _UFFDIO_API, struct uffdio_api)
@@ -39,6 +41,7 @@
 #define UFFDIO_COPY _IOWR(UFFDIO, _UFFDIO_COPY, struct uffdio_copy)
 #define UFFDIO_ZEROPAGE _IOWR(UFFDIO, _UFFDIO_ZEROPAGE, struct uffdio_zeropage)
 #define UFFDIO_WRITEPROTECT _IOWR(UFFDIO, _UFFDIO_WRITEPROTECT, struct uffdio_writeprotect)
+#define UFFDIO_CONTINUE _IOWR(UFFDIO, _UFFDIO_CONTINUE, struct uffdio_continue)
 struct uffd_msg {
   __u8 event;
   __u8 reserved1;
@@ -78,6 +81,7 @@
 #define UFFD_EVENT_UNMAP 0x16
 #define UFFD_PAGEFAULT_FLAG_WRITE (1 << 0)
 #define UFFD_PAGEFAULT_FLAG_WP (1 << 1)
+#define UFFD_PAGEFAULT_FLAG_MINOR (1 << 2)
 struct uffdio_api {
   __u64 api;
 #define UFFD_FEATURE_PAGEFAULT_FLAG_WP (1 << 0)
@@ -89,6 +93,8 @@
 #define UFFD_FEATURE_EVENT_UNMAP (1 << 6)
 #define UFFD_FEATURE_SIGBUS (1 << 7)
 #define UFFD_FEATURE_THREAD_ID (1 << 8)
+#define UFFD_FEATURE_MINOR_HUGETLBFS (1 << 9)
+#define UFFD_FEATURE_MINOR_SHMEM (1 << 10)
   __u64 features;
   __u64 ioctls;
 };
@@ -100,6 +106,7 @@
   struct uffdio_range range;
 #define UFFDIO_REGISTER_MODE_MISSING ((__u64) 1 << 0)
 #define UFFDIO_REGISTER_MODE_WP ((__u64) 1 << 1)
+#define UFFDIO_REGISTER_MODE_MINOR ((__u64) 1 << 2)
   __u64 mode;
   __u64 ioctls;
 };
@@ -124,5 +131,11 @@
 #define UFFDIO_WRITEPROTECT_MODE_DONTWAKE ((__u64) 1 << 1)
   __u64 mode;
 };
+struct uffdio_continue {
+  struct uffdio_range range;
+#define UFFDIO_CONTINUE_MODE_DONTWAKE ((__u64) 1 << 0)
+  __u64 mode;
+  __s64 mapped;
+};
 #define UFFD_USER_MODE_ONLY 1
 #endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 75e5ccd..1a11355 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef __LINUX_V4L2_CONTROLS_H
 #define __LINUX_V4L2_CONTROLS_H
+#include <linux/const.h>
 #include <linux/types.h>
 #define V4L2_CTRL_CLASS_USER 0x00980000
 #define V4L2_CTRL_CLASS_CODEC 0x00990000
@@ -32,6 +33,7 @@
 #define V4L2_CTRL_CLASS_RF_TUNER 0x00a20000
 #define V4L2_CTRL_CLASS_DETECT 0x00a30000
 #define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a40000
+#define V4L2_CTRL_CLASS_COLORIMETRY 0x00a50000
 #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
 #define V4L2_CID_USER_BASE V4L2_CID_BASE
 #define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
@@ -88,6 +90,7 @@
   V4L2_COLORFX_SOLARIZATION = 13,
   V4L2_COLORFX_ANTIQUE = 14,
   V4L2_COLORFX_SET_CBCR = 15,
+  V4L2_COLORFX_SET_RGB = 16,
 };
 #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE + 32)
 #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE + 33)
@@ -100,7 +103,8 @@
 #define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE + 40)
 #define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE + 41)
 #define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE + 42)
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE + 43)
+#define V4L2_CID_COLORFX_RGB (V4L2_CID_BASE + 43)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE + 44)
 #define V4L2_CID_USER_MEYE_BASE (V4L2_CID_USER_BASE + 0x1000)
 #define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010)
 #define V4L2_CID_USER_S2255_BASE (V4L2_CID_USER_BASE + 0x1030)
@@ -114,6 +118,7 @@
 #define V4L2_CID_USER_ATMEL_ISC_BASE (V4L2_CID_USER_BASE + 0x10c0)
 #define V4L2_CID_USER_CODA_BASE (V4L2_CID_USER_BASE + 0x10e0)
 #define V4L2_CID_USER_CCS_BASE (V4L2_CID_USER_BASE + 0x10f0)
+#define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170)
 #define V4L2_CID_CODEC_BASE (V4L2_CTRL_CLASS_CODEC | 0x900)
 #define V4L2_CID_CODEC_CLASS (V4L2_CTRL_CLASS_CODEC | 1)
 #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_CODEC_BASE + 0)
@@ -318,6 +323,12 @@
 #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_CODEC_BASE + 228)
 #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_CODEC_BASE + 229)
 #define V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID (V4L2_CID_CODEC_BASE + 230)
+#define V4L2_CID_MPEG_VIDEO_AU_DELIMITER (V4L2_CID_CODEC_BASE + 231)
+#define V4L2_CID_MPEG_VIDEO_LTR_COUNT (V4L2_CID_CODEC_BASE + 232)
+#define V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX (V4L2_CID_CODEC_BASE + 233)
+#define V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES (V4L2_CID_CODEC_BASE + 234)
+#define V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR (V4L2_CID_CODEC_BASE + 235)
+#define V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD (V4L2_CID_CODEC_BASE + 236)
 #define V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL (V4L2_CID_CODEC_BASE + 270)
 enum v4l2_mpeg_video_mpeg2_level {
   V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW = 0,
@@ -670,6 +681,8 @@
 #define V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP (V4L2_CID_CODEC_BASE + 650)
 #define V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP (V4L2_CID_CODEC_BASE + 651)
 #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_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 {
@@ -926,6 +939,7 @@
 #define V4L2_CID_TEST_PATTERN_BLUE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6)
 #define V4L2_CID_TEST_PATTERN_GREENB (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7)
 #define V4L2_CID_UNIT_CELL_SIZE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8)
+#define V4L2_CID_NOTIFY_GAINS (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 9)
 #define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900)
 #define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1)
 #define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1)
@@ -1158,17 +1172,17 @@
   __u32 flags;
 };
 #define V4L2_FWHT_VERSION 3
-#define V4L2_FWHT_FL_IS_INTERLACED BIT(0)
-#define V4L2_FWHT_FL_IS_BOTTOM_FIRST BIT(1)
-#define V4L2_FWHT_FL_IS_ALTERNATE BIT(2)
-#define V4L2_FWHT_FL_IS_BOTTOM_FIELD BIT(3)
-#define V4L2_FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4)
-#define V4L2_FWHT_FL_CB_IS_UNCOMPRESSED BIT(5)
-#define V4L2_FWHT_FL_CR_IS_UNCOMPRESSED BIT(6)
-#define V4L2_FWHT_FL_CHROMA_FULL_HEIGHT BIT(7)
-#define V4L2_FWHT_FL_CHROMA_FULL_WIDTH BIT(8)
-#define V4L2_FWHT_FL_ALPHA_IS_UNCOMPRESSED BIT(9)
-#define V4L2_FWHT_FL_I_FRAME BIT(10)
+#define V4L2_FWHT_FL_IS_INTERLACED _BITUL(0)
+#define V4L2_FWHT_FL_IS_BOTTOM_FIRST _BITUL(1)
+#define V4L2_FWHT_FL_IS_ALTERNATE _BITUL(2)
+#define V4L2_FWHT_FL_IS_BOTTOM_FIELD _BITUL(3)
+#define V4L2_FWHT_FL_LUMA_IS_UNCOMPRESSED _BITUL(4)
+#define V4L2_FWHT_FL_CB_IS_UNCOMPRESSED _BITUL(5)
+#define V4L2_FWHT_FL_CR_IS_UNCOMPRESSED _BITUL(6)
+#define V4L2_FWHT_FL_CHROMA_FULL_HEIGHT _BITUL(7)
+#define V4L2_FWHT_FL_CHROMA_FULL_WIDTH _BITUL(8)
+#define V4L2_FWHT_FL_ALPHA_IS_UNCOMPRESSED _BITUL(9)
+#define V4L2_FWHT_FL_I_FRAME _BITUL(10)
 #define V4L2_FWHT_FL_COMPONENTS_NUM_MSK GENMASK(18, 16)
 #define V4L2_FWHT_FL_COMPONENTS_NUM_OFFSET 16
 #define V4L2_FWHT_FL_PIXENC_MSK GENMASK(20, 19)
@@ -1188,6 +1202,279 @@
   __u32 ycbcr_enc;
   __u32 quantization;
 };
+#define V4L2_VP8_SEGMENT_FLAG_ENABLED 0x01
+#define V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP8_SEGMENT_FLAG_UPDATE_FEATURE_DATA 0x04
+#define V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE 0x08
+struct v4l2_vp8_segment {
+  __s8 quant_update[4];
+  __s8 lf_update[4];
+  __u8 segment_probs[3];
+  __u8 padding;
+  __u32 flags;
+};
+#define V4L2_VP8_LF_ADJ_ENABLE 0x01
+#define V4L2_VP8_LF_DELTA_UPDATE 0x02
+#define V4L2_VP8_LF_FILTER_TYPE_SIMPLE 0x04
+struct v4l2_vp8_loop_filter {
+  __s8 ref_frm_delta[4];
+  __s8 mb_mode_delta[4];
+  __u8 sharpness_level;
+  __u8 level;
+  __u16 padding;
+  __u32 flags;
+};
+struct v4l2_vp8_quantization {
+  __u8 y_ac_qi;
+  __s8 y_dc_delta;
+  __s8 y2_dc_delta;
+  __s8 y2_ac_delta;
+  __s8 uv_dc_delta;
+  __s8 uv_ac_delta;
+  __u16 padding;
+};
+#define V4L2_VP8_COEFF_PROB_CNT 11
+#define V4L2_VP8_MV_PROB_CNT 19
+struct v4l2_vp8_entropy {
+  __u8 coeff_probs[4][8][3][V4L2_VP8_COEFF_PROB_CNT];
+  __u8 y_mode_probs[4];
+  __u8 uv_mode_probs[3];
+  __u8 mv_probs[2][V4L2_VP8_MV_PROB_CNT];
+  __u8 padding[3];
+};
+struct v4l2_vp8_entropy_coder_state {
+  __u8 range;
+  __u8 value;
+  __u8 bit_count;
+  __u8 padding;
+};
+#define V4L2_VP8_FRAME_FLAG_KEY_FRAME 0x01
+#define V4L2_VP8_FRAME_FLAG_EXPERIMENTAL 0x02
+#define V4L2_VP8_FRAME_FLAG_SHOW_FRAME 0x04
+#define V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF 0x08
+#define V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN 0x10
+#define V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT 0x20
+#define V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) (! ! ((hdr)->flags & V4L2_VP8_FRAME_FLAG_KEY_FRAME))
+#define V4L2_CID_STATELESS_VP8_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 200)
+struct v4l2_ctrl_vp8_frame {
+  struct v4l2_vp8_segment segment;
+  struct v4l2_vp8_loop_filter lf;
+  struct v4l2_vp8_quantization quant;
+  struct v4l2_vp8_entropy entropy;
+  struct v4l2_vp8_entropy_coder_state coder_state;
+  __u16 width;
+  __u16 height;
+  __u8 horizontal_scale;
+  __u8 vertical_scale;
+  __u8 version;
+  __u8 prob_skip_false;
+  __u8 prob_intra;
+  __u8 prob_last;
+  __u8 prob_gf;
+  __u8 num_dct_parts;
+  __u32 first_part_size;
+  __u32 first_part_header_bits;
+  __u32 dct_part_sizes[8];
+  __u64 last_frame_ts;
+  __u64 golden_frame_ts;
+  __u64 alt_frame_ts;
+  __u64 flags;
+};
+#define V4L2_MPEG2_SEQ_FLAG_PROGRESSIVE 0x01
+#define V4L2_CID_STATELESS_MPEG2_SEQUENCE (V4L2_CID_CODEC_STATELESS_BASE + 220)
+struct v4l2_ctrl_mpeg2_sequence {
+  __u16 horizontal_size;
+  __u16 vertical_size;
+  __u32 vbv_buffer_size;
+  __u16 profile_and_level_indication;
+  __u8 chroma_format;
+  __u8 flags;
+};
+#define V4L2_MPEG2_PIC_CODING_TYPE_I 1
+#define V4L2_MPEG2_PIC_CODING_TYPE_P 2
+#define V4L2_MPEG2_PIC_CODING_TYPE_B 3
+#define V4L2_MPEG2_PIC_CODING_TYPE_D 4
+#define V4L2_MPEG2_PIC_TOP_FIELD 0x1
+#define V4L2_MPEG2_PIC_BOTTOM_FIELD 0x2
+#define V4L2_MPEG2_PIC_FRAME 0x3
+#define V4L2_MPEG2_PIC_FLAG_TOP_FIELD_FIRST 0x0001
+#define V4L2_MPEG2_PIC_FLAG_FRAME_PRED_DCT 0x0002
+#define V4L2_MPEG2_PIC_FLAG_CONCEALMENT_MV 0x0004
+#define V4L2_MPEG2_PIC_FLAG_Q_SCALE_TYPE 0x0008
+#define V4L2_MPEG2_PIC_FLAG_INTRA_VLC 0x0010
+#define V4L2_MPEG2_PIC_FLAG_ALT_SCAN 0x0020
+#define V4L2_MPEG2_PIC_FLAG_REPEAT_FIRST 0x0040
+#define V4L2_MPEG2_PIC_FLAG_PROGRESSIVE 0x0080
+#define V4L2_CID_STATELESS_MPEG2_PICTURE (V4L2_CID_CODEC_STATELESS_BASE + 221)
+struct v4l2_ctrl_mpeg2_picture {
+  __u64 backward_ref_ts;
+  __u64 forward_ref_ts;
+  __u32 flags;
+  __u8 f_code[2][2];
+  __u8 picture_coding_type;
+  __u8 picture_structure;
+  __u8 intra_dc_precision;
+  __u8 reserved[5];
+};
+#define V4L2_CID_STATELESS_MPEG2_QUANTISATION (V4L2_CID_CODEC_STATELESS_BASE + 222)
+struct v4l2_ctrl_mpeg2_quantisation {
+  __u8 intra_quantiser_matrix[64];
+  __u8 non_intra_quantiser_matrix[64];
+  __u8 chroma_intra_quantiser_matrix[64];
+  __u8 chroma_non_intra_quantiser_matrix[64];
+};
+#define V4L2_CID_COLORIMETRY_CLASS_BASE (V4L2_CTRL_CLASS_COLORIMETRY | 0x900)
+#define V4L2_CID_COLORIMETRY_CLASS (V4L2_CTRL_CLASS_COLORIMETRY | 1)
+#define V4L2_CID_COLORIMETRY_HDR10_CLL_INFO (V4L2_CID_COLORIMETRY_CLASS_BASE + 0)
+struct v4l2_ctrl_hdr10_cll_info {
+  __u16 max_content_light_level;
+  __u16 max_pic_average_light_level;
+};
+#define V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY (V4L2_CID_COLORIMETRY_CLASS_BASE + 1)
+#define V4L2_HDR10_MASTERING_PRIMARIES_X_LOW 5
+#define V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH 37000
+#define V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW 5
+#define V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH 42000
+#define V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW 5
+#define V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH 37000
+#define V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW 5
+#define V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH 42000
+#define V4L2_HDR10_MASTERING_MAX_LUMA_LOW 50000
+#define V4L2_HDR10_MASTERING_MAX_LUMA_HIGH 100000000
+#define V4L2_HDR10_MASTERING_MIN_LUMA_LOW 1
+#define V4L2_HDR10_MASTERING_MIN_LUMA_HIGH 50000
+struct v4l2_ctrl_hdr10_mastering_display {
+  __u16 display_primaries_x[3];
+  __u16 display_primaries_y[3];
+  __u16 white_point_x;
+  __u16 white_point_y;
+  __u32 max_display_mastering_luminance;
+  __u32 min_display_mastering_luminance;
+};
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED 0x1
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE 0x2
+struct v4l2_vp9_loop_filter {
+  __s8 ref_deltas[4];
+  __s8 mode_deltas[2];
+  __u8 level;
+  __u8 sharpness;
+  __u8 flags;
+  __u8 reserved[7];
+};
+struct v4l2_vp9_quantization {
+  __u8 base_q_idx;
+  __s8 delta_q_y_dc;
+  __s8 delta_q_uv_dc;
+  __s8 delta_q_uv_ac;
+  __u8 reserved[4];
+};
+#define V4L2_VP9_SEGMENTATION_FLAG_ENABLED 0x01
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE 0x04
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA 0x08
+#define V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE 0x10
+#define V4L2_VP9_SEG_LVL_ALT_Q 0
+#define V4L2_VP9_SEG_LVL_ALT_L 1
+#define V4L2_VP9_SEG_LVL_REF_FRAME 2
+#define V4L2_VP9_SEG_LVL_SKIP 3
+#define V4L2_VP9_SEG_LVL_MAX 4
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id) (1 << (id))
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK 0xf
+struct v4l2_vp9_segmentation {
+  __s16 feature_data[8][4];
+  __u8 feature_enabled[8];
+  __u8 tree_probs[7];
+  __u8 pred_probs[3];
+  __u8 flags;
+  __u8 reserved[5];
+};
+#define V4L2_VP9_FRAME_FLAG_KEY_FRAME 0x001
+#define V4L2_VP9_FRAME_FLAG_SHOW_FRAME 0x002
+#define V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT 0x004
+#define V4L2_VP9_FRAME_FLAG_INTRA_ONLY 0x008
+#define V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV 0x010
+#define V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX 0x020
+#define V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE 0x040
+#define V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING 0x080
+#define V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING 0x100
+#define V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING 0x200
+#define V4L2_VP9_SIGN_BIAS_LAST 0x1
+#define V4L2_VP9_SIGN_BIAS_GOLDEN 0x2
+#define V4L2_VP9_SIGN_BIAS_ALT 0x4
+#define V4L2_VP9_RESET_FRAME_CTX_NONE 0
+#define V4L2_VP9_RESET_FRAME_CTX_SPEC 1
+#define V4L2_VP9_RESET_FRAME_CTX_ALL 2
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP 0
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH 1
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP 2
+#define V4L2_VP9_INTERP_FILTER_BILINEAR 3
+#define V4L2_VP9_INTERP_FILTER_SWITCHABLE 4
+#define V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE 0
+#define V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE 1
+#define V4L2_VP9_REFERENCE_MODE_SELECT 2
+#define V4L2_VP9_PROFILE_MAX 3
+#define V4L2_CID_STATELESS_VP9_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 300)
+struct v4l2_ctrl_vp9_frame {
+  struct v4l2_vp9_loop_filter lf;
+  struct v4l2_vp9_quantization quant;
+  struct v4l2_vp9_segmentation seg;
+  __u32 flags;
+  __u16 compressed_header_size;
+  __u16 uncompressed_header_size;
+  __u16 frame_width_minus_1;
+  __u16 frame_height_minus_1;
+  __u16 render_width_minus_1;
+  __u16 render_height_minus_1;
+  __u64 last_frame_ts;
+  __u64 golden_frame_ts;
+  __u64 alt_frame_ts;
+  __u8 ref_frame_sign_bias;
+  __u8 reset_frame_context;
+  __u8 frame_context_idx;
+  __u8 profile;
+  __u8 bit_depth;
+  __u8 interpolation_filter;
+  __u8 tile_cols_log2;
+  __u8 tile_rows_log2;
+  __u8 reference_mode;
+  __u8 reserved[7];
+};
+#define V4L2_VP9_NUM_FRAME_CTX 4
+struct v4l2_vp9_mv_probs {
+  __u8 joint[3];
+  __u8 sign[2];
+  __u8 classes[2][10];
+  __u8 class0_bit[2];
+  __u8 bits[2][10];
+  __u8 class0_fr[2][2][3];
+  __u8 fr[2][3];
+  __u8 class0_hp[2];
+  __u8 hp[2];
+};
+#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR (V4L2_CID_CODEC_STATELESS_BASE + 301)
+#define V4L2_VP9_TX_MODE_ONLY_4X4 0
+#define V4L2_VP9_TX_MODE_ALLOW_8X8 1
+#define V4L2_VP9_TX_MODE_ALLOW_16X16 2
+#define V4L2_VP9_TX_MODE_ALLOW_32X32 3
+#define V4L2_VP9_TX_MODE_SELECT 4
+struct v4l2_ctrl_vp9_compressed_hdr {
+  __u8 tx_mode;
+  __u8 tx8[2][1];
+  __u8 tx16[2][2];
+  __u8 tx32[2][3];
+  __u8 coef[4][2][2][6][6][3];
+  __u8 skip[3];
+  __u8 inter_mode[7][3];
+  __u8 interp_filter[4][2];
+  __u8 is_inter[4];
+  __u8 comp_mode[5];
+  __u8 single_ref[5][2];
+  __u8 comp_ref[5];
+  __u8 y_mode[4][9];
+  __u8 uv_mode[10][9];
+  __u8 partition[16][3];
+  struct v4l2_vp9_mv_probs mv;
+};
 #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/vdpa.h b/libc/kernel/uapi/linux/vdpa.h
index bee6618..b3e5d39 100644
--- a/libc/kernel/uapi/linux/vdpa.h
+++ b/libc/kernel/uapi/linux/vdpa.h
@@ -27,9 +27,11 @@
   VDPA_CMD_DEV_NEW,
   VDPA_CMD_DEV_DEL,
   VDPA_CMD_DEV_GET,
+  VDPA_CMD_DEV_CONFIG_GET,
 };
 enum vdpa_attr {
   VDPA_ATTR_UNSPEC,
+  VDPA_ATTR_PAD = VDPA_ATTR_UNSPEC,
   VDPA_ATTR_MGMTDEV_BUS_NAME,
   VDPA_ATTR_MGMTDEV_DEV_NAME,
   VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES,
@@ -38,6 +40,14 @@
   VDPA_ATTR_DEV_VENDOR_ID,
   VDPA_ATTR_DEV_MAX_VQS,
   VDPA_ATTR_DEV_MAX_VQ_SIZE,
+  VDPA_ATTR_DEV_MIN_VQ_SIZE,
+  VDPA_ATTR_DEV_NET_CFG_MACADDR,
+  VDPA_ATTR_DEV_NET_STATUS,
+  VDPA_ATTR_DEV_NET_CFG_MAX_VQP,
+  VDPA_ATTR_DEV_NET_CFG_MTU,
+  VDPA_ATTR_DEV_NEGOTIATED_FEATURES,
+  VDPA_ATTR_DEV_MGMTDEV_MAX_VQS,
+  VDPA_ATTR_DEV_SUPPORTED_FEATURES,
   VDPA_ATTR_MAX,
 };
 #endif
diff --git a/libc/kernel/uapi/linux/vduse.h b/libc/kernel/uapi/linux/vduse.h
new file mode 100644
index 0000000..2dc8c82
--- /dev/null
+++ b/libc/kernel/uapi/linux/vduse.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_VDUSE_H_
+#define _UAPI_VDUSE_H_
+#include <linux/types.h>
+#define VDUSE_BASE 0x81
+#define VDUSE_API_VERSION 0
+#define VDUSE_GET_API_VERSION _IOR(VDUSE_BASE, 0x00, __u64)
+#define VDUSE_SET_API_VERSION _IOW(VDUSE_BASE, 0x01, __u64)
+struct vduse_dev_config {
+#define VDUSE_NAME_MAX 256
+  char name[VDUSE_NAME_MAX];
+  __u32 vendor_id;
+  __u32 device_id;
+  __u64 features;
+  __u32 vq_num;
+  __u32 vq_align;
+  __u32 reserved[13];
+  __u32 config_size;
+  __u8 config[];
+};
+#define VDUSE_CREATE_DEV _IOW(VDUSE_BASE, 0x02, struct vduse_dev_config)
+#define VDUSE_DESTROY_DEV _IOW(VDUSE_BASE, 0x03, char[VDUSE_NAME_MAX])
+struct vduse_iotlb_entry {
+  __u64 offset;
+  __u64 start;
+  __u64 last;
+#define VDUSE_ACCESS_RO 0x1
+#define VDUSE_ACCESS_WO 0x2
+#define VDUSE_ACCESS_RW 0x3
+  __u8 perm;
+};
+#define VDUSE_IOTLB_GET_FD _IOWR(VDUSE_BASE, 0x10, struct vduse_iotlb_entry)
+#define VDUSE_DEV_GET_FEATURES _IOR(VDUSE_BASE, 0x11, __u64)
+struct vduse_config_data {
+  __u32 offset;
+  __u32 length;
+  __u8 buffer[];
+};
+#define VDUSE_DEV_SET_CONFIG _IOW(VDUSE_BASE, 0x12, struct vduse_config_data)
+#define VDUSE_DEV_INJECT_CONFIG_IRQ _IO(VDUSE_BASE, 0x13)
+struct vduse_vq_config {
+  __u32 index;
+  __u16 max_size;
+  __u16 reserved[13];
+};
+#define VDUSE_VQ_SETUP _IOW(VDUSE_BASE, 0x14, struct vduse_vq_config)
+struct vduse_vq_state_split {
+  __u16 avail_index;
+};
+struct vduse_vq_state_packed {
+  __u16 last_avail_counter;
+  __u16 last_avail_idx;
+  __u16 last_used_counter;
+  __u16 last_used_idx;
+};
+struct vduse_vq_info {
+  __u32 index;
+  __u32 num;
+  __u64 desc_addr;
+  __u64 driver_addr;
+  __u64 device_addr;
+  union {
+    struct vduse_vq_state_split split;
+    struct vduse_vq_state_packed packed;
+  };
+  __u8 ready;
+};
+#define VDUSE_VQ_GET_INFO _IOWR(VDUSE_BASE, 0x15, struct vduse_vq_info)
+struct vduse_vq_eventfd {
+  __u32 index;
+#define VDUSE_EVENTFD_DEASSIGN - 1
+  int fd;
+};
+#define VDUSE_VQ_SETUP_KICKFD _IOW(VDUSE_BASE, 0x16, struct vduse_vq_eventfd)
+#define VDUSE_VQ_INJECT_IRQ _IOW(VDUSE_BASE, 0x17, __u32)
+enum vduse_req_type {
+  VDUSE_GET_VQ_STATE,
+  VDUSE_SET_STATUS,
+  VDUSE_UPDATE_IOTLB,
+};
+struct vduse_vq_state {
+  __u32 index;
+  union {
+    struct vduse_vq_state_split split;
+    struct vduse_vq_state_packed packed;
+  };
+};
+struct vduse_dev_status {
+  __u8 status;
+};
+struct vduse_iova_range {
+  __u64 start;
+  __u64 last;
+};
+struct vduse_dev_request {
+  __u32 type;
+  __u32 request_id;
+  __u32 reserved[4];
+  union {
+    struct vduse_vq_state vq_state;
+    struct vduse_dev_status s;
+    struct vduse_iova_range iova;
+    __u32 padding[32];
+  };
+};
+struct vduse_dev_response {
+  __u32 request_id;
+#define VDUSE_REQ_RESULT_OK 0x00
+#define VDUSE_REQ_RESULT_FAILED 0x01
+  __u32 result;
+  __u32 reserved[4];
+  union {
+    struct vduse_vq_state vq_state;
+    __u32 padding[32];
+  };
+};
+#endif
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 86c0070..2dfd696 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 330752
+#define LINUX_VERSION_CODE 332032
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
 #define LINUX_VERSION_MAJOR 5
-#define LINUX_VERSION_PATCHLEVEL 12
+#define LINUX_VERSION_PATCHLEVEL 17
 #define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 76d9af9..74bd328 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -24,7 +24,12 @@
 #include <linux/types.h>
 #include <linux/v4l2-common.h>
 #include <linux/v4l2-controls.h>
+/* ---------------------------------------------------
+ * This value manually changed due to b/228783882.
+ * Next kernel update should keep this value as is.
+ */
 #define VIDEO_MAX_FRAME 64
+/* --------------------------------------------------- */
 #define VIDEO_MAX_PLANES 8
 #define v4l2_fourcc(a,b,c,d) ((__u32) (a) | ((__u32) (b) << 8) | ((__u32) (c) << 16) | ((__u32) (d) << 24))
 #define v4l2_fourcc_be(a,b,c,d) (v4l2_fourcc(a, b, c, d) | (1U << 31))
@@ -266,6 +271,7 @@
 #define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4')
 #define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O')
 #define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P')
+#define V4L2_PIX_FMT_YUV24 v4l2_fourcc('Y', 'U', 'V', '3')
 #define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4')
 #define V4L2_PIX_FMT_AYUV32 v4l2_fourcc('A', 'Y', 'U', 'V')
 #define V4L2_PIX_FMT_XYUV32 v4l2_fourcc('X', 'Y', 'U', 'V')
@@ -278,13 +284,10 @@
 #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1')
 #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_HM12 v4l2_fourcc('H', 'M', '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_NV12MT v4l2_fourcc('T', 'M', '1', '2')
-#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', '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')
@@ -297,6 +300,11 @@
 #define V4L2_PIX_FMT_YVU422M v4l2_fourcc('Y', 'M', '6', '1')
 #define V4L2_PIX_FMT_YUV444M v4l2_fourcc('Y', 'M', '2', '4')
 #define V4L2_PIX_FMT_YVU444M v4l2_fourcc('Y', 'M', '4', '2')
+#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_NV12MT v4l2_fourcc('T', 'M', '1', '2')
+#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2')
 #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1')
 #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G')
 #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G')
@@ -355,7 +363,9 @@
 #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G')
 #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L')
 #define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0')
+#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F')
 #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0')
+#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F')
 #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C')
 #define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T')
 #define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H')
@@ -390,8 +400,8 @@
 #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I')
 #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ')
 #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1')
+#define V4L2_PIX_FMT_MM21 v4l2_fourcc('M', 'M', '2', '1')
 #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I')
-#define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2')
 #define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4')
 #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4')
 #define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b')
@@ -526,8 +536,10 @@
   __u32 type;
   __u32 memory;
   __u32 capabilities;
-  __u32 reserved[1];
+  __u8 flags;
+  __u8 reserved[3];
 };
+#define V4L2_MEMORY_FLAG_NON_COHERENT (1 << 0)
 #define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0)
 #define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1)
 #define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
@@ -888,6 +900,12 @@
     struct v4l2_ctrl_h264_slice_params __user * p_h264_slice_params;
     struct v4l2_ctrl_h264_decode_params __user * p_h264_decode_params;
     struct v4l2_ctrl_fwht_params __user * p_fwht_params;
+    struct v4l2_ctrl_vp8_frame __user * p_vp8_frame;
+    struct v4l2_ctrl_mpeg2_sequence __user * p_mpeg2_sequence;
+    struct v4l2_ctrl_mpeg2_picture __user * p_mpeg2_picture;
+    struct v4l2_ctrl_mpeg2_quantisation __user * p_mpeg2_quantisation;
+    struct v4l2_ctrl_vp9_compressed_hdr __user * p_vp9_compressed_hdr_probs;
+    struct v4l2_ctrl_vp9_frame __user * p_vp9_frame;
     void __user * ptr;
   };
 } __attribute__((packed));
@@ -925,6 +943,8 @@
   V4L2_CTRL_TYPE_U16 = 0x0101,
   V4L2_CTRL_TYPE_U32 = 0x0102,
   V4L2_CTRL_TYPE_AREA = 0x0106,
+  V4L2_CTRL_TYPE_HDR10_CLL_INFO = 0x0110,
+  V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY = 0x0111,
   V4L2_CTRL_TYPE_H264_SPS = 0x0200,
   V4L2_CTRL_TYPE_H264_PPS = 0x0201,
   V4L2_CTRL_TYPE_H264_SCALING_MATRIX = 0x0202,
@@ -932,6 +952,12 @@
   V4L2_CTRL_TYPE_H264_DECODE_PARAMS = 0x0204,
   V4L2_CTRL_TYPE_H264_PRED_WEIGHTS = 0x0205,
   V4L2_CTRL_TYPE_FWHT_PARAMS = 0x0220,
+  V4L2_CTRL_TYPE_VP8_FRAME = 0x0240,
+  V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250,
+  V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251,
+  V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252,
+  V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260,
+  V4L2_CTRL_TYPE_VP9_FRAME = 0x0261,
 };
 struct v4l2_queryctrl {
   __u32 id;
@@ -1365,7 +1391,8 @@
   __u32 memory;
   struct v4l2_format format;
   __u32 capabilities;
-  __u32 reserved[7];
+  __u32 flags;
+  __u32 reserved[6];
 };
 #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
 #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
@@ -1450,4 +1477,6 @@
 #define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info)
 #define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl)
 #define BASE_VIDIOC_PRIVATE 192
+#define V4L2_PIX_FMT_HM12 V4L2_PIX_FMT_NV12_16L16
+#define V4L2_PIX_FMT_SUNXI_TILED_NV12 V4L2_PIX_FMT_NV12_32L32
 #endif
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/virtio_bt.h
similarity index 63%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/virtio_bt.h
index bb45c3d..7e29eaa 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/virtio_bt.h
@@ -16,14 +16,25 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
-#include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
+#ifndef _UAPI_LINUX_VIRTIO_BT_H
+#define _UAPI_LINUX_VIRTIO_BT_H
+#include <linux/virtio_types.h>
+#define VIRTIO_BT_F_VND_HCI 0
+#define VIRTIO_BT_F_MSFT_EXT 1
+#define VIRTIO_BT_F_AOSP_EXT 2
+enum virtio_bt_config_type {
+  VIRTIO_BT_CONFIG_TYPE_PRIMARY = 0,
+  VIRTIO_BT_CONFIG_TYPE_AMP = 1,
 };
+enum virtio_bt_config_vendor {
+  VIRTIO_BT_CONFIG_VENDOR_NONE = 0,
+  VIRTIO_BT_CONFIG_VENDOR_ZEPHYR = 1,
+  VIRTIO_BT_CONFIG_VENDOR_INTEL = 2,
+  VIRTIO_BT_CONFIG_VENDOR_REALTEK = 3,
+};
+struct virtio_bt_config {
+  __u8 type;
+  __u16 vendor;
+  __u16 msft_opcode;
+} __attribute__((packed));
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_gpio.h b/libc/kernel/uapi/linux/virtio_gpio.h
new file mode 100644
index 0000000..543fe76
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_gpio.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _LINUX_VIRTIO_GPIO_H
+#define _LINUX_VIRTIO_GPIO_H
+#include <linux/types.h>
+#define VIRTIO_GPIO_F_IRQ 0
+#define VIRTIO_GPIO_MSG_GET_NAMES 0x0001
+#define VIRTIO_GPIO_MSG_GET_DIRECTION 0x0002
+#define VIRTIO_GPIO_MSG_SET_DIRECTION 0x0003
+#define VIRTIO_GPIO_MSG_GET_VALUE 0x0004
+#define VIRTIO_GPIO_MSG_SET_VALUE 0x0005
+#define VIRTIO_GPIO_MSG_IRQ_TYPE 0x0006
+#define VIRTIO_GPIO_STATUS_OK 0x0
+#define VIRTIO_GPIO_STATUS_ERR 0x1
+#define VIRTIO_GPIO_DIRECTION_NONE 0x00
+#define VIRTIO_GPIO_DIRECTION_OUT 0x01
+#define VIRTIO_GPIO_DIRECTION_IN 0x02
+#define VIRTIO_GPIO_IRQ_TYPE_NONE 0x00
+#define VIRTIO_GPIO_IRQ_TYPE_EDGE_RISING 0x01
+#define VIRTIO_GPIO_IRQ_TYPE_EDGE_FALLING 0x02
+#define VIRTIO_GPIO_IRQ_TYPE_EDGE_BOTH 0x03
+#define VIRTIO_GPIO_IRQ_TYPE_LEVEL_HIGH 0x04
+#define VIRTIO_GPIO_IRQ_TYPE_LEVEL_LOW 0x08
+struct virtio_gpio_config {
+  __le16 ngpio;
+  __u8 padding[2];
+  __le32 gpio_names_size;
+};
+struct virtio_gpio_request {
+  __le16 type;
+  __le16 gpio;
+  __le32 value;
+};
+struct virtio_gpio_response {
+  __u8 status;
+  __u8 value;
+};
+struct virtio_gpio_response_get_names {
+  __u8 status;
+  __u8 value[];
+};
+struct virtio_gpio_irq_request {
+  __le16 gpio;
+};
+struct virtio_gpio_irq_response {
+  __u8 status;
+};
+#define VIRTIO_GPIO_IRQ_STATUS_INVALID 0x0
+#define VIRTIO_GPIO_IRQ_STATUS_VALID 0x1
+#endif
diff --git a/libc/kernel/uapi/linux/virtio_gpu.h b/libc/kernel/uapi/linux/virtio_gpu.h
index 83ad5a7..8a21afd 100644
--- a/libc/kernel/uapi/linux/virtio_gpu.h
+++ b/libc/kernel/uapi/linux/virtio_gpu.h
@@ -23,6 +23,7 @@
 #define VIRTIO_GPU_F_EDID 1
 #define VIRTIO_GPU_F_RESOURCE_UUID 2
 #define VIRTIO_GPU_F_RESOURCE_BLOB 3
+#define VIRTIO_GPU_F_CONTEXT_INIT 4
 enum virtio_gpu_ctrl_type {
   VIRTIO_GPU_UNDEFINED = 0,
   VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100,
@@ -70,12 +71,14 @@
   VIRTIO_GPU_SHM_ID_HOST_VISIBLE = 1
 };
 #define VIRTIO_GPU_FLAG_FENCE (1 << 0)
+#define VIRTIO_GPU_FLAG_INFO_RING_IDX (1 << 1)
 struct virtio_gpu_ctrl_hdr {
   __le32 type;
   __le32 flags;
   __le64 fence_id;
   __le32 ctx_id;
-  __le32 padding;
+  __u8 ring_idx;
+  __u8 padding[3];
 };
 struct virtio_gpu_cursor_pos {
   __le32 scanout_id;
@@ -181,10 +184,11 @@
   __le32 flags;
   __le32 padding;
 };
+#define VIRTIO_GPU_CONTEXT_INIT_CAPSET_ID_MASK 0x000000ff
 struct virtio_gpu_ctx_create {
   struct virtio_gpu_ctrl_hdr hdr;
   __le32 nlen;
-  __le32 padding;
+  __le32 context_init;
   char debug_name[64];
 };
 struct virtio_gpu_ctx_destroy {
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/virtio_i2c.h
similarity index 71%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/virtio_i2c.h
index bb45c3d..9540f26 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/virtio_i2c.h
@@ -16,14 +16,21 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
+#ifndef _UAPI_LINUX_VIRTIO_I2C_H
+#define _UAPI_LINUX_VIRTIO_I2C_H
+#include <linux/const.h>
 #include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
+#define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST 0
+#define VIRTIO_I2C_FLAGS_FAIL_NEXT _BITUL(0)
+#define VIRTIO_I2C_FLAGS_M_RD _BITUL(1)
+struct virtio_i2c_out_hdr {
+  __le16 addr;
+  __le16 padding;
+  __le32 flags;
 };
+struct virtio_i2c_in_hdr {
+  __u8 status;
+};
+#define VIRTIO_I2C_MSG_OK 0
+#define VIRTIO_I2C_MSG_ERR 1
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_ids.h b/libc/kernel/uapi/linux/virtio_ids.h
index bae26a0..2894700 100644
--- a/libc/kernel/uapi/linux/virtio_ids.h
+++ b/libc/kernel/uapi/linux/virtio_ids.h
@@ -40,7 +40,28 @@
 #define VIRTIO_ID_PSTORE 22
 #define VIRTIO_ID_IOMMU 23
 #define VIRTIO_ID_MEM 24
+#define VIRTIO_ID_SOUND 25
 #define VIRTIO_ID_FS 26
 #define VIRTIO_ID_PMEM 27
+#define VIRTIO_ID_RPMB 28
 #define VIRTIO_ID_MAC80211_HWSIM 29
+#define VIRTIO_ID_VIDEO_ENCODER 30
+#define VIRTIO_ID_VIDEO_DECODER 31
+#define VIRTIO_ID_SCMI 32
+#define VIRTIO_ID_NITRO_SEC_MOD 33
+#define VIRTIO_ID_I2C_ADAPTER 34
+#define VIRTIO_ID_WATCHDOG 35
+#define VIRTIO_ID_CAN 36
+#define VIRTIO_ID_DMABUF 37
+#define VIRTIO_ID_PARAM_SERV 38
+#define VIRTIO_ID_AUDIO_POLICY 39
+#define VIRTIO_ID_BT 40
+#define VIRTIO_ID_GPIO 41
+#define VIRTIO_TRANS_ID_NET 1000
+#define VIRTIO_TRANS_ID_BLOCK 1001
+#define VIRTIO_TRANS_ID_BALLOON 1002
+#define VIRTIO_TRANS_ID_CONSOLE 1003
+#define VIRTIO_TRANS_ID_SCSI 1004
+#define VIRTIO_TRANS_ID_RNG 1005
+#define VIRTIO_TRANS_ID_9P 1009
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_iommu.h b/libc/kernel/uapi/linux/virtio_iommu.h
index b08de57..ec8def8 100644
--- a/libc/kernel/uapi/linux/virtio_iommu.h
+++ b/libc/kernel/uapi/linux/virtio_iommu.h
@@ -25,6 +25,7 @@
 #define VIRTIO_IOMMU_F_BYPASS 3
 #define VIRTIO_IOMMU_F_PROBE 4
 #define VIRTIO_IOMMU_F_MMIO 5
+#define VIRTIO_IOMMU_F_BYPASS_CONFIG 6
 struct virtio_iommu_range_64 {
   __le64 start;
   __le64 end;
@@ -38,6 +39,8 @@
   struct virtio_iommu_range_64 input_range;
   struct virtio_iommu_range_32 domain_range;
   __le32 probe_size;
+  __u8 bypass;
+  __u8 reserved[3];
 };
 #define VIRTIO_IOMMU_T_ATTACH 0x01
 #define VIRTIO_IOMMU_T_DETACH 0x02
@@ -61,11 +64,13 @@
   __u8 status;
   __u8 reserved[3];
 };
+#define VIRTIO_IOMMU_ATTACH_F_BYPASS (1 << 0)
 struct virtio_iommu_req_attach {
   struct virtio_iommu_req_head head;
   __le32 domain;
   __le32 endpoint;
-  __u8 reserved[8];
+  __le32 flags;
+  __u8 reserved[4];
   struct virtio_iommu_req_tail tail;
 };
 struct virtio_iommu_req_detach {
diff --git a/libc/kernel/uapi/linux/virtio_mem.h b/libc/kernel/uapi/linux/virtio_mem.h
index d6542b7..66ffce1 100644
--- a/libc/kernel/uapi/linux/virtio_mem.h
+++ b/libc/kernel/uapi/linux/virtio_mem.h
@@ -23,6 +23,7 @@
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
 #define VIRTIO_MEM_F_ACPI_PXM 0
+#define VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE 1
 #define VIRTIO_MEM_REQ_PLUG 0
 #define VIRTIO_MEM_REQ_UNPLUG 1
 #define VIRTIO_MEM_REQ_UNPLUG_ALL 2
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/virtio_pcidev.h
similarity index 68%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/virtio_pcidev.h
index bb45c3d..01c5869 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/virtio_pcidev.h
@@ -16,14 +16,26 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
+#ifndef _UAPI_LINUX_VIRTIO_PCIDEV_H
+#define _UAPI_LINUX_VIRTIO_PCIDEV_H
 #include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
+enum virtio_pcidev_ops {
+  VIRTIO_PCIDEV_OP_RESERVED = 0,
+  VIRTIO_PCIDEV_OP_CFG_READ,
+  VIRTIO_PCIDEV_OP_CFG_WRITE,
+  VIRTIO_PCIDEV_OP_MMIO_READ,
+  VIRTIO_PCIDEV_OP_MMIO_WRITE,
+  VIRTIO_PCIDEV_OP_MMIO_MEMSET,
+  VIRTIO_PCIDEV_OP_INT,
+  VIRTIO_PCIDEV_OP_MSI,
+  VIRTIO_PCIDEV_OP_PME,
+};
+struct virtio_pcidev_msg {
+  __u8 op;
+  __u8 bar;
+  __u16 reserved;
+  __u32 size;
+  __u64 addr;
+  __u8 data[];
 };
 #endif
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/virtio_scmi.h
similarity index 78%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/virtio_scmi.h
index bb45c3d..7907ed4 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/virtio_scmi.h
@@ -16,14 +16,12 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
-#include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
-};
+#ifndef _UAPI_LINUX_VIRTIO_SCMI_H
+#define _UAPI_LINUX_VIRTIO_SCMI_H
+#include <linux/virtio_types.h>
+#define VIRTIO_SCMI_F_P2A_CHANNELS 0
+#define VIRTIO_SCMI_F_SHARED_MEMORY 1
+#define VIRTIO_SCMI_VQ_TX 0
+#define VIRTIO_SCMI_VQ_RX 1
+#define VIRTIO_SCMI_VQ_MAX_CNT 2
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_snd.h b/libc/kernel/uapi/linux/virtio_snd.h
new file mode 100644
index 0000000..60dfa62
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_snd.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 VIRTIO_SND_IF_H
+#define VIRTIO_SND_IF_H
+#include <linux/virtio_types.h>
+struct virtio_snd_config {
+  __le32 jacks;
+  __le32 streams;
+  __le32 chmaps;
+};
+enum {
+  VIRTIO_SND_VQ_CONTROL = 0,
+  VIRTIO_SND_VQ_EVENT,
+  VIRTIO_SND_VQ_TX,
+  VIRTIO_SND_VQ_RX,
+  VIRTIO_SND_VQ_MAX
+};
+enum {
+  VIRTIO_SND_D_OUTPUT = 0,
+  VIRTIO_SND_D_INPUT
+};
+enum {
+  VIRTIO_SND_R_JACK_INFO = 1,
+  VIRTIO_SND_R_JACK_REMAP,
+  VIRTIO_SND_R_PCM_INFO = 0x0100,
+  VIRTIO_SND_R_PCM_SET_PARAMS,
+  VIRTIO_SND_R_PCM_PREPARE,
+  VIRTIO_SND_R_PCM_RELEASE,
+  VIRTIO_SND_R_PCM_START,
+  VIRTIO_SND_R_PCM_STOP,
+  VIRTIO_SND_R_CHMAP_INFO = 0x0200,
+  VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
+  VIRTIO_SND_EVT_JACK_DISCONNECTED,
+  VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
+  VIRTIO_SND_EVT_PCM_XRUN,
+  VIRTIO_SND_S_OK = 0x8000,
+  VIRTIO_SND_S_BAD_MSG,
+  VIRTIO_SND_S_NOT_SUPP,
+  VIRTIO_SND_S_IO_ERR
+};
+struct virtio_snd_hdr {
+  __le32 code;
+};
+struct virtio_snd_event {
+  struct virtio_snd_hdr hdr;
+  __le32 data;
+};
+struct virtio_snd_query_info {
+  struct virtio_snd_hdr hdr;
+  __le32 start_id;
+  __le32 count;
+  __le32 size;
+};
+struct virtio_snd_info {
+  __le32 hda_fn_nid;
+};
+struct virtio_snd_jack_hdr {
+  struct virtio_snd_hdr hdr;
+  __le32 jack_id;
+};
+enum {
+  VIRTIO_SND_JACK_F_REMAP = 0
+};
+struct virtio_snd_jack_info {
+  struct virtio_snd_info hdr;
+  __le32 features;
+  __le32 hda_reg_defconf;
+  __le32 hda_reg_caps;
+  __u8 connected;
+  __u8 padding[7];
+};
+struct virtio_snd_jack_remap {
+  struct virtio_snd_jack_hdr hdr;
+  __le32 association;
+  __le32 sequence;
+};
+struct virtio_snd_pcm_hdr {
+  struct virtio_snd_hdr hdr;
+  __le32 stream_id;
+};
+enum {
+  VIRTIO_SND_PCM_F_SHMEM_HOST = 0,
+  VIRTIO_SND_PCM_F_SHMEM_GUEST,
+  VIRTIO_SND_PCM_F_MSG_POLLING,
+  VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS,
+  VIRTIO_SND_PCM_F_EVT_XRUNS
+};
+enum {
+  VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0,
+  VIRTIO_SND_PCM_FMT_MU_LAW,
+  VIRTIO_SND_PCM_FMT_A_LAW,
+  VIRTIO_SND_PCM_FMT_S8,
+  VIRTIO_SND_PCM_FMT_U8,
+  VIRTIO_SND_PCM_FMT_S16,
+  VIRTIO_SND_PCM_FMT_U16,
+  VIRTIO_SND_PCM_FMT_S18_3,
+  VIRTIO_SND_PCM_FMT_U18_3,
+  VIRTIO_SND_PCM_FMT_S20_3,
+  VIRTIO_SND_PCM_FMT_U20_3,
+  VIRTIO_SND_PCM_FMT_S24_3,
+  VIRTIO_SND_PCM_FMT_U24_3,
+  VIRTIO_SND_PCM_FMT_S20,
+  VIRTIO_SND_PCM_FMT_U20,
+  VIRTIO_SND_PCM_FMT_S24,
+  VIRTIO_SND_PCM_FMT_U24,
+  VIRTIO_SND_PCM_FMT_S32,
+  VIRTIO_SND_PCM_FMT_U32,
+  VIRTIO_SND_PCM_FMT_FLOAT,
+  VIRTIO_SND_PCM_FMT_FLOAT64,
+  VIRTIO_SND_PCM_FMT_DSD_U8,
+  VIRTIO_SND_PCM_FMT_DSD_U16,
+  VIRTIO_SND_PCM_FMT_DSD_U32,
+  VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME
+};
+enum {
+  VIRTIO_SND_PCM_RATE_5512 = 0,
+  VIRTIO_SND_PCM_RATE_8000,
+  VIRTIO_SND_PCM_RATE_11025,
+  VIRTIO_SND_PCM_RATE_16000,
+  VIRTIO_SND_PCM_RATE_22050,
+  VIRTIO_SND_PCM_RATE_32000,
+  VIRTIO_SND_PCM_RATE_44100,
+  VIRTIO_SND_PCM_RATE_48000,
+  VIRTIO_SND_PCM_RATE_64000,
+  VIRTIO_SND_PCM_RATE_88200,
+  VIRTIO_SND_PCM_RATE_96000,
+  VIRTIO_SND_PCM_RATE_176400,
+  VIRTIO_SND_PCM_RATE_192000,
+  VIRTIO_SND_PCM_RATE_384000
+};
+struct virtio_snd_pcm_info {
+  struct virtio_snd_info hdr;
+  __le32 features;
+  __le64 formats;
+  __le64 rates;
+  __u8 direction;
+  __u8 channels_min;
+  __u8 channels_max;
+  __u8 padding[5];
+};
+struct virtio_snd_pcm_set_params {
+  struct virtio_snd_pcm_hdr hdr;
+  __le32 buffer_bytes;
+  __le32 period_bytes;
+  __le32 features;
+  __u8 channels;
+  __u8 format;
+  __u8 rate;
+  __u8 padding;
+};
+struct virtio_snd_pcm_xfer {
+  __le32 stream_id;
+};
+struct virtio_snd_pcm_status {
+  __le32 status;
+  __le32 latency_bytes;
+};
+struct virtio_snd_chmap_hdr {
+  struct virtio_snd_hdr hdr;
+  __le32 chmap_id;
+};
+enum {
+  VIRTIO_SND_CHMAP_NONE = 0,
+  VIRTIO_SND_CHMAP_NA,
+  VIRTIO_SND_CHMAP_MONO,
+  VIRTIO_SND_CHMAP_FL,
+  VIRTIO_SND_CHMAP_FR,
+  VIRTIO_SND_CHMAP_RL,
+  VIRTIO_SND_CHMAP_RR,
+  VIRTIO_SND_CHMAP_FC,
+  VIRTIO_SND_CHMAP_LFE,
+  VIRTIO_SND_CHMAP_SL,
+  VIRTIO_SND_CHMAP_SR,
+  VIRTIO_SND_CHMAP_RC,
+  VIRTIO_SND_CHMAP_FLC,
+  VIRTIO_SND_CHMAP_FRC,
+  VIRTIO_SND_CHMAP_RLC,
+  VIRTIO_SND_CHMAP_RRC,
+  VIRTIO_SND_CHMAP_FLW,
+  VIRTIO_SND_CHMAP_FRW,
+  VIRTIO_SND_CHMAP_FLH,
+  VIRTIO_SND_CHMAP_FCH,
+  VIRTIO_SND_CHMAP_FRH,
+  VIRTIO_SND_CHMAP_TC,
+  VIRTIO_SND_CHMAP_TFL,
+  VIRTIO_SND_CHMAP_TFR,
+  VIRTIO_SND_CHMAP_TFC,
+  VIRTIO_SND_CHMAP_TRL,
+  VIRTIO_SND_CHMAP_TRR,
+  VIRTIO_SND_CHMAP_TRC,
+  VIRTIO_SND_CHMAP_TFLC,
+  VIRTIO_SND_CHMAP_TFRC,
+  VIRTIO_SND_CHMAP_TSL,
+  VIRTIO_SND_CHMAP_TSR,
+  VIRTIO_SND_CHMAP_LLFE,
+  VIRTIO_SND_CHMAP_RLFE,
+  VIRTIO_SND_CHMAP_BC,
+  VIRTIO_SND_CHMAP_BLC,
+  VIRTIO_SND_CHMAP_BRC
+};
+#define VIRTIO_SND_CHMAP_MAX_SIZE 18
+struct virtio_snd_chmap_info {
+  struct virtio_snd_info hdr;
+  __u8 direction;
+  __u8 channels;
+  __u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
+};
+#endif
diff --git a/libc/kernel/uapi/linux/virtio_vsock.h b/libc/kernel/uapi/linux/virtio_vsock.h
index 7a9e259..73b5d49 100644
--- a/libc/kernel/uapi/linux/virtio_vsock.h
+++ b/libc/kernel/uapi/linux/virtio_vsock.h
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
+#define VIRTIO_VSOCK_F_SEQPACKET 1
 struct virtio_vsock_config {
   __le64 guest_cid;
 } __attribute__((packed));
@@ -44,6 +45,7 @@
 } __attribute__((packed));
 enum virtio_vsock_type {
   VIRTIO_VSOCK_TYPE_STREAM = 1,
+  VIRTIO_VSOCK_TYPE_SEQPACKET = 2,
 };
 enum virtio_vsock_op {
   VIRTIO_VSOCK_OP_INVALID = 0,
@@ -59,4 +61,8 @@
   VIRTIO_VSOCK_SHUTDOWN_RCV = 1,
   VIRTIO_VSOCK_SHUTDOWN_SEND = 2,
 };
+enum virtio_vsock_rw {
+  VIRTIO_VSOCK_SEQ_EOM = 1,
+  VIRTIO_VSOCK_SEQ_EOR = 2,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/vm_sockets.h b/libc/kernel/uapi/linux/vm_sockets.h
index 50e8456..58f720d 100644
--- a/libc/kernel/uapi/linux/vm_sockets.h
+++ b/libc/kernel/uapi/linux/vm_sockets.h
@@ -25,8 +25,14 @@
 #define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2
 #define SO_VM_SOCKETS_PEER_HOST_VM_ID 3
 #define SO_VM_SOCKETS_TRUSTED 5
-#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD 6
 #define SO_VM_SOCKETS_NONBLOCK_TXRX 7
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW 8
+#if __BITS_PER_LONG == 64 || defined(__x86_64__) && defined(__ILP32__)
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD
+#else
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT (sizeof(time_t) == sizeof(__kernel_long_t) ? SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD : SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW)
+#endif
 #define VMADDR_CID_ANY - 1U
 #define VMADDR_PORT_ANY - 1U
 #define VMADDR_CID_HYPERVISOR 0
diff --git a/libc/kernel/uapi/linux/raw.h b/libc/kernel/uapi/linux/wwan.h
similarity index 81%
copy from libc/kernel/uapi/linux/raw.h
copy to libc/kernel/uapi/linux/wwan.h
index bb45c3d..9f68713 100644
--- a/libc/kernel/uapi/linux/raw.h
+++ b/libc/kernel/uapi/linux/wwan.h
@@ -16,14 +16,12 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef __LINUX_RAW_H
-#define __LINUX_RAW_H
-#include <linux/types.h>
-#define RAW_SETBIND _IO(0xac, 0)
-#define RAW_GETBIND _IO(0xac, 1)
-struct raw_config_request {
-  int raw_minor;
-  __u64 block_major;
-  __u64 block_minor;
+#ifndef _UAPI_WWAN_H_
+#define _UAPI_WWAN_H_
+enum {
+  IFLA_WWAN_UNSPEC,
+  IFLA_WWAN_LINK_ID,
+  __IFLA_WWAN_MAX
 };
+#define IFLA_WWAN_MAX (__IFLA_WWAN_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index b0e930c..f4df95f 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -182,6 +182,10 @@
 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
   XFRM_MSG_MAPPING,
 #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
+  XFRM_MSG_SETDEFAULT,
+#define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT
+  XFRM_MSG_GETDEFAULT,
+#define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT
   __XFRM_MSG_MAX
 };
 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@@ -261,6 +265,7 @@
   XFRMA_SET_MARK,
   XFRMA_SET_MARK_MASK,
   XFRMA_IF_ID,
+  XFRMA_MTIMER_THRESH,
   __XFRMA_MAX
 #define XFRMA_OUTPUT_MARK XFRMA_SET_MARK
 #define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -430,6 +435,14 @@
 };
 #define XFRM_OFFLOAD_IPV6 1
 #define XFRM_OFFLOAD_INBOUND 2
+struct xfrm_userpolicy_default {
+#define XFRM_USERPOLICY_UNSPEC 0
+#define XFRM_USERPOLICY_BLOCK 1
+#define XFRM_USERPOLICY_ACCEPT 2
+  __u8 in;
+  __u8 fwd;
+  __u8 out;
+};
 #define XFRMGRP_ACQUIRE 1
 #define XFRMGRP_EXPIRE 2
 #define XFRMGRP_SA 4
diff --git a/libc/kernel/uapi/misc/habanalabs.h b/libc/kernel/uapi/misc/habanalabs.h
index b009023..6e3439a 100644
--- a/libc/kernel/uapi/misc/habanalabs.h
+++ b/libc/kernel/uapi/misc/habanalabs.h
@@ -208,11 +208,43 @@
   GAUDI_ENGINE_ID_NIC_9,
   GAUDI_ENGINE_ID_SIZE
 };
+enum hl_goya_pll_index {
+  HL_GOYA_CPU_PLL = 0,
+  HL_GOYA_IC_PLL,
+  HL_GOYA_MC_PLL,
+  HL_GOYA_MME_PLL,
+  HL_GOYA_PCI_PLL,
+  HL_GOYA_EMMC_PLL,
+  HL_GOYA_TPC_PLL,
+  HL_GOYA_PLL_MAX
+};
+enum hl_gaudi_pll_index {
+  HL_GAUDI_CPU_PLL = 0,
+  HL_GAUDI_PCI_PLL,
+  HL_GAUDI_SRAM_PLL,
+  HL_GAUDI_HBM_PLL,
+  HL_GAUDI_NIC_PLL,
+  HL_GAUDI_DMA_PLL,
+  HL_GAUDI_MESH_PLL,
+  HL_GAUDI_MME_PLL,
+  HL_GAUDI_TPC_PLL,
+  HL_GAUDI_IF_PLL,
+  HL_GAUDI_PLL_MAX
+};
 enum hl_device_status {
   HL_DEVICE_STATUS_OPERATIONAL,
   HL_DEVICE_STATUS_IN_RESET,
   HL_DEVICE_STATUS_MALFUNCTION,
-  HL_DEVICE_STATUS_NEEDS_RESET
+  HL_DEVICE_STATUS_NEEDS_RESET,
+  HL_DEVICE_STATUS_IN_DEVICE_CREATION,
+  HL_DEVICE_STATUS_LAST = HL_DEVICE_STATUS_IN_DEVICE_CREATION
+};
+enum hl_server_type {
+  HL_SERVER_TYPE_UNKNOWN = 0,
+  HL_SERVER_GAUDI_HLS1 = 1,
+  HL_SERVER_GAUDI_HLS1H = 2,
+  HL_SERVER_GAUDI_TYPE1 = 3,
+  HL_SERVER_GAUDI_TYPE2 = 4
 };
 #define HL_INFO_HW_IP_INFO 0
 #define HL_INFO_HW_EVENTS 1
@@ -230,6 +262,13 @@
 #define HL_INFO_SYNC_MANAGER 14
 #define HL_INFO_TOTAL_ENERGY 15
 #define HL_INFO_PLL_FREQUENCY 16
+#define HL_INFO_POWER 17
+#define HL_INFO_OPEN_STATS 18
+#define HL_INFO_DRAM_REPLACED_ROWS 21
+#define HL_INFO_DRAM_PENDING_ROWS 22
+#define HL_INFO_LAST_ERR_OPEN_DEV_TIME 23
+#define HL_INFO_CS_TIMEOUT_EVENT 24
+#define HL_INFO_RAZWI_EVENT 25
 #define HL_INFO_VERSION_MAX_LEN 128
 #define HL_INFO_CARD_NAME_MAX_LEN 16
 struct hl_info_hw_ip_info {
@@ -242,7 +281,7 @@
   __u32 module_id;
   __u32 reserved;
   __u16 first_available_interrupt_id;
-  __u16 reserved2;
+  __u16 server_type;
   __u32 cpld_version;
   __u32 psoc_pci_pll_nr;
   __u32 psoc_pci_pll_nf;
@@ -253,7 +292,7 @@
   __u8 pad[2];
   __u8 cpucp_version[HL_INFO_VERSION_MAX_LEN];
   __u8 card_name[HL_INFO_CARD_NAME_MAX_LEN];
-  __u64 reserved3;
+  __u64 reserved2;
   __u64 dram_page_size;
 };
 struct hl_info_dram_usage {
@@ -291,10 +330,18 @@
   __u64 tx_throughput;
   __u64 replay_cnt;
 };
-#define HL_CLK_THROTTLE_POWER 0x1
-#define HL_CLK_THROTTLE_THERMAL 0x2
+enum hl_clk_throttling_type {
+  HL_CLK_THROTTLE_TYPE_POWER,
+  HL_CLK_THROTTLE_TYPE_THERMAL,
+  HL_CLK_THROTTLE_TYPE_MAX
+};
+#define HL_CLK_THROTTLE_POWER (1 << HL_CLK_THROTTLE_TYPE_POWER)
+#define HL_CLK_THROTTLE_THERMAL (1 << HL_CLK_THROTTLE_TYPE_THERMAL)
 struct hl_info_clk_throttle {
   __u32 clk_throttling_reason;
+  __u32 pad;
+  __u64 clk_throttling_timestamp_us[HL_CLK_THROTTLE_TYPE_MAX];
+  __u64 clk_throttling_duration_ns[HL_CLK_THROTTLE_TYPE_MAX];
 };
 struct hl_info_energy {
   __u64 total_energy_consumption;
@@ -303,6 +350,13 @@
 struct hl_pll_frequency_info {
   __u16 output[HL_PLL_NUM_OUTPUTS];
 };
+struct hl_open_stats_info {
+  __u64 open_counter;
+  __u64 last_open_period_ms;
+};
+struct hl_power_info {
+  __u64 power;
+};
 struct hl_info_sync_manager {
   __u32 first_available_sync_object;
   __u32 first_available_monitor;
@@ -323,6 +377,24 @@
   __u64 total_validation_drop_cnt;
   __u64 ctx_validation_drop_cnt;
 };
+struct hl_info_last_err_open_dev_time {
+  __s64 timestamp;
+};
+struct hl_info_cs_timeout_event {
+  __s64 timestamp;
+  __u64 seq;
+};
+#define HL_RAZWI_PAGE_FAULT 0
+#define HL_RAZWI_MMU_ACCESS_ERROR 1
+struct hl_info_razwi_event {
+  __s64 timestamp;
+  __u64 addr;
+  __u16 engine_id_1;
+  __u16 engine_id_2;
+  __u8 no_engine_id;
+  __u8 error_type;
+  __u8 pad[2];
+};
 enum gaudi_dcores {
   HL_GAUDI_WS_DCORE,
   HL_GAUDI_WN_DCORE,
@@ -346,6 +418,7 @@
 #define HL_CB_OP_INFO 2
 #define HL_MAX_CB_SIZE (0x200000 - 32)
 #define HL_CB_FLAGS_MAP 0x1
+#define HL_CB_FLAGS_GET_DEVICE_VA 0x2
 struct hl_cb_in {
   __u64 cb_handle;
   __u32 op;
@@ -356,9 +429,12 @@
 struct hl_cb_out {
   union {
     __u64 cb_handle;
-    struct {
-      __u32 usage_cnt;
-      __u32 pad;
+    union {
+      struct {
+        __u32 usage_cnt;
+        __u32 pad;
+      };
+      __u64 device_va;
     };
   };
 };
@@ -371,11 +447,13 @@
   union {
     __u64 cb_handle;
     __u64 signal_seq_arr;
+    __u64 encaps_signal_seq;
   };
   __u32 queue_index;
   union {
     __u32 cb_size;
     __u32 num_signal_seq_arr;
+    __u32 encaps_signal_offset;
   };
   __u32 cs_chunk_flags;
   __u32 collective_engine_id;
@@ -389,47 +467,89 @@
 #define HL_CS_FLAGS_STAGED_SUBMISSION 0x40
 #define HL_CS_FLAGS_STAGED_SUBMISSION_FIRST 0x80
 #define HL_CS_FLAGS_STAGED_SUBMISSION_LAST 0x100
+#define HL_CS_FLAGS_CUSTOM_TIMEOUT 0x200
+#define HL_CS_FLAGS_SKIP_RESET_ON_TIMEOUT 0x400
+#define HL_CS_FLAGS_ENCAP_SIGNALS 0x800
+#define HL_CS_FLAGS_RESERVE_SIGNALS_ONLY 0x1000
+#define HL_CS_FLAGS_UNRESERVE_SIGNALS_ONLY 0x2000
 #define HL_CS_STATUS_SUCCESS 0
 #define HL_MAX_JOBS_PER_CS 512
 struct hl_cs_in {
   __u64 chunks_restore;
   __u64 chunks_execute;
   union {
-    __u64 chunks_store;
     __u64 seq;
+    __u32 encaps_sig_handle_id;
+    struct {
+      __u32 encaps_signals_count;
+      __u32 encaps_signals_q_idx;
+    };
   };
   __u32 num_chunks_restore;
   __u32 num_chunks_execute;
-  __u32 num_chunks_store;
+  __u32 timeout;
   __u32 cs_flags;
   __u32 ctx_id;
 };
 struct hl_cs_out {
-  __u64 seq;
+  union {
+    __u64 seq;
+    struct {
+      __u32 handle_id;
+      __u32 count;
+    };
+  };
   __u32 status;
-  __u32 pad;
+  __u32 sob_base_addr_offset;
+  __u16 sob_count_before_submission;
+  __u16 pad[3];
 };
 union hl_cs_args {
   struct hl_cs_in in;
   struct hl_cs_out out;
 };
+#define HL_WAIT_CS_FLAGS_INTERRUPT 0x2
+#define HL_WAIT_CS_FLAGS_INTERRUPT_MASK 0xFFF00000
+#define HL_WAIT_CS_FLAGS_MULTI_CS 0x4
+#define HL_WAIT_CS_FLAGS_INTERRUPT_KERNEL_CQ 0x10
+#define HL_WAIT_MULTI_CS_LIST_MAX_LEN 32
 struct hl_wait_cs_in {
-  __u64 seq;
-  __u64 timeout_us;
+  union {
+    struct {
+      __u64 seq;
+      __u64 timeout_us;
+    };
+    struct {
+      union {
+        __u64 addr;
+        __u64 cq_counters_handle;
+      };
+      __u64 target;
+    };
+  };
   __u32 ctx_id;
-  __u32 pad;
+  __u32 flags;
+  union {
+    struct {
+      __u8 seq_arr_len;
+      __u8 pad[7];
+    };
+    __u64 interrupt_timeout_us;
+  };
+  __u64 cq_counters_offset;
 };
 #define HL_WAIT_CS_STATUS_COMPLETED 0
 #define HL_WAIT_CS_STATUS_BUSY 1
 #define HL_WAIT_CS_STATUS_TIMEDOUT 2
 #define HL_WAIT_CS_STATUS_ABORTED 3
-#define HL_WAIT_CS_STATUS_INTERRUPTED 4
 #define HL_WAIT_CS_STATUS_FLAG_GONE 0x1
 #define HL_WAIT_CS_STATUS_FLAG_TIMESTAMP_VLD 0x2
 struct hl_wait_cs_out {
   __u32 status;
   __u32 flags;
   __s64 timestamp_nsec;
+  __u32 cs_completion_map;
+  __u32 pad;
 };
 union hl_wait_cs_args {
   struct hl_wait_cs_in in;
@@ -440,9 +560,11 @@
 #define HL_MEM_OP_MAP 2
 #define HL_MEM_OP_UNMAP 3
 #define HL_MEM_OP_MAP_BLOCK 4
+#define HL_MEM_OP_EXPORT_DMABUF_FD 5
 #define HL_MEM_CONTIGUOUS 0x1
 #define HL_MEM_SHARED 0x2
 #define HL_MEM_USERPTR 0x4
+#define HL_MEM_FORCE_HINT 0x8
 struct hl_mem_in {
   union {
     struct {
@@ -466,6 +588,10 @@
     struct {
       __u64 device_virt_addr;
     } unmap;
+    struct {
+      __u64 handle;
+      __u64 mem_size;
+    } export_dmabuf_fd;
   };
   __u32 op;
   __u32 flags;
@@ -481,6 +607,7 @@
       __u32 block_size;
       __u32 pad;
     };
+    __s32 fd;
   };
 };
 union hl_mem_args {
diff --git a/libc/kernel/uapi/misc/uacce/hisi_qm.h b/libc/kernel/uapi/misc/uacce/hisi_qm.h
index 49d9f6a..87757a9 100644
--- a/libc/kernel/uapi/misc/uacce/hisi_qm.h
+++ b/libc/kernel/uapi/misc/uacce/hisi_qm.h
@@ -25,5 +25,6 @@
 };
 #define HISI_QM_API_VER_BASE "hisi_qm_v1"
 #define HISI_QM_API_VER2_BASE "hisi_qm_v2"
+#define HISI_QM_API_VER3_BASE "hisi_qm_v3"
 #define UACCE_CMD_QM_SET_QP_CTX _IOWR('H', 10, struct hisi_qp_ctx)
 #endif
diff --git a/libc/kernel/uapi/mtd/mtd-abi.h b/libc/kernel/uapi/mtd/mtd-abi.h
index 680ac1e..50ae565 100644
--- a/libc/kernel/uapi/mtd/mtd-abi.h
+++ b/libc/kernel/uapi/mtd/mtd-abi.h
@@ -121,6 +121,7 @@
 #define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64)
 #define MEMISLOCKED _IOR('M', 23, struct erase_info_user)
 #define MEMWRITE _IOWR('M', 24, struct mtd_write_req)
+#define OTPERASE _IOW('M', 25, struct otp_info)
 struct nand_oobinfo {
   __u32 useecc;
   __u32 eccbytes;
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 3e45dc3..62ba685 100644
--- a/libc/kernel/uapi/rdma/bnxt_re-abi.h
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -24,7 +24,13 @@
 #define BNXT_RE_CHIP_ID0_CHIP_REV_SFT 0x10
 #define BNXT_RE_CHIP_ID0_CHIP_MET_SFT 0x18
 enum {
-  BNXT_RE_UCNTX_CMASK_HAVE_CCTX = 0x1ULL
+  BNXT_RE_UCNTX_CMASK_HAVE_CCTX = 0x1ULL,
+  BNXT_RE_UCNTX_CMASK_HAVE_MODE = 0x02ULL,
+};
+enum bnxt_re_wqe_mode {
+  BNXT_QPLIB_WQE_MODE_STATIC = 0x00,
+  BNXT_QPLIB_WQE_MODE_VARIABLE = 0x01,
+  BNXT_QPLIB_WQE_MODE_INVALID = 0x02,
 };
 struct bnxt_re_uctx_resp {
   __u32 dev_id;
@@ -36,6 +42,8 @@
   __aligned_u64 comp_mask;
   __u32 chip_id0;
   __u32 chip_id1;
+  __u32 mode;
+  __u32 rsvd1;
 };
 struct bnxt_re_pd_resp {
   __u32 pdid;
diff --git a/libc/kernel/uapi/rdma/efa-abi.h b/libc/kernel/uapi/rdma/efa-abi.h
index f20e3e0..4b6842b 100644
--- a/libc/kernel/uapi/rdma/efa-abi.h
+++ b/libc/kernel/uapi/rdma/efa-abi.h
@@ -47,11 +47,18 @@
   __u16 pdn;
   __u8 reserved_30[2];
 };
+enum {
+  EFA_CREATE_CQ_WITH_COMPLETION_CHANNEL = 1 << 0,
+};
 struct efa_ibv_create_cq {
   __u32 comp_mask;
   __u32 cq_entry_size;
   __u16 num_sub_cqs;
-  __u8 reserved_50[6];
+  __u8 flags;
+  __u8 reserved_58[5];
+};
+enum {
+  EFA_CREATE_CQ_RESP_DB_OFF = 1 << 0,
 };
 struct efa_ibv_create_cq_resp {
   __u32 comp_mask;
@@ -59,7 +66,9 @@
   __aligned_u64 q_mmap_key;
   __aligned_u64 q_mmap_size;
   __u16 cq_idx;
-  __u8 reserved_d0[6];
+  __u8 reserved_d0[2];
+  __u32 db_off;
+  __aligned_u64 db_mmap_key;
 };
 enum {
   EFA_QP_DRIVER_TYPE_SRD = 0,
@@ -92,6 +101,7 @@
 enum {
   EFA_QUERY_DEVICE_CAPS_RDMA_READ = 1 << 0,
   EFA_QUERY_DEVICE_CAPS_RNR_RETRY = 1 << 1,
+  EFA_QUERY_DEVICE_CAPS_CQ_NOTIFICATIONS = 1 << 2,
 };
 struct efa_ibv_ex_query_device_resp {
   __u32 comp_mask;
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index ad3e460..9c8d028 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -54,13 +54,17 @@
   HNS_ROCE_QP_CAP_RQ_RECORD_DB = 1 << 0,
   HNS_ROCE_QP_CAP_SQ_RECORD_DB = 1 << 1,
   HNS_ROCE_QP_CAP_OWNER_DB = 1 << 2,
+  HNS_ROCE_QP_CAP_DIRECT_WQE = 1 << 5,
 };
 struct hns_roce_ib_create_qp_resp {
   __aligned_u64 cap_flags;
+  __aligned_u64 dwqe_mmap_key;
 };
 struct hns_roce_ib_alloc_ucontext_resp {
   __u32 qp_tab_size;
   __u32 cqe_size;
+  __u32 srq_tab_size;
+  __u32 reserved;
 };
 struct hns_roce_ib_alloc_pd_resp {
   __u32 pdn;
diff --git a/libc/kernel/uapi/rdma/i40iw-abi.h b/libc/kernel/uapi/rdma/i40iw-abi.h
deleted file mode 100644
index 60a17f5..0000000
--- a/libc/kernel/uapi/rdma/i40iw-abi.h
+++ /dev/null
@@ -1,75 +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 I40IW_ABI_H
-#define I40IW_ABI_H
-#include <linux/types.h>
-#define I40IW_ABI_VER 5
-struct i40iw_alloc_ucontext_req {
-  __u32 reserved32;
-  __u8 userspace_ver;
-  __u8 reserved8[3];
-};
-struct i40iw_alloc_ucontext_resp {
-  __u32 max_pds;
-  __u32 max_qps;
-  __u32 wq_size;
-  __u8 kernel_ver;
-  __u8 reserved[3];
-};
-struct i40iw_alloc_pd_resp {
-  __u32 pd_id;
-  __u8 reserved[4];
-};
-struct i40iw_create_cq_req {
-  __aligned_u64 user_cq_buffer;
-  __aligned_u64 user_shadow_area;
-};
-struct i40iw_create_qp_req {
-  __aligned_u64 user_wqe_buffers;
-  __aligned_u64 user_compl_ctx;
-  __aligned_u64 user_sq_phb;
-  __aligned_u64 user_rq_phb;
-};
-enum i40iw_memreg_type {
-  IW_MEMREG_TYPE_MEM = 0x0000,
-  IW_MEMREG_TYPE_QP = 0x0001,
-  IW_MEMREG_TYPE_CQ = 0x0002,
-};
-struct i40iw_mem_reg_req {
-  __u16 reg_type;
-  __u16 cq_pages;
-  __u16 rq_pages;
-  __u16 sq_pages;
-};
-struct i40iw_create_cq_resp {
-  __u32 cq_id;
-  __u32 cq_size;
-  __u32 mmap_db_index;
-  __u32 reserved;
-};
-struct i40iw_create_qp_resp {
-  __u32 qp_id;
-  __u32 actual_sq_size;
-  __u32 actual_rq_size;
-  __u32 i40iw_drv_opt;
-  __u16 push_idx;
-  __u8 lsmm;
-  __u8 rsvd2;
-};
-#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
index c443738..3b94907 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
@@ -181,6 +181,7 @@
   RDMA_DRIVER_OCRDMA,
   RDMA_DRIVER_NES,
   RDMA_DRIVER_I40IW,
+  RDMA_DRIVER_IRDMA = RDMA_DRIVER_I40IW,
   RDMA_DRIVER_VMW_PVRDMA,
   RDMA_DRIVER_QEDR,
   RDMA_DRIVER_HNS,
diff --git a/libc/kernel/uapi/rdma/ib_user_mad.h b/libc/kernel/uapi/rdma/ib_user_mad.h
index dadb590..04b9f08 100644
--- a/libc/kernel/uapi/rdma/ib_user_mad.h
+++ b/libc/kernel/uapi/rdma/ib_user_mad.h
@@ -61,7 +61,7 @@
 };
 struct ib_user_mad {
   struct ib_user_mad_hdr hdr;
-  __aligned_u64 data[0];
+  __aligned_u64 data[];
 };
 typedef unsigned long __attribute__((aligned(4))) packed_ulong;
 #define IB_USER_MAD_LONGS_PER_METHOD_MASK (128 / (8 * sizeof(long)))
diff --git a/libc/kernel/uapi/rdma/irdma-abi.h b/libc/kernel/uapi/rdma/irdma-abi.h
new file mode 100644
index 0000000..b6840cf
--- /dev/null
+++ b/libc/kernel/uapi/rdma/irdma-abi.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 IRDMA_ABI_H
+#define IRDMA_ABI_H
+#include <linux/types.h>
+#define IRDMA_ABI_VER 5
+enum irdma_memreg_type {
+  IRDMA_MEMREG_TYPE_MEM = 0,
+  IRDMA_MEMREG_TYPE_QP = 1,
+  IRDMA_MEMREG_TYPE_CQ = 2,
+};
+struct irdma_alloc_ucontext_req {
+  __u32 rsvd32;
+  __u8 userspace_ver;
+  __u8 rsvd8[3];
+};
+struct irdma_alloc_ucontext_resp {
+  __u32 max_pds;
+  __u32 max_qps;
+  __u32 wq_size;
+  __u8 kernel_ver;
+  __u8 rsvd[3];
+  __aligned_u64 feature_flags;
+  __aligned_u64 db_mmap_key;
+  __u32 max_hw_wq_frags;
+  __u32 max_hw_read_sges;
+  __u32 max_hw_inline;
+  __u32 max_hw_rq_quanta;
+  __u32 max_hw_wq_quanta;
+  __u32 min_hw_cq_size;
+  __u32 max_hw_cq_size;
+  __u16 max_hw_sq_chunk;
+  __u8 hw_rev;
+  __u8 rsvd2;
+};
+struct irdma_alloc_pd_resp {
+  __u32 pd_id;
+  __u8 rsvd[4];
+};
+struct irdma_resize_cq_req {
+  __aligned_u64 user_cq_buffer;
+};
+struct irdma_create_cq_req {
+  __aligned_u64 user_cq_buf;
+  __aligned_u64 user_shadow_area;
+};
+struct irdma_create_qp_req {
+  __aligned_u64 user_wqe_bufs;
+  __aligned_u64 user_compl_ctx;
+};
+struct irdma_mem_reg_req {
+  __u16 reg_type;
+  __u16 cq_pages;
+  __u16 rq_pages;
+  __u16 sq_pages;
+};
+struct irdma_modify_qp_req {
+  __u8 sq_flush;
+  __u8 rq_flush;
+  __u8 rsvd[6];
+};
+struct irdma_create_cq_resp {
+  __u32 cq_id;
+  __u32 cq_size;
+};
+struct irdma_create_qp_resp {
+  __u32 qp_id;
+  __u32 actual_sq_size;
+  __u32 actual_rq_size;
+  __u32 irdma_drv_opt;
+  __u16 push_idx;
+  __u8 lsmm;
+  __u8 rsvd;
+  __u32 qp_caps;
+};
+struct irdma_modify_qp_resp {
+  __aligned_u64 push_wqe_mmap_key;
+  __aligned_u64 push_db_mmap_key;
+  __u16 push_offset;
+  __u8 push_valid;
+  __u8 rsvd[5];
+};
+struct irdma_create_ah_resp {
+  __u32 ah_id;
+  __u8 rsvd[4];
+};
+#endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index 59a9f53..aadb20e 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -33,6 +33,7 @@
   MLX5_QP_FLAG_ALLOW_SCATTER_CQE = 1 << 8,
   MLX5_QP_FLAG_PACKET_BASED_CREDIT_MODE = 1 << 9,
   MLX5_QP_FLAG_UAR_PAGE_INDEX = 1 << 10,
+  MLX5_QP_FLAG_DCI_STREAM = 1 << 11,
 };
 enum {
   MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
@@ -67,6 +68,8 @@
   MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0,
   MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY = 1UL << 1,
   MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE = 1UL << 2,
+  MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS = 1UL << 3,
+  MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_REAL_TIME_TS = 1UL << 4,
 };
 enum mlx5_user_cmds_supp_uhw {
   MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE = 1 << 0,
@@ -163,6 +166,10 @@
   __u32 supported_qpts;
   __u32 reserved;
 };
+struct mlx5_ib_dci_streams_caps {
+  __u8 max_log_num_concurent;
+  __u8 max_log_num_errored;
+};
 enum mlx5_ib_query_dev_resp_flags {
   MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0,
   MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_PAD = 1 << 1,
@@ -188,11 +195,13 @@
   struct mlx5_ib_sw_parsing_caps sw_parsing_caps;
   struct mlx5_ib_striding_rq_caps striding_rq_caps;
   __u32 tunnel_offloads_caps;
-  __u32 reserved;
+  struct mlx5_ib_dci_streams_caps dci_streams_caps;
+  __u16 reserved;
 };
 enum mlx5_ib_create_cq_flags {
   MLX5_IB_CREATE_CQ_FLAGS_CQE_128B_PAD = 1 << 0,
   MLX5_IB_CREATE_CQ_FLAGS_UAR_PAGE_INDEX = 1 << 1,
+  MLX5_IB_CREATE_CQ_FLAGS_REAL_TIME_TS = 1 << 2,
 };
 struct mlx5_ib_create_cq {
   __aligned_u64 buf_addr;
@@ -227,6 +236,10 @@
   __u32 srqn;
   __u32 reserved;
 };
+struct mlx5_ib_create_qp_dci_streams {
+  __u8 log_num_concurent;
+  __u8 log_num_errored;
+};
 struct mlx5_ib_create_qp {
   __aligned_u64 buf_addr;
   __aligned_u64 db_addr;
@@ -241,7 +254,8 @@
     __aligned_u64 access_key;
   };
   __u32 ece_options;
-  __u32 reserved;
+  struct mlx5_ib_create_qp_dci_streams dci_streams;
+  __u16 reserved;
 };
 enum mlx5_rx_hash_function_flags {
   MLX5_RX_HASH_FUNC_TOEPLITZ = 1 << 0,
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index 804a90b..862abcb 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -23,6 +23,22 @@
 enum mlx5_ib_create_flow_action_attrs {
   MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS = (1U << UVERBS_ID_NS_SHIFT),
 };
+enum mlx5_ib_dm_methods {
+  MLX5_IB_METHOD_DM_MAP_OP_ADDR = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_METHOD_DM_QUERY,
+};
+enum mlx5_ib_dm_map_op_addr_attrs {
+  MLX5_IB_ATTR_DM_MAP_OP_ADDR_REQ_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_ATTR_DM_MAP_OP_ADDR_REQ_OP,
+  MLX5_IB_ATTR_DM_MAP_OP_ADDR_RESP_START_OFFSET,
+  MLX5_IB_ATTR_DM_MAP_OP_ADDR_RESP_PAGE_INDEX,
+};
+enum mlx5_ib_query_dm_attrs {
+  MLX5_IB_ATTR_QUERY_DM_REQ_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_ATTR_QUERY_DM_RESP_START_OFFSET,
+  MLX5_IB_ATTR_QUERY_DM_RESP_PAGE_INDEX,
+  MLX5_IB_ATTR_QUERY_DM_RESP_LENGTH,
+};
 enum mlx5_ib_alloc_dm_attrs {
   MLX5_IB_ATTR_ALLOC_DM_RESP_START_OFFSET = (1U << UVERBS_ID_NS_SHIFT),
   MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX,
@@ -118,6 +134,7 @@
   MLX5_IB_ATTR_DEVX_UMEM_REG_LEN,
   MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS,
   MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID,
+  MLX5_IB_ATTR_DEVX_UMEM_REG_PGSZ_BITMAP,
 };
 enum mlx5_ib_devx_umem_dereg_attrs {
   MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
@@ -181,7 +198,7 @@
 enum mlx5_ib_device_query_context_attrs {
   MLX5_IB_ATTR_QUERY_CONTEXT_RESP_UCTX = (1U << UVERBS_ID_NS_SHIFT),
 };
-#define MLX5_IB_DW_MATCH_PARAM 0x90
+#define MLX5_IB_DW_MATCH_PARAM 0xA0
 struct mlx5_ib_match_params {
   __u32 match_params[MLX5_IB_DW_MATCH_PARAM];
 };
@@ -236,4 +253,11 @@
 enum mlx5_ib_pd_methods {
   MLX5_IB_METHOD_PD_QUERY = (1U << UVERBS_ID_NS_SHIFT),
 };
+enum mlx5_ib_device_methods {
+  MLX5_IB_METHOD_QUERY_PORT = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum mlx5_ib_query_port_attrs {
+  MLX5_IB_ATTR_QUERY_PORT_PORT_NUM = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_ATTR_QUERY_PORT,
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index bfbfd76..c3c3f89 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -58,4 +58,26 @@
   MLX5_IB_UAPI_UAR_ALLOC_TYPE_BF = 0x0,
   MLX5_IB_UAPI_UAR_ALLOC_TYPE_NC = 0x1,
 };
+enum mlx5_ib_uapi_query_port_flags {
+  MLX5_IB_UAPI_QUERY_PORT_VPORT = 1 << 0,
+  MLX5_IB_UAPI_QUERY_PORT_VPORT_VHCA_ID = 1 << 1,
+  MLX5_IB_UAPI_QUERY_PORT_VPORT_STEERING_ICM_RX = 1 << 2,
+  MLX5_IB_UAPI_QUERY_PORT_VPORT_STEERING_ICM_TX = 1 << 3,
+  MLX5_IB_UAPI_QUERY_PORT_VPORT_REG_C0 = 1 << 4,
+  MLX5_IB_UAPI_QUERY_PORT_ESW_OWNER_VHCA_ID = 1 << 5,
+};
+struct mlx5_ib_uapi_reg {
+  __u32 value;
+  __u32 mask;
+};
+struct mlx5_ib_uapi_query_port {
+  __aligned_u64 flags;
+  __u16 vport;
+  __u16 vport_vhca_id;
+  __u16 esw_owner_vhca_id;
+  __u16 rsvd0;
+  __aligned_u64 vport_steering_icm_rx;
+  __aligned_u64 vport_steering_icm_tx;
+  struct mlx5_ib_uapi_reg reg_c0;
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index 48444da..bdb5fdd 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -207,6 +207,9 @@
   RDMA_NLDEV_CMD_RES_QP_GET_RAW,
   RDMA_NLDEV_CMD_RES_CQ_GET_RAW,
   RDMA_NLDEV_CMD_RES_MR_GET_RAW,
+  RDMA_NLDEV_CMD_RES_CTX_GET,
+  RDMA_NLDEV_CMD_RES_SRQ_GET,
+  RDMA_NLDEV_CMD_STAT_GET_STATUS,
   RDMA_NLDEV_NUM_OPS
 };
 enum rdma_nldev_print_type {
@@ -301,6 +304,16 @@
   RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_VALUE,
   RDMA_NLDEV_ATTR_DEV_DIM,
   RDMA_NLDEV_ATTR_RES_RAW,
+  RDMA_NLDEV_ATTR_RES_CTX,
+  RDMA_NLDEV_ATTR_RES_CTX_ENTRY,
+  RDMA_NLDEV_ATTR_RES_SRQ,
+  RDMA_NLDEV_ATTR_RES_SRQ_ENTRY,
+  RDMA_NLDEV_ATTR_RES_SRQN,
+  RDMA_NLDEV_ATTR_MIN_RANGE,
+  RDMA_NLDEV_ATTR_MAX_RANGE,
+  RDMA_NLDEV_SYS_ATTR_COPY_ON_FORK,
+  RDMA_NLDEV_ATTR_STAT_HWCOUNTER_INDEX,
+  RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC,
   RDMA_NLDEV_ATTR_MAX
 };
 enum rdma_nl_counter_mode {
diff --git a/libc/kernel/uapi/rdma/rdma_user_cm.h b/libc/kernel/uapi/rdma/rdma_user_cm.h
index 9618734..7b1f7ee 100644
--- a/libc/kernel/uapi/rdma/rdma_user_cm.h
+++ b/libc/kernel/uapi/rdma/rdma_user_cm.h
@@ -88,7 +88,7 @@
   __u32 id;
   __u16 addr_size;
   __u16 reserved;
-  struct sockaddr_storage addr;
+  struct __kernel_sockaddr_storage addr;
 };
 struct rdma_ucm_resolve_ip {
   struct sockaddr_in6 src_addr;
@@ -102,8 +102,8 @@
   __u16 src_size;
   __u16 dst_size;
   __u32 reserved;
-  struct sockaddr_storage src_addr;
-  struct sockaddr_storage dst_addr;
+  struct __kernel_sockaddr_storage src_addr;
+  struct __kernel_sockaddr_storage dst_addr;
 };
 struct rdma_ucm_resolve_route {
   __u32 id;
@@ -137,8 +137,8 @@
   __u16 pkey;
   __u16 src_size;
   __u16 dst_size;
-  struct sockaddr_storage src_addr;
-  struct sockaddr_storage dst_addr;
+  struct __kernel_sockaddr_storage src_addr;
+  struct __kernel_sockaddr_storage dst_addr;
   __u32 ibdev_index;
   __u32 reserved1;
 };
@@ -225,7 +225,7 @@
   __u32 id;
   __u16 addr_size;
   __u16 join_flags;
-  struct sockaddr_storage addr;
+  struct __kernel_sockaddr_storage addr;
 };
 struct rdma_ucm_get_event {
   __aligned_u64 response;
diff --git a/libc/kernel/uapi/rdma/rdma_user_rxe.h b/libc/kernel/uapi/rdma/rdma_user_rxe.h
index 9fd21d7..cdb00c7 100644
--- a/libc/kernel/uapi/rdma/rdma_user_rxe.h
+++ b/libc/kernel/uapi/rdma/rdma_user_rxe.h
@@ -76,15 +76,19 @@
       __u32 remote_qpn;
       __u32 remote_qkey;
       __u16 pkey_index;
+      __u16 reserved;
+      __u32 ah_num;
+      __u32 pad[4];
+      struct rxe_av av;
     } ud;
     struct {
-      union {
-        struct ib_mr * mr;
-        __aligned_u64 reserved;
-      };
-      __u32 key;
+      __aligned_u64 addr;
+      __aligned_u64 length;
+      __u32 mr_lkey;
+      __u32 mw_rkey;
+      __u32 rkey;
       __u32 access;
-    } reg;
+    } mw;
   } wr;
 };
 struct rxe_sge {
@@ -105,13 +109,12 @@
   __u32 sge_offset;
   __u32 reserved;
   union {
-    __u8 inline_data[0];
-    struct rxe_sge sge[0];
+    __DECLARE_FLEX_ARRAY(__u8, inline_data);
+    __DECLARE_FLEX_ARRAY(struct rxe_sge, sge);
   };
 };
 struct rxe_send_wqe {
   struct rxe_send_wr wr;
-  struct rxe_av av;
   __u32 status;
   __u32 state;
   __aligned_u64 iova;
@@ -129,6 +132,10 @@
   __u32 padding;
   struct rxe_dma_info dma;
 };
+struct rxe_create_ah_resp {
+  __u32 ah_num;
+  __u32 reserved;
+};
 struct rxe_create_cq_resp {
   struct mminfo mi;
 };
diff --git a/libc/kernel/uapi/scsi/fc/fc_els.h b/libc/kernel/uapi/scsi/fc/fc_els.h
index f31e764..04ae5b8 100644
--- a/libc/kernel/uapi/scsi/fc/fc_els.h
+++ b/libc/kernel/uapi/scsi/fc/fc_els.h
@@ -42,6 +42,7 @@
   ELS_REC = 0x13,
   ELS_SRR = 0x14,
   ELS_FPIN = 0x16,
+  ELS_EDC = 0x17,
   ELS_RDP = 0x18,
   ELS_RDF = 0x19,
   ELS_PRLI = 0x20,
@@ -85,7 +86,7 @@
   ELS_LKA = 0x80,
   ELS_AUTH_ELS = 0x90,
 };
-#define FC_ELS_CMDS_INIT {[ELS_LS_RJT] = "LS_RJT",[ELS_LS_ACC] = "LS_ACC",[ELS_PLOGI] = "PLOGI",[ELS_FLOGI] = "FLOGI",[ELS_LOGO] = "LOGO",[ELS_ABTX] = "ABTX",[ELS_RCS] = "RCS",[ELS_RES] = "RES",[ELS_RSS] = "RSS",[ELS_RSI] = "RSI",[ELS_ESTS] = "ESTS",[ELS_ESTC] = "ESTC",[ELS_ADVC] = "ADVC",[ELS_RTV] = "RTV",[ELS_RLS] = "RLS",[ELS_ECHO] = "ECHO",[ELS_TEST] = "TEST",[ELS_RRQ] = "RRQ",[ELS_REC] = "REC",[ELS_SRR] = "SRR",[ELS_FPIN] = "FPIN",[ELS_RDP] = "RDP",[ELS_RDF] = "RDF",[ELS_PRLI] = "PRLI",[ELS_PRLO] = "PRLO",[ELS_SCN] = "SCN",[ELS_TPLS] = "TPLS",[ELS_TPRLO] = "TPRLO",[ELS_LCLM] = "LCLM",[ELS_GAID] = "GAID",[ELS_FACT] = "FACT",[ELS_FDACDT] = "FDACDT",[ELS_NACT] = "NACT",[ELS_NDACT] = "NDACT",[ELS_QOSR] = "QOSR",[ELS_RVCS] = "RVCS",[ELS_PDISC] = "PDISC",[ELS_FDISC] = "FDISC",[ELS_ADISC] = "ADISC",[ELS_RNC] = "RNC",[ELS_FARP_REQ] = "FARP_REQ",[ELS_FARP_REPL] = "FARP_REPL",[ELS_RPS] = "RPS",[ELS_RPL] = "RPL",[ELS_RPBC] = "RPBC",[ELS_FAN] = "FAN",[ELS_RSCN] = "RSCN",[ELS_SCR] = "SCR",[ELS_RNFT] = "RNFT",[ELS_CSR] = "CSR",[ELS_CSU] = "CSU",[ELS_LINIT] = "LINIT",[ELS_LSTS] = "LSTS",[ELS_RNID] = "RNID",[ELS_RLIR] = "RLIR",[ELS_LIRR] = "LIRR",[ELS_SRL] = "SRL",[ELS_SBRP] = "SBRP",[ELS_RPSC] = "RPSC",[ELS_QSA] = "QSA",[ELS_EVFP] = "EVFP",[ELS_LKA] = "LKA",[ELS_AUTH_ELS] = "AUTH_ELS", \
+#define FC_ELS_CMDS_INIT {[ELS_LS_RJT] = "LS_RJT",[ELS_LS_ACC] = "LS_ACC",[ELS_PLOGI] = "PLOGI",[ELS_FLOGI] = "FLOGI",[ELS_LOGO] = "LOGO",[ELS_ABTX] = "ABTX",[ELS_RCS] = "RCS",[ELS_RES] = "RES",[ELS_RSS] = "RSS",[ELS_RSI] = "RSI",[ELS_ESTS] = "ESTS",[ELS_ESTC] = "ESTC",[ELS_ADVC] = "ADVC",[ELS_RTV] = "RTV",[ELS_RLS] = "RLS",[ELS_ECHO] = "ECHO",[ELS_TEST] = "TEST",[ELS_RRQ] = "RRQ",[ELS_REC] = "REC",[ELS_SRR] = "SRR",[ELS_FPIN] = "FPIN",[ELS_EDC] = "EDC",[ELS_RDP] = "RDP",[ELS_RDF] = "RDF",[ELS_PRLI] = "PRLI",[ELS_PRLO] = "PRLO",[ELS_SCN] = "SCN",[ELS_TPLS] = "TPLS",[ELS_TPRLO] = "TPRLO",[ELS_LCLM] = "LCLM",[ELS_GAID] = "GAID",[ELS_FACT] = "FACT",[ELS_FDACDT] = "FDACDT",[ELS_NACT] = "NACT",[ELS_NDACT] = "NDACT",[ELS_QOSR] = "QOSR",[ELS_RVCS] = "RVCS",[ELS_PDISC] = "PDISC",[ELS_FDISC] = "FDISC",[ELS_ADISC] = "ADISC",[ELS_RNC] = "RNC",[ELS_FARP_REQ] = "FARP_REQ",[ELS_FARP_REPL] = "FARP_REPL",[ELS_RPS] = "RPS",[ELS_RPL] = "RPL",[ELS_RPBC] = "RPBC",[ELS_FAN] = "FAN",[ELS_RSCN] = "RSCN",[ELS_SCR] = "SCR",[ELS_RNFT] = "RNFT",[ELS_CSR] = "CSR",[ELS_CSU] = "CSU",[ELS_LINIT] = "LINIT",[ELS_LSTS] = "LSTS",[ELS_RNID] = "RNID",[ELS_RLIR] = "RLIR",[ELS_LIRR] = "LIRR",[ELS_SRL] = "SRL",[ELS_SBRP] = "SBRP",[ELS_RPSC] = "RPSC",[ELS_QSA] = "QSA",[ELS_EVFP] = "EVFP",[ELS_LKA] = "LKA",[ELS_AUTH_ELS] = "AUTH_ELS", \
 }
 struct fc_els_ls_acc {
   __u8 la_cmd;
@@ -128,13 +129,15 @@
 };
 enum fc_ls_tlv_dtag {
   ELS_DTAG_LS_REQ_INFO = 0x00000001,
+  ELS_DTAG_LNK_FAULT_CAP = 0x0001000D,
+  ELS_DTAG_CG_SIGNAL_CAP = 0x0001000F,
   ELS_DTAG_LNK_INTEGRITY = 0x00020001,
   ELS_DTAG_DELIVERY = 0x00020002,
   ELS_DTAG_PEER_CONGEST = 0x00020003,
   ELS_DTAG_CONGESTION = 0x00020004,
   ELS_DTAG_FPIN_REGISTER = 0x00030001,
 };
-#define FC_LS_TLV_DTAG_INIT { { ELS_DTAG_LS_REQ_INFO, "Link Service Request Information" }, { ELS_DTAG_LNK_INTEGRITY, "Link Integrity Notification" }, { ELS_DTAG_DELIVERY, "Delivery Notification Present" }, { ELS_DTAG_PEER_CONGEST, "Peer Congestion Notification" }, { ELS_DTAG_CONGESTION, "Congestion Notification" }, { ELS_DTAG_FPIN_REGISTER, "FPIN Registration" }, \
+#define FC_LS_TLV_DTAG_INIT { { ELS_DTAG_LS_REQ_INFO, "Link Service Request Information" }, { ELS_DTAG_LNK_FAULT_CAP, "Link Fault Capability" }, { ELS_DTAG_CG_SIGNAL_CAP, "Congestion Signaling Capability" }, { ELS_DTAG_LNK_INTEGRITY, "Link Integrity Notification" }, { ELS_DTAG_DELIVERY, "Delivery Notification Present" }, { ELS_DTAG_PEER_CONGEST, "Peer Congestion Notification" }, { ELS_DTAG_CONGESTION, "Congestion Notification" }, { ELS_DTAG_FPIN_REGISTER, "FPIN Registration" }, \
 }
 struct fc_tlv_desc {
   __be32 desc_tag;
@@ -668,4 +671,48 @@
   struct fc_els_lsri_desc lsri;
   struct fc_tlv_desc desc[0];
 };
+struct fc_diag_lnkflt_desc {
+  __be32 desc_tag;
+  __be32 desc_len;
+  __be32 degrade_activate_threshold;
+  __be32 degrade_deactivate_threshold;
+  __be32 fec_degrade_interval;
+};
+enum fc_edc_cg_signal_cap_types {
+  EDC_CG_SIG_NOTSUPPORTED = 0x00,
+  EDC_CG_SIG_WARN_ONLY = 0x01,
+  EDC_CG_SIG_WARN_ALARM = 0x02,
+};
+#define FC_EDC_CG_SIGNAL_CAP_TYPES_INIT { { EDC_CG_SIG_NOTSUPPORTED, "Signaling Not Supported" }, { EDC_CG_SIG_WARN_ONLY, "Warning Signal" }, { EDC_CG_SIG_WARN_ALARM, "Warning and Alarm Signals" }, \
+}
+enum fc_diag_cg_sig_freq_types {
+  EDC_CG_SIGFREQ_CNT_MIN = 1,
+  EDC_CG_SIGFREQ_CNT_MAX = 999,
+  EDC_CG_SIGFREQ_SEC = 0x1,
+  EDC_CG_SIGFREQ_MSEC = 0x2,
+};
+struct fc_diag_cg_sig_freq {
+  __be16 count;
+  __be16 units;
+};
+struct fc_diag_cg_sig_desc {
+  __be32 desc_tag;
+  __be32 desc_len;
+  __be32 xmt_signal_capability;
+  struct fc_diag_cg_sig_freq xmt_signal_frequency;
+  __be32 rcv_signal_capability;
+  struct fc_diag_cg_sig_freq rcv_signal_frequency;
+};
+struct fc_els_edc {
+  __u8 edc_cmd;
+  __u8 edc_zero[3];
+  __be32 desc_len;
+  struct fc_tlv_desc desc[0];
+};
+struct fc_els_edc_resp {
+  struct fc_els_ls_acc acc_hdr;
+  __be32 desc_list_len;
+  struct fc_els_lsri_desc lsri;
+  struct fc_tlv_desc desc[0];
+};
 #endif
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index c962603..eeb12b0 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -157,8 +157,8 @@
 struct snd_soc_tplg_private {
   __le32 size;
   union {
-    char data[0];
-    struct snd_soc_tplg_vendor_array array[0];
+    __DECLARE_FLEX_ARRAY(char, data);
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_array, array);
   };
 } __attribute__((packed));
 struct snd_soc_tplg_tlv_dbscale {
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 397cccc..b0e47c1 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -32,8 +32,9 @@
 #define SNDRV_PROTOCOL_MINOR(version) (((version) >> 8) & 0xff)
 #define SNDRV_PROTOCOL_MICRO(version) ((version) & 0xff)
 #define SNDRV_PROTOCOL_INCOMPATIBLE(kversion,uversion) (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
+#define AES_IEC958_STATUS_SIZE 24
 struct snd_aes_iec958 {
-  unsigned char status[24];
+  unsigned char status[AES_IEC958_STATUS_SIZE];
   unsigned char subcode[147];
   unsigned char pad;
   unsigned char dig_subframe[4];
@@ -234,6 +235,8 @@
 #define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000
 #define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000
 #define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000
+#define SNDRV_PCM_INFO_EXPLICIT_SYNC 0x10000000
+#define SNDRV_PCM_INFO_NO_REWINDS 0x20000000
 #define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000
 #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000
 #if __BITS_PER_LONG == 32 && defined(__USE_TIME_BITS64)
@@ -562,7 +565,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, 1)
+#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 2)
 enum {
   SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
   SNDRV_RAWMIDI_STREAM_INPUT,
@@ -584,12 +587,32 @@
   unsigned int subdevices_avail;
   unsigned char reserved[64];
 };
+#define SNDRV_RAWMIDI_MODE_FRAMING_MASK (7 << 0)
+#define SNDRV_RAWMIDI_MODE_FRAMING_SHIFT 0
+#define SNDRV_RAWMIDI_MODE_FRAMING_NONE (0 << 0)
+#define SNDRV_RAWMIDI_MODE_FRAMING_TSTAMP (1 << 0)
+#define SNDRV_RAWMIDI_MODE_CLOCK_MASK (7 << 3)
+#define SNDRV_RAWMIDI_MODE_CLOCK_SHIFT 3
+#define SNDRV_RAWMIDI_MODE_CLOCK_NONE (0 << 3)
+#define SNDRV_RAWMIDI_MODE_CLOCK_REALTIME (1 << 3)
+#define SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC (2 << 3)
+#define SNDRV_RAWMIDI_MODE_CLOCK_MONOTONIC_RAW (3 << 3)
+#define SNDRV_RAWMIDI_FRAMING_DATA_LENGTH 16
+struct snd_rawmidi_framing_tstamp {
+  __u8 frame_type;
+  __u8 length;
+  __u8 reserved[2];
+  __u32 tv_nsec;
+  __u64 tv_sec;
+  __u8 data[SNDRV_RAWMIDI_FRAMING_DATA_LENGTH];
+} __packed;
 struct snd_rawmidi_params {
   int stream;
   size_t buffer_size;
   size_t avail_min;
   unsigned int no_active_sensing : 1;
-  unsigned char reserved[16];
+  unsigned int mode;
+  unsigned char reserved[12];
 };
 struct snd_rawmidi_status {
   int stream;
@@ -601,6 +624,7 @@
 };
 #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)
 #define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params)
 #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
 #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
diff --git a/libc/kernel/uapi/sound/firewire.h b/libc/kernel/uapi/sound/firewire.h
index 67c010b..198a8f4 100644
--- a/libc/kernel/uapi/sound/firewire.h
+++ b/libc/kernel/uapi/sound/firewire.h
@@ -26,6 +26,7 @@
 #define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
 #define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
 #define SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL 0x7473636d
+#define SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE 0x4d545244
 struct snd_firewire_event_common {
   unsigned int type;
 };
@@ -68,6 +69,11 @@
   unsigned int type;
   struct snd_firewire_tascam_change changes[0];
 };
+struct snd_firewire_event_motu_register_dsp_change {
+  unsigned int type;
+  __u32 count;
+  __u32 changes[];
+};
 union snd_firewire_event {
   struct snd_firewire_event_common common;
   struct snd_firewire_event_lock_status lock_status;
@@ -76,11 +82,15 @@
   struct snd_firewire_event_digi00x_message digi00x_message;
   struct snd_firewire_event_tascam_control tascam_control;
   struct snd_firewire_event_motu_notification motu_notification;
+  struct snd_firewire_event_motu_register_dsp_change motu_register_dsp_change;
 };
 #define SNDRV_FIREWIRE_IOCTL_GET_INFO _IOR('H', 0xf8, struct snd_firewire_get_info)
 #define SNDRV_FIREWIRE_IOCTL_LOCK _IO('H', 0xf9)
 #define SNDRV_FIREWIRE_IOCTL_UNLOCK _IO('H', 0xfa)
 #define SNDRV_FIREWIRE_IOCTL_TASCAM_STATE _IOR('H', 0xfb, struct snd_firewire_tascam_state)
+#define SNDRV_FIREWIRE_IOCTL_MOTU_REGISTER_DSP_METER _IOR('H', 0xfc, struct snd_firewire_motu_register_dsp_meter)
+#define SNDRV_FIREWIRE_IOCTL_MOTU_COMMAND_DSP_METER _IOR('H', 0xfd, struct snd_firewire_motu_command_dsp_meter)
+#define SNDRV_FIREWIRE_IOCTL_MOTU_REGISTER_DSP_PARAMETER _IOR('H', 0xfe, struct snd_firewire_motu_register_dsp_parameter)
 #define SNDRV_FIREWIRE_TYPE_DICE 1
 #define SNDRV_FIREWIRE_TYPE_FIREWORKS 2
 #define SNDRV_FIREWIRE_TYPE_BEBOB 3
@@ -99,4 +109,49 @@
 struct snd_firewire_tascam_state {
   __be32 data[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
 };
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_INPUT_COUNT 24
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_OUTPUT_COUNT 24
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_COUNT (SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_INPUT_COUNT + SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_OUTPUT_COUNT)
+struct snd_firewire_motu_register_dsp_meter {
+  __u8 data[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_COUNT];
+};
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT 4
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT 20
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT 10
+#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT (SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT + 2)
+struct snd_firewire_motu_register_dsp_parameter {
+  struct {
+    struct {
+      __u8 gain[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
+      __u8 pan[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
+      __u8 flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
+      __u8 paired_balance[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
+      __u8 paired_width[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
+    } source[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT];
+    struct {
+      __u8 paired_volume[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT];
+      __u8 paired_flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT];
+    } output;
+  } mixer;
+  struct {
+    __u8 main_paired_volume;
+    __u8 hp_paired_volume;
+    __u8 hp_paired_assignment;
+    __u8 reserved[5];
+  } output;
+  struct {
+    __u8 boost_flag;
+    __u8 nominal_level_flag;
+    __u8 reserved[6];
+  } line_input;
+  struct {
+    __u8 gain_and_invert[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT];
+    __u8 flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT];
+  } input;
+  __u8 reserved[64];
+};
+#define SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT 400
+struct snd_firewire_motu_command_dsp_meter {
+  float data[SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT];
+};
 #endif
diff --git a/libc/kernel/uapi/sound/snd_ar_tokens.h b/libc/kernel/uapi/sound/snd_ar_tokens.h
new file mode 100644
index 0000000..39c0684
--- /dev/null
+++ b/libc/kernel/uapi/sound/snd_ar_tokens.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 __SND_AR_TOKENS_H__
+#define __SND_AR_TOKENS_H__
+#define APM_SUB_GRAPH_PERF_MODE_LOW_POWER 0x1
+#define APM_SUB_GRAPH_PERF_MODE_LOW_LATENCY 0x2
+#define APM_SUB_GRAPH_DIRECTION_TX 0x1
+#define APM_SUB_GRAPH_DIRECTION_RX 0x2
+#define APM_SUB_GRAPH_SID_AUDIO_PLAYBACK 0x1
+#define APM_SUB_GRAPH_SID_AUDIO_RECORD 0x2
+#define APM_SUB_GRAPH_SID_VOICE_CALL 0x3
+#define APM_CONTAINER_CAP_ID_PP 0x1
+#define APM_CONTAINER_CAP_ID_CD 0x2
+#define APM_CONTAINER_CAP_ID_EP 0x3
+#define APM_CONTAINER_CAP_ID_OLC 0x4
+#define APM_CONT_GRAPH_POS_STREAM 0x1
+#define APM_CONT_GRAPH_POS_PER_STR_PER_DEV 0x2
+#define APM_CONT_GRAPH_POS_STR_DEV 0x3
+#define APM_CONT_GRAPH_POS_GLOBAL_DEV 0x4
+#define APM_PROC_DOMAIN_ID_MDSP 0x1
+#define APM_PROC_DOMAIN_ID_ADSP 0x2
+#define APM_PROC_DOMAIN_ID_SDSP 0x4
+#define APM_PROC_DOMAIN_ID_CDSP 0x5
+#define PCM_INTERLEAVED 1
+#define PCM_DEINTERLEAVED_PACKED 2
+#define PCM_DEINTERLEAVED_UNPACKED 3
+#define AR_I2S_WS_SRC_EXTERNAL 0
+#define AR_I2S_WS_SRC_INTERNAL 1
+enum ar_event_types {
+  AR_EVENT_NONE = 0,
+  AR_PGA_DAPM_EVENT
+};
+#define SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX 256
+#define SND_SOC_AR_TPLG_VOL_CTL 257
+#define AR_TKN_DAI_INDEX 1
+#define AR_TKN_U32_SUB_GRAPH_INSTANCE_ID 2
+#define AR_TKN_U32_SUB_GRAPH_PERF_MODE 3
+#define AR_TKN_U32_SUB_GRAPH_DIRECTION 4
+#define AR_TKN_U32_SUB_GRAPH_SCENARIO_ID 5
+#define AR_TKN_U32_CONTAINER_INSTANCE_ID 100
+#define AR_TKN_U32_CONTAINER_CAPABILITY_ID 101
+#define AR_TKN_U32_CONTAINER_STACK_SIZE 102
+#define AR_TKN_U32_CONTAINER_GRAPH_POS 103
+#define AR_TKN_U32_CONTAINER_PROC_DOMAIN 104
+#define AR_TKN_U32_MODULE_ID 200
+#define AR_TKN_U32_MODULE_INSTANCE_ID 201
+#define AR_TKN_U32_MODULE_MAX_IP_PORTS 202
+#define AR_TKN_U32_MODULE_MAX_OP_PORTS 203
+#define AR_TKN_U32_MODULE_IN_PORTS 204
+#define AR_TKN_U32_MODULE_OUT_PORTS 205
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID 206
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID 207
+#define AR_TKN_U32_MODULE_SRC_INSTANCE_ID 208
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID 209
+#define AR_TKN_U32_MODULE_HW_IF_IDX 250
+#define AR_TKN_U32_MODULE_HW_IF_TYPE 251
+#define AR_TKN_U32_MODULE_FMT_INTERLEAVE 252
+#define AR_TKN_U32_MODULE_FMT_DATA 253
+#define AR_TKN_U32_MODULE_FMT_SAMPLE_RATE 254
+#define AR_TKN_U32_MODULE_FMT_BIT_DEPTH 255
+#define AR_TKN_U32_MODULE_SD_LINE_IDX 256
+#define AR_TKN_U32_MODULE_WS_SRC 257
+#define AR_TKN_U32_MODULE_FRAME_SZ_FACTOR 258
+#define AR_TKN_U32_MODULE_LOG_CODE 259
+#define AR_TKN_U32_MODULE_LOG_TAP_POINT_ID 260
+#define AR_TKN_U32_MODULE_LOG_MODE 261
+#endif
diff --git a/libc/kernel/uapi/sound/snd_sst_tokens.h b/libc/kernel/uapi/sound/snd_sst_tokens.h
index 85a99c7..bf012fa 100644
--- a/libc/kernel/uapi/sound/snd_sst_tokens.h
+++ b/libc/kernel/uapi/sound/snd_sst_tokens.h
@@ -97,6 +97,7 @@
   SKL_TKN_U32_ASTATE_COUNT,
   SKL_TKN_U32_ASTATE_KCPS,
   SKL_TKN_U32_ASTATE_CLK_SRC,
-  SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC,
+  SKL_TKN_U32_FMT_CFG_IDX = 96,
+  SKL_TKN_MAX = SKL_TKN_U32_FMT_CFG_IDX,
 };
 #endif
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index ef62372..856281a 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -36,6 +36,7 @@
 #define SOF_TKN_SCHED_CORE 203
 #define SOF_TKN_SCHED_FRAMES 204
 #define SOF_TKN_SCHED_TIME_DOMAIN 205
+#define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
 #define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
 #define SOF_TKN_VOLUME_RAMP_STEP_MS 251
 #define SOF_TKN_SRC_RATE_IN 300
@@ -86,4 +87,7 @@
 #define SOF_TKN_INTEL_ALH_CH 1401
 #define SOF_TKN_INTEL_HDA_RATE 1500
 #define SOF_TKN_INTEL_HDA_CH 1501
+#define SOF_TKN_MEDIATEK_AFE_RATE 1600
+#define SOF_TKN_MEDIATEK_AFE_CH 1601
+#define SOF_TKN_MEDIATEK_AFE_FORMAT 1602
 #endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c31e306..7397b68 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -631,7 +631,7 @@
     mbsinit;
     mbsnrtowcs; # introduced=21
     mbsrtowcs;
-    mbstowcs;
+    mbstowcs; # introduced=21
     mbtowc; # introduced=21
     memalign;
     memccpy;
@@ -1194,7 +1194,7 @@
     wcstold_l; # introduced=21
     wcstoll; # introduced=21
     wcstoll_l; # introduced=21
-    wcstombs;
+    wcstombs; # introduced=21
     wcstoul;
     wcstoull; # introduced=21
     wcstoull_l; # introduced=21
@@ -1556,6 +1556,7 @@
     __libc_register_thread_exit_callback;
     __libc_iterate_dynamic_tls;
     __libc_register_dynamic_tls_listeners;
+    android_reset_stack_guards;
     ffsl;
     ffsll;
     pidfd_getfd;
@@ -1564,6 +1565,17 @@
     process_madvise;
 } LIBC_R;
 
+LIBC_T { # introduced=Tiramisu
+  global:
+    backtrace;
+    backtrace_symbols;
+    backtrace_symbols_fd;
+    preadv2;
+    preadv64v2;
+    pwritev2;
+    pwritev64v2;
+} LIBC_S;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86
@@ -1776,5 +1788,4 @@
     android_net_res_stats_get_info_for_net;
     android_net_res_stats_aggregate;
     android_net_res_stats_get_usable_servers;
-    android_reset_stack_guards;
 } LIBC_Q;
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 3b3a22e..7ff3db2 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -37,12 +37,6 @@
     },
     native_coverage: false,
 
-    target: {
-        android: {
-            static_libs: ["libc++demangle"],
-        },
-    },
-
     // -Wno-error=format-zero-length needed for gcc to compile.
     cflags: [
         "-Wall",
@@ -125,6 +119,7 @@
 // ==============================================================
 cc_test {
     name: "malloc_debug_unit_tests",
+    test_suites: ["device-tests"],
 
     srcs: [
         "tests/backtrace_fake.cpp",
@@ -171,6 +166,7 @@
 
     include_dirs: [
         "bionic/libc",
+        "bionic", // For SKIP_WITH_HWASAN.
     ],
 
     header_libs: [
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 90c9136..b982c0a 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -66,7 +66,8 @@
 std::unordered_map<FrameKeyType, size_t> PointerData::key_to_index_ GUARDED_BY(
     PointerData::frame_mutex_);
 std::unordered_map<size_t, FrameInfoType> PointerData::frames_ GUARDED_BY(PointerData::frame_mutex_);
-std::unordered_map<size_t, std::vector<unwindstack::LocalFrameData>> PointerData::backtraces_info_ GUARDED_BY(PointerData::frame_mutex_);
+std::unordered_map<size_t, std::vector<unwindstack::FrameData>> PointerData::backtraces_info_
+    GUARDED_BY(PointerData::frame_mutex_);
 constexpr size_t kBacktraceEmptyIndex = 1;
 size_t PointerData::cur_hash_index_ GUARDED_BY(PointerData::frame_mutex_);
 
@@ -136,7 +137,7 @@
 
 size_t PointerData::AddBacktrace(size_t num_frames) {
   std::vector<uintptr_t> frames;
-  std::vector<unwindstack::LocalFrameData> frames_info;
+  std::vector<unwindstack::FrameData> frames_info;
   if (g_debug->config().options() & BACKTRACE_FULL) {
     if (!Unwind(&frames, &frames_info, num_frames)) {
       return kBacktraceEmptyIndex;
@@ -386,7 +387,7 @@
     REQUIRES(pointer_mutex_, frame_mutex_) {
   for (const auto& entry : pointers_) {
     FrameInfoType* frame_info = nullptr;
-    std::vector<unwindstack::LocalFrameData>* backtrace_info = nullptr;
+    std::vector<unwindstack::FrameData>* backtrace_info = nullptr;
     size_t hash_index = entry.second.hash_index;
     if (hash_index > kBacktraceEmptyIndex) {
       auto frame_entry = frames_.find(hash_index);
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 37d87db..92d2653 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -39,7 +39,7 @@
 #include <vector>
 
 #include <platform/bionic/macros.h>
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 #include "OptionData.h"
 #include "UnwindBacktrace.h"
@@ -109,7 +109,7 @@
   size_t size;
   bool zygote_child_alloc;
   FrameInfoType* frame_info;
-  std::vector<unwindstack::LocalFrameData>* backtrace_info;
+  std::vector<unwindstack::FrameData>* backtrace_info;
 };
 
 class PointerData : public OptionData {
@@ -181,7 +181,7 @@
   static std::mutex frame_mutex_;
   static std::unordered_map<FrameKeyType, size_t> key_to_index_;
   static std::unordered_map<size_t, FrameInfoType> frames_;
-  static std::unordered_map<size_t, std::vector<unwindstack::LocalFrameData>> backtraces_info_;
+  static std::unordered_map<size_t, std::vector<unwindstack::FrameData>> backtraces_info_;
   static size_t cur_hash_index_;
 
   static std::mutex free_pointer_mutex_;
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index bebc1c1..662f5f8 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -573,9 +573,6 @@
 /system/libutils.so which starts at 0xb000. The relative pc is 0x510 and
 it is in an unknown function.
 
-There is a tool to visualize this data,
-[native\_heapdump\_viewer.py](https://android.googlesource.com/platform/development/+/master/scripts/native_heapdump_viewer.py).
-
 Examples
 ========
 
@@ -644,6 +641,13 @@
 for the best way to use malloc debug in Android O or later on non-rooted
 devices.
 
+**NOTE**: Android 12 introduced a bug that can cause the wrap.\<APP\> property to
+no longer work. Use the commands below so that the wrap.\<APP\> instructions will work:
+
+    adb shell setprop dalvik.vm.force-java-zygote-fork-loop true
+    adb shell stop
+    adb shell start
+
 If you do have a rooted device, you can enable malloc debug for a specific
 program/application (Android O or later):
 
@@ -692,24 +696,3 @@
 symbols in your app's shared libraries rather than stripping them. That
 way you'll see the location of the leak directly without having to use
 something like the <code>ndk-stack</code> tool.
-
-### Analyzing heap dumps
-
-To analyze the data produced by the dumpheap command, run
-[development/scripts/native\_heapdump\_viewer.py](https://android.googlesource.com/platform/development/+/master/scripts/native_heapdump_viewer.py)
-
-In order for the script to properly symbolize the stacks in the file,
-make sure the script is executed from the tree that built the image.
-
-To collect, transfer, and analyze a dump:
-
-    adb shell am dumpheap -n <PID_TO_DUMP> /data/local/tmp/heap.txt
-    adb shell pull /data/local/tmp/heap.txt .
-    python development/scripts/native_heapdump_viewer.py --symbols /some/path/to/symbols/ heap.txt > heap_info.txt
-
-At the moment, the script will look for symbols in the given directory,
-using the path the .so file would have on the device. So if your .so file
-is at `/data/app/.../lib/arm/libx.so` on the device, it will need to be at
-`/some/path/to/symbols/data/app/.../lib/arm/libx.so` locally given the
-command line above. That is: you need to mirror the directory structure
-for the app in the symbols directory.
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index 128991b..f6c3e69 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -36,8 +36,12 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
-#include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Memory.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/Unwinder.h>
 
 #include "UnwindBacktrace.h"
 #include "debug_log.h"
@@ -52,49 +56,65 @@
 
 static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT;
 
-static unwindstack::LocalUnwinder* g_unwinder;
-
-static void Setup() {
+static unwindstack::LocalUpdatableMaps* g_maps;
+static std::shared_ptr<unwindstack::Memory> g_process_memory;
 #if defined(__LP64__)
-  std::vector<std::string> skip_libraries{"/system/lib64/libunwindstack.so", "/system/lib64/libc_malloc_debug.so"};
+static std::vector<std::string> g_skip_libraries{"/system/lib64/libunwindstack.so",
+                                                 "/system/lib64/libc_malloc_debug.so"};
 #else
-  std::vector<std::string> skip_libraries{"/system/lib/libunwindstack.so", "/system/lib/libc_malloc_debug.so"};
+static std::vector<std::string> g_skip_libraries{"/system/lib/libunwindstack.so",
+                                                 "/system/lib/libc_malloc_debug.so"};
 #endif
 
-  g_unwinder = new unwindstack::LocalUnwinder(skip_libraries);
-  g_unwinder->Init();
+static void Setup() {
+  g_maps = new unwindstack::LocalUpdatableMaps;
+  if (!g_maps->Parse()) {
+    delete g_maps;
+    g_maps = nullptr;
+  }
+
+  g_process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
 }
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* frame_info, size_t max_frames) {
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* frame_info,
+            size_t max_frames) {
   pthread_once(&g_setup_once, Setup);
 
-  if (g_unwinder == nullptr) {
+  if (g_maps == nullptr) {
     return false;
   }
 
-  if (!g_unwinder->Unwind(frame_info, max_frames)) {
+  std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+  unwindstack::RegsGetLocal(regs.get());
+  unwindstack::Unwinder unwinder(max_frames, g_maps, regs.get(), g_process_memory);
+  unwinder.Unwind(&g_skip_libraries);
+  if (unwinder.NumFrames() == 0) {
     frames->clear();
     frame_info->clear();
     return false;
   }
+  *frame_info = unwinder.ConsumeFrames();
 
-  for (const auto& frame : *frame_info) {
-    frames->push_back(frame.pc);
+  frames->resize(frame_info->size());
+  for (size_t i = 0; i < frame_info->size(); i++) {
+    frames->at(i) = frame_info->at(i).pc;
   }
   return true;
 }
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info) {
+void UnwindLog(const std::vector<unwindstack::FrameData>& frame_info) {
   for (size_t i = 0; i < frame_info.size(); i++) {
-    const unwindstack::LocalFrameData* info = &frame_info[i];
-    unwindstack::MapInfo* map_info = info->map_info;
+    const unwindstack::FrameData* info = &frame_info[i];
+    auto map_info = info->map_info;
 
     std::string line = android::base::StringPrintf("          #%0zd  pc %" PAD_PTR "  ", i, info->rel_pc);
-    if (map_info->offset() != 0) {
+    if (map_info != nullptr && map_info->offset() != 0) {
       line += android::base::StringPrintf("(offset 0x%" PRIx64 ") ", map_info->offset());
     }
 
-    if (map_info->name().empty()) {
+    if (map_info == nullptr) {
+      line += "<unknown>";
+    } else if (map_info->name().empty()) {
       line += android::base::StringPrintf("<anonymous:%" PRIx64 ">", map_info->start());
     } else {
       line += map_info->name();
diff --git a/libc/malloc_debug/UnwindBacktrace.h b/libc/malloc_debug/UnwindBacktrace.h
index 4c6c8d4..7f89907 100644
--- a/libc/malloc_debug/UnwindBacktrace.h
+++ b/libc/malloc_debug/UnwindBacktrace.h
@@ -33,9 +33,10 @@
 #include <string>
 #include <vector>
 
-#include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Unwinder.h>
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* info, size_t max_frames);
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info,
+            size_t max_frames);
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info);
+void UnwindLog(const std::vector<unwindstack::FrameData>& frame_info);
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d23ab15..9f38946 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -49,6 +49,7 @@
 #include <platform/bionic/reserved_signals.h>
 #include <private/MallocXmlElem.h>
 #include <private/bionic_malloc_dispatch.h>
+#include <unwindstack/Unwinder.h>
 
 #include "Config.h"
 #include "DebugData.h"
@@ -193,7 +194,7 @@
 void BacktraceAndLog() {
   if (g_debug->config().options() & BACKTRACE_FULL) {
     std::vector<uintptr_t> frames;
-    std::vector<unwindstack::LocalFrameData> frames_info;
+    std::vector<unwindstack::FrameData> frames_info;
     if (!Unwind(&frames, &frames_info, 256)) {
       error_log("  Backtrace failed to get any frames.");
     } else {
diff --git a/libc/malloc_debug/tests/backtrace_fake.cpp b/libc/malloc_debug/tests/backtrace_fake.cpp
index ad16c02..f54bae8 100644
--- a/libc/malloc_debug/tests/backtrace_fake.cpp
+++ b/libc/malloc_debug/tests/backtrace_fake.cpp
@@ -20,7 +20,7 @@
 #include <vector>
 #include <utility>
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 #include "backtrace.h"
 #include "backtrace_fake.h"
@@ -60,17 +60,17 @@
   }
 }
 
-static std::deque<std::vector<unwindstack::LocalFrameData>> g_fake_local_frame_data;
+static std::deque<std::vector<unwindstack::FrameData>> g_fake_local_frame_data;
 
 void BacktraceUnwindFakeClearAll() {
   g_fake_local_frame_data.clear();
 }
 
-void BacktraceUnwindFake(const std::vector<unwindstack::LocalFrameData>& frames) {
+void BacktraceUnwindFake(const std::vector<unwindstack::FrameData>& frames) {
   g_fake_local_frame_data.push_back(frames);
 }
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* info, size_t) {
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info, size_t) {
   if (g_fake_local_frame_data.empty()) {
     return false;
   }
@@ -85,5 +85,4 @@
   return true;
 }
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& /*frame_info*/) {
-}
+void UnwindLog(const std::vector<unwindstack::FrameData>& /*frame_info*/) {}
diff --git a/libc/malloc_debug/tests/backtrace_fake.h b/libc/malloc_debug/tests/backtrace_fake.h
index a9ee97d..246fc61 100644
--- a/libc/malloc_debug/tests/backtrace_fake.h
+++ b/libc/malloc_debug/tests/backtrace_fake.h
@@ -21,12 +21,12 @@
 
 #include <vector>
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 void backtrace_fake_clear_all();
 void backtrace_fake_add(const std::vector<uintptr_t>& ips);
 
 void BacktraceUnwindFakeClearAll();
-void BacktraceUnwindFake(const std::vector<unwindstack::LocalFrameData>& frames);
+void BacktraceUnwindFake(const std::vector<unwindstack::FrameData>& frames);
 
 #endif // MALLOC_DEBUG_TESTS_BACKTRACE_FAKE_H
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index 68b3a1e..92679e4 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -29,6 +29,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <poll.h>
+#include <setjmp.h>
 #include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -40,10 +41,13 @@
 
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 #include <log/log_read.h>
 
 #include <atomic>
+#include <mutex>
+#include <random>
 #include <string>
 #include <thread>
 #include <vector>
@@ -52,13 +56,12 @@
 #include <backtrace/BacktraceMap.h>
 
 #include <bionic/malloc.h>
+#include <tests/utils.h>
 
 // All DISABLED_ tests are designed to be executed after malloc debug
 // is enabled. These tests don't run be default, and are executed
 // by wrappers that will enable various malloc debug features.
 
-static constexpr time_t kTimeoutSeconds = 10;
-
 extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
   static const char* initial_args[] = {"--slow_threshold_ms=30000",
                                        "--deadline_threshold_ms=1200000"};
@@ -67,171 +70,392 @@
   return true;
 }
 
-static void Exec(const char* test_name, const char* debug_options, pid_t* pid, int exit_code = 0,
-                 time_t timeout_seconds = kTimeoutSeconds) {
-  int fds[2];
-  ASSERT_NE(-1, pipe(fds));
-  ASSERT_NE(-1, fcntl(fds[0], F_SETFL, O_NONBLOCK));
-  if ((*pid = fork()) == 0) {
-    ASSERT_EQ(0, setenv("LIBC_DEBUG_MALLOC_OPTIONS", debug_options, 1));
-    close(fds[0]);
-    close(STDIN_FILENO);
-    close(STDOUT_FILENO);
-    close(STDERR_FILENO);
-    ASSERT_NE(0, dup2(fds[1], STDOUT_FILENO));
-    ASSERT_NE(0, dup2(fds[1], STDERR_FILENO));
-
-    std::vector<const char*> args;
-    // Get a copy of this argument so it doesn't disappear on us.
-    std::string exec(testing::internal::GetArgvs()[0]);
-    args.push_back(exec.c_str());
-    args.push_back("--gtest_also_run_disabled_tests");
-    std::string filter_arg = std::string("--gtest_filter=") + test_name;
-    args.push_back(filter_arg.c_str());
-    // Need this because some code depends on exit codes from the test run
-    // but the isolation runner does not support that.
-    args.push_back("--no_isolate");
-    args.push_back(nullptr);
-    execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
-    exit(20);
-  }
-  ASSERT_NE(-1, *pid);
-  close(fds[1]);
-
-  std::string output;
-  std::vector<char> buffer(4096);
-  time_t start_time = time(nullptr);
-  bool done = false;
-  while (true) {
-    struct pollfd read_fd = {.fd = fds[0], .events = POLLIN};
-    if (TEMP_FAILURE_RETRY(poll(&read_fd, 1, 1)) > 0) {
-      ssize_t bytes = TEMP_FAILURE_RETRY(read(fds[0], buffer.data(), sizeof(buffer) - 1));
-      if (bytes == -1 && errno == EAGAIN) {
-        continue;
+class LogReader {
+ public:
+  LogReader(pid_t pid, log_id log) {
+    std::call_once(log_start_time_flag_, []() {
+      // Use this to figure out the point at which to start grabbing the log.
+      // This avoids accidentally grabbing data from a previous process with
+      // the same pid.
+      log_start_time_ = {};
+      logger_list* list = android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, 1000, 0);
+      if (list == nullptr) {
+        return;
       }
-      ASSERT_NE(-1, bytes);
-      if (bytes == 0) {
+      log_msg log_msg;
+      int ret = android_logger_list_read(list, &log_msg);
+      android_logger_list_close(list);
+      if (ret <= 0) {
+        return;
+      }
+      log_start_time_.tv_sec = log_msg.entry.sec;
+      log_start_time_.tv_nsec = log_msg.entry.nsec;
+    });
+
+    std::call_once(jmp_data_key_flag_, []() {
+      pthread_key_create(&jmp_data_key_, [](void* ptr) { free(ptr); });
+      signal(SIGUSR1, [](int) {
+        jmp_buf* jb = reinterpret_cast<jmp_buf*>(pthread_getspecific(jmp_data_key_));
+        if (jb != nullptr) {
+          // The thread reading the log is in a blocking read call that
+          // cannot be interrupted. In order to get out of this read loop,
+          // it's necessary to call longjmp when a SIGUSR1 signal is sent
+          // to the thread.
+          longjmp(*jb, 1);
+        }
+      });
+    });
+
+    reader_.reset(new std::thread([this, pid, log] {
+      tid_.store(gettid(), std::memory_order_release);
+      logger_list* list;
+      while (true) {
+        // Do not use non-blocking mode so that the two threads
+        // are essentially asleep and not consuming any cpu.
+        list = android_logger_list_open(log, 0, 1000, pid);
+        if (list != nullptr) {
+          break;
+        }
+        // Wait for a short time for the log to become available.
+        usleep(1000);
+      }
+
+      jmp_buf* jb = reinterpret_cast<jmp_buf*>(malloc(sizeof(jmp_buf)));
+      if (jb == nullptr) {
+        printf("Failed to allocate memory for jmp_buf\n");
+        return;
+      }
+      pthread_setspecific(jmp_data_key_, jb);
+      if (setjmp(*jb) != 0) {
+        // SIGUSR1 signal hit, we need to terminate the thread.
+        android_logger_list_free(list);
+        return;
+      }
+
+      while (true) {
+        log_msg msg;
+        int actual = android_logger_list_read(list, &msg);
+        if (actual < 0) {
+          if (actual == -EINTR) {
+            // Interrupted retry.
+            continue;
+          }
+          // Unknown error.
+          break;
+        } else if (actual == 0) {
+          // Nothing left to read.
+          break;
+        }
+        // Do not allow SIGUSR1 while processing the log message.
+        // This avoids a deadlock if the thread is being terminated
+        // at this moment.
+        sigset64_t mask_set;
+        sigprocmask64(SIG_SETMASK, nullptr, &mask_set);
+        sigaddset64(&mask_set, SIGUSR1);
+        sigprocmask64(SIG_SETMASK, &mask_set, nullptr);
+
+        {
+          // Lock while appending to the data.
+          std::lock_guard<std::mutex> guard(data_lock_);
+          char* msg_str = msg.msg();
+          // Make sure the message is not empty and recent.
+          if (msg_str != nullptr && (msg.entry.sec > log_start_time_.tv_sec ||
+                                     (msg.entry.sec == log_start_time_.tv_sec &&
+                                      msg.entry.nsec > log_start_time_.tv_nsec))) {
+            // Skip the tag part of the message.
+            char* tag = msg_str + 1;
+            msg_str = tag + strlen(tag) + 1;
+            log_data_ += msg_str;
+            if (log_data_.back() != '\n') {
+              log_data_ += '\n';
+            }
+          }
+        }
+
+        // Re-enable SIGUSR1
+        sigprocmask64(SIG_SETMASK, nullptr, &mask_set);
+        sigdelset64(&mask_set, SIGUSR1);
+        sigprocmask64(SIG_SETMASK, &mask_set, nullptr);
+      }
+      android_logger_list_free(list);
+    }));
+  }
+
+  virtual ~LogReader() {
+    tgkill(getpid(), tid_.load(std::memory_order_acquire), SIGUSR1);
+    reader_->join();
+  }
+
+  std::string GetLog() {
+    std::lock_guard<std::mutex> guard(data_lock_);
+    return log_data_;
+  }
+
+ private:
+  std::unique_ptr<std::thread> reader_;
+  std::string log_data_;
+  std::mutex data_lock_;
+  std::atomic<pid_t> tid_;
+
+  static std::once_flag jmp_data_key_flag_;
+  static pthread_key_t jmp_data_key_;
+
+  static std::once_flag log_start_time_flag_;
+  static log_time log_start_time_;
+};
+
+std::once_flag LogReader::jmp_data_key_flag_;
+pthread_key_t LogReader::jmp_data_key_;
+
+std::once_flag LogReader::log_start_time_flag_;
+log_time LogReader::log_start_time_;
+
+class MallocDebugSystemTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    expected_log_strings_.clear();
+    unexpected_log_strings_.clear();
+
+    // All tests expect this message to be present.
+    expected_log_strings_.push_back("malloc debug enabled");
+  }
+
+  void Exec(const char* test_name, const char* debug_options, int expected_exit_code = 0) {
+    std::random_device rd;
+    std::mt19937 generator(rd());
+    std::uniform_int_distribution<> rand_usleep_time(1, 10);
+    std::srand(std::time(nullptr));
+
+    for (size_t i = 0; i < kMaxRetries; i++) {
+      ASSERT_NO_FATAL_FAILURE(InternalExec(test_name, debug_options, expected_exit_code));
+
+      // Due to log messages sometimes getting lost, if a log message
+      // is not present, allow retrying the test.
+      std::string error_msg;
+      bool found_expected = CheckExpectedLogStrings(&error_msg);
+      if (!found_expected) {
+        ASSERT_NE(i, kMaxRetries - 1) << error_msg;
+        // Sleep a random amount of time to attempt to avoid tests syncing
+        // up and sending the log messages at the same time.
+        usleep(1000 * rand_usleep_time(generator));
+      }
+
+      // This doesn't need to be retried since if the log message is
+      // present, that is an immediate fail.
+      ASSERT_NO_FATAL_FAILURE(VerifyUnexpectedLogStrings());
+      if (found_expected) {
+        break;
+      }
+    }
+  }
+
+  void InternalExec(const char* test_name, const char* debug_options, int expected_exit_code) {
+    int fds[2];
+    ASSERT_NE(-1, pipe(fds));
+    ASSERT_NE(-1, fcntl(fds[0], F_SETFL, O_NONBLOCK));
+    if ((pid_ = fork()) == 0) {
+      ASSERT_EQ(0, setenv("LIBC_DEBUG_MALLOC_OPTIONS", debug_options, 1));
+      close(fds[0]);
+      close(STDIN_FILENO);
+      close(STDOUT_FILENO);
+      close(STDERR_FILENO);
+      ASSERT_NE(0, dup2(fds[1], STDOUT_FILENO));
+      ASSERT_NE(0, dup2(fds[1], STDERR_FILENO));
+
+      std::vector<const char*> args;
+      // Get a copy of this argument so it doesn't disappear on us.
+      std::string exec(testing::internal::GetArgvs()[0]);
+      args.push_back(exec.c_str());
+      args.push_back("--gtest_also_run_disabled_tests");
+      std::string filter_arg = std::string("--gtest_filter=") + test_name;
+      args.push_back(filter_arg.c_str());
+      // Need this because some code depends on exit codes from the test run
+      // but the isolation runner does not support that.
+      args.push_back("--no_isolate");
+      args.push_back(nullptr);
+      execv(args[0], reinterpret_cast<char* const*>(const_cast<char**>(args.data())));
+      exit(20);
+    }
+    ASSERT_NE(-1, pid_);
+    close(fds[1]);
+
+    // Create threads to read the log output from the forked process as
+    // soon as possible in case there is something flooding the log.
+    log_main_.reset(new LogReader(pid_, LOG_ID_MAIN));
+    log_crash_.reset(new LogReader(pid_, LOG_ID_CRASH));
+
+    output_.clear();
+    std::vector<char> buffer(4096);
+    time_t start_time = time(nullptr);
+    bool read_done = false;
+    while (true) {
+      struct pollfd read_fd = {.fd = fds[0], .events = POLLIN};
+      if (TEMP_FAILURE_RETRY(poll(&read_fd, 1, 1)) > 0) {
+        ssize_t bytes = TEMP_FAILURE_RETRY(read(fds[0], buffer.data(), sizeof(buffer) - 1));
+        if (bytes == -1 && errno == EAGAIN) {
+          continue;
+        }
+        ASSERT_NE(-1, bytes);
+        if (bytes == 0) {
+          read_done = true;
+          break;
+        }
+        output_.append(buffer.data(), bytes);
+      }
+
+      if ((time(nullptr) - start_time) > kReadOutputTimeoutSeconds) {
+        kill(pid_, SIGINT);
+        break;
+      }
+    }
+
+    bool done = false;
+    int status;
+    start_time = time(nullptr);
+    while (true) {
+      int wait_pid = waitpid(pid_, &status, WNOHANG);
+      if (pid_ == wait_pid) {
         done = true;
         break;
       }
-      output.append(buffer.data(), bytes);
+      if ((time(nullptr) - start_time) > kWaitpidTimeoutSeconds) {
+        break;
+      }
+    }
+    if (!done) {
+      kill(pid_, SIGKILL);
+      start_time = time(nullptr);
+      while (true) {
+        int kill_status;
+        int wait_pid = waitpid(pid_, &kill_status, WNOHANG);
+        if (wait_pid == pid_ || (time(nullptr) - start_time) > kWaitpidTimeoutSeconds) {
+          break;
+        }
+      }
     }
 
-    if ((time(nullptr) - start_time) > timeout_seconds) {
-      kill(*pid, SIGINT);
-      break;
-    }
-  }
-  EXPECT_TRUE(done) << "Timed out while reading data, output:\n" << output;
+    // Check timeout conditions first.
+    ASSERT_TRUE(read_done) << "Timed out while reading data, output:\n" << output_;
+    ASSERT_TRUE(done) << "Timed out waiting for waitpid, output:\n" << output_;
 
-  done = false;
-  int status;
-  start_time = time(nullptr);
-  while (true) {
-    int wait_pid = waitpid(*pid, &status, WNOHANG);
-    if (*pid == wait_pid) {
-      done = true;
-      break;
-    }
-    if ((time(nullptr) - start_time) > timeout_seconds) {
-      break;
-    }
+    ASSERT_FALSE(WIFSIGNALED(status)) << "Failed with signal " << WTERMSIG(status) << "\nOutput:\n"
+                                      << output_;
+    ASSERT_EQ(expected_exit_code, WEXITSTATUS(status)) << "Output:\n" << output_;
   }
-  if (!done) {
-    kill(*pid, SIGKILL);
-    start_time = time(nullptr);
+
+  bool CheckExpectedLogStrings(std::string* error_msg) {
+    time_t start = time(nullptr);
+    std::string missing_match;
+    std::string log_str;
     while (true) {
-      int kill_status;
-      int wait_pid = waitpid(*pid, &kill_status, WNOHANG);
-      if (wait_pid == *pid || (time(nullptr) - start_time) > timeout_seconds) {
+      log_str = log_main_->GetLog();
+      missing_match.clear();
+      // Look for the expected strings.
+      for (auto str : expected_log_strings_) {
+        if (log_str.find(str) == std::string::npos) {
+          missing_match = str;
+          break;
+        }
+      }
+      if (missing_match.empty()) {
+        return true;
+      }
+      if ((time(nullptr) - start) > kLogTimeoutSeconds) {
         break;
       }
     }
+
+    *error_msg = android::base::StringPrintf("Didn't find string '%s' in log output:\n%s",
+                                             missing_match.c_str(), log_str.c_str());
+    return false;
+  }
+
+  void VerifyUnexpectedLogStrings() {
+    std::string log_str = log_main_->GetLog();
+    for (auto str : unexpected_log_strings_) {
+      ASSERT_TRUE(log_str.find(str) == std::string::npos)
+          << "Unexpectedly found string '" << str << "' in log output:\n"
+          << log_str;
+    }
   }
 
-  ASSERT_TRUE(done) << "Timed out waiting for waitpid, output:\n" << output;
-  ASSERT_FALSE(WIFSIGNALED(status))
-      << "Failed with signal " << WTERMSIG(status) << "\nOutput:\n" << output;
-  ASSERT_EQ(exit_code, WEXITSTATUS(status)) << "Output:\n" << output;
-}
-
-static void GetLogStr(pid_t pid, std::string* log_str, log_id log = LOG_ID_MAIN) {
-  log_str->clear();
-
-  logger_list* list;
-  list = android_logger_list_open(log, ANDROID_LOG_NONBLOCK, 1000, pid);
-  ASSERT_TRUE(list != nullptr);
-
-  while (true) {
-    log_msg msg;
-    ssize_t actual = android_logger_list_read(list, &msg);
-    if (actual < 0) {
-      if (actual == -EINTR) {
-        // Interrupted retry.
-        continue;
-      } else if (actual == -EAGAIN) {
-        // Non-blocking EOF, finished.
-        break;
-      } else {
-        break;
+  void VerifyLeak(const char* test_prefix) {
+    struct FunctionInfo {
+      const char* name;
+      size_t size;
+    };
+    static FunctionInfo functions[] = {
+      {
+          "aligned_alloc",
+          1152,
+      },
+      {
+          "calloc",
+          1123,
+      },
+      {
+          "malloc",
+          1123,
+      },
+      {
+          "memalign",
+          1123,
+      },
+      {
+          "posix_memalign",
+          1123,
+      },
+      {
+          "reallocarray",
+          1123,
+      },
+      {
+          "realloc",
+          1123,
+      },
+#if !defined(__LP64__)
+      {
+          "pvalloc",
+          4096,
+      },
+      {
+          "valloc",
+          1123,
       }
-    } else if (actual == 0) {
-      break;
-    }
-    ASSERT_EQ(msg.entry.pid, pid);
+#endif
+    };
 
-    char* msg_str = msg.msg();
-    if (msg_str != nullptr) {
-      char* tag = msg_str + 1;
-      msg_str = tag + strlen(tag) + 1;
-      *log_str += msg_str;
-      if (log_str->back() != '\n') {
-        *log_str += '\n';
-      }
+    size_t match_len = expected_log_strings_.size() + 1;
+    expected_log_strings_.resize(match_len);
+    for (size_t i = 0; i < sizeof(functions) / sizeof(FunctionInfo); i++) {
+      SCOPED_TRACE(testing::Message()
+                   << functions[i].name << " expected size " << functions[i].size);
+
+      expected_log_strings_[match_len - 1] =
+          android::base::StringPrintf("leaked block of size %zu at", functions[i].size);
+
+      std::string test = std::string("MallocTests.DISABLED_") + test_prefix + functions[i].name;
+      ASSERT_NO_FATAL_FAILURE(Exec(test.c_str(), "verbose backtrace leak_track"));
     }
   }
 
-  android_logger_list_close(list);
-}
+  std::unique_ptr<LogReader> log_main_;
+  std::unique_ptr<LogReader> log_crash_;
+  pid_t pid_;
+  std::string output_;
+  std::vector<std::string> expected_log_strings_;
+  std::vector<std::string> unexpected_log_strings_;
 
-static void FindStrings(pid_t pid, std::vector<const char*> match_strings,
-                        std::vector<const char*> no_match_strings = std::vector<const char*>{},
-                        time_t timeout_seconds = kTimeoutSeconds) {
-  std::string log_str;
-  time_t start = time(nullptr);
-  std::string missing_match;
-  while (true) {
-    GetLogStr(pid, &log_str);
-    missing_match.clear();
-    // Look for the expected strings.
-    for (auto str : match_strings) {
-      if (log_str.find(str) == std::string::npos) {
-        missing_match = str;
-        break;
-      }
-    }
-
-    // Verify the unexpected strings are not present.
-    for (auto str : no_match_strings) {
-      ASSERT_TRUE(log_str.find(str) == std::string::npos) << "Unexpectedly found '" << str << "' in log output:\n" << log_str;
-    }
-    if (missing_match.empty()) {
-      return;
-    }
-    if ((time(nullptr) - start) > timeout_seconds) {
-      break;
-    }
-  }
-  ASSERT_EQ("", missing_match) << "Didn't find expected log output:\n" << log_str;
-}
+  static constexpr size_t kReadOutputTimeoutSeconds = 180;
+  static constexpr size_t kWaitpidTimeoutSeconds = 10;
+  static constexpr size_t kLogTimeoutSeconds = 5;
+  static constexpr size_t kMaxRetries = 3;
+};
 
 TEST(MallocTests, DISABLED_smoke) {}
 
-TEST(MallocDebugSystemTest, smoke) {
-  pid_t pid;
-  ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_smoke", "verbose backtrace", &pid));
-
-  ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"}));
+TEST_F(MallocDebugSystemTest, smoke) {
+  Exec("MallocTests.DISABLED_smoke", "verbose backtrace");
 }
 
 static void SetAllocationLimit() {
@@ -383,69 +607,12 @@
 }
 #endif
 
-static void VerifyLeak(const char* test_prefix) {
-  struct FunctionInfo {
-    const char* name;
-    size_t size;
-  };
-  static FunctionInfo functions[] = {
-    {
-      "aligned_alloc",
-      1152,
-    },
-    {
-      "calloc",
-      1123,
-    },
-    {
-      "malloc",
-      1123,
-    },
-    {
-      "memalign",
-      1123,
-    },
-    {
-      "posix_memalign",
-      1123,
-    },
-    {
-      "reallocarray",
-      1123,
-    },
-    {
-      "realloc",
-      1123,
-    },
-#if !defined(__LP64__)
-    {
-      "pvalloc",
-      4096,
-    },
-    {
-      "valloc",
-      1123,
-    }
-#endif
-  };
-
-  for (size_t i = 0; i < sizeof(functions) / sizeof(FunctionInfo); i++) {
-    pid_t pid;
-    SCOPED_TRACE(testing::Message() << functions[i].name << " expected size " << functions[i].size);
-    std::string test = std::string("MallocTests.DISABLED_") + test_prefix + functions[i].name;
-    ASSERT_NO_FATAL_FAILURE(Exec(test.c_str(), "verbose backtrace leak_track", &pid));
-
-    std::string expected_leak = android::base::StringPrintf("leaked block of size %zu at", functions[i].size);
-    EXPECT_NO_FATAL_FAILURE(FindStrings(
-        pid, std::vector<const char*>{"malloc debug enabled", expected_leak.c_str()}));
-  }
-}
-
-TEST(MallocDebugSystemTest, verify_leak) {
+TEST_F(MallocDebugSystemTest, verify_leak) {
   VerifyLeak("leak_memory_");
 }
 
-TEST(MallocDebugSystemTest, verify_leak_allocation_limit) {
+TEST_F(MallocDebugSystemTest, verify_leak_allocation_limit) {
+  SKIP_WITH_HWASAN;
   VerifyLeak("leak_memory_limit_");
 }
 
@@ -463,7 +630,7 @@
           exit(1000);
         }
         free(ptr);
-        thread_mask.fetch_or(1 << i);
+        thread_mask.fetch_or(1U << i);
       }
     });
     malloc_thread.detach();
@@ -477,19 +644,15 @@
 
 // Verify that exiting while other threads are doing malloc operations,
 // that there are no crashes.
-TEST(MallocDebugSystemTest, exit_while_threads_allocating) {
+TEST_F(MallocDebugSystemTest, exit_while_threads_allocating) {
   for (size_t i = 0; i < 100; i++) {
     SCOPED_TRACE(::testing::Message() << "Run " << i);
-    pid_t pid;
     ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_exit_while_threads_allocating",
-                                 "verbose backtrace", &pid, kExpectedExitCode));
+                                 "verbose backtrace", kExpectedExitCode));
 
-    ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"}));
-
-    std::string log_str;
-    GetLogStr(pid, &log_str, LOG_ID_CRASH);
+    std::string log_str = log_crash_->GetLog();
     ASSERT_TRUE(log_str.find("Fatal signal") == std::string::npos)
-        << "Found crash in log.\nLog message: " << log_str;
+        << "Found crash in log.\nLog message: " << log_str << " pid: " << pid_;
   }
 }
 
@@ -511,7 +674,7 @@
 
   for (size_t i = 0; i < kMaxThreads; i++) {
     std::thread malloc_thread([&thread_mask, &run, &allocs, i] {
-      thread_mask.fetch_or(1 << i);
+      thread_mask.fetch_or(1U << i);
       while (!run)
         ;
       for (auto ptr : allocs[i]) {
@@ -528,21 +691,17 @@
   exit(kExpectedExitCode);
 }
 
-TEST(MallocDebugSystemTest, exit_while_threads_freeing_allocs_with_header) {
+TEST_F(MallocDebugSystemTest, exit_while_threads_freeing_allocs_with_header) {
   for (size_t i = 0; i < 50; i++) {
     SCOPED_TRACE(::testing::Message() << "Run " << i);
-    pid_t pid;
     // Enable guard to force the use of a header.
     ASSERT_NO_FATAL_FAILURE(
         Exec("MallocTests.DISABLED_exit_while_threads_freeing_allocs_with_header", "verbose guard",
-             &pid, kExpectedExitCode));
+             kExpectedExitCode));
 
-    ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"}));
-
-    std::string log_str;
-    GetLogStr(pid, &log_str, LOG_ID_CRASH);
+    std::string log_str = log_crash_->GetLog();
     ASSERT_TRUE(log_str.find("Fatal signal") == std::string::npos)
-        << "Found crash in log.\nLog message: " << log_str;
+        << "Found crash in log.\nLog message: " << log_str << " pid: " << pid_;
   }
 }
 
@@ -571,21 +730,18 @@
   free(ptr);
 }
 
-TEST(MallocDebugSystemTest, write_leak_info_no_header) {
-  pid_t pid;
-  ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_write_leak_info", "verbose backtrace", &pid, 0));
-
-  ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"},
-
-                          std::vector<const char*>{" HAS INVALID TAG ", "USED AFTER FREE ", "UNKNOWN POINTER "}));
+TEST_F(MallocDebugSystemTest, write_leak_info_no_header) {
+  unexpected_log_strings_.push_back(" HAS INVALID TAG ");
+  unexpected_log_strings_.push_back("USED AFTER FREE ");
+  unexpected_log_strings_.push_back("UNKNOWN POINTER ");
+  Exec("MallocTests.DISABLED_write_leak_info", "verbose backtrace");
 }
 
-TEST(MallocDebugSystemTest, write_leak_info_header) {
-  pid_t pid;
-  ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_write_leak_info", "verbose backtrace guard", &pid, 0));
-
-  ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"},
-                          std::vector<const char*>{" HAS INVALID TAG ", "USED AFTER FREE ", "UNKNOWN POINTER "}));
+TEST_F(MallocDebugSystemTest, write_leak_info_header) {
+  unexpected_log_strings_.push_back(" HAS INVALID TAG ");
+  unexpected_log_strings_.push_back("USED AFTER FREE ");
+  unexpected_log_strings_.push_back("UNKNOWN POINTER ");
+  Exec("MallocTests.DISABLED_write_leak_info", "verbose backtrace guard");
 }
 
 TEST(MallocTests, DISABLED_malloc_and_backtrace_deadlock) {
@@ -619,13 +775,9 @@
   thread.join();
 }
 
-TEST(MallocDebugSystemTest, malloc_and_backtrace_deadlock) {
-  pid_t pid;
-  ASSERT_NO_FATAL_FAILURE(Exec("MallocTests.DISABLED_malloc_and_backtrace_deadlock",
-                               "verbose verify_pointers", &pid, 0, 180));
-
+TEST_F(MallocDebugSystemTest, malloc_and_backtrace_deadlock) {
   // Make sure that malloc debug is enabled and that no timeouts occur during
   // unwinds.
-  ASSERT_NO_FATAL_FAILURE(FindStrings(pid, std::vector<const char*>{"malloc debug enabled"},
-                                      std::vector<const char*>{"Timed out waiting for "}));
+  unexpected_log_strings_.push_back("Timed out waiting for ");
+  Exec("MallocTests.DISABLED_malloc_and_backtrace_deadlock", "verbose verify_pointers", 0);
 }
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 1298df7..ea2dc78 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -40,10 +40,13 @@
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android-base/test_utils.h>
 
 #include <platform/bionic/macros.h>
 #include <private/bionic_malloc_dispatch.h>
 
+#include <unwindstack/Unwinder.h>
+
 #include "Config.h"
 #include "malloc_debug.h"
 
@@ -1528,19 +1531,20 @@
 TEST_F(MallocDebugTest, backtrace_full_dump_on_exit) {
   pid_t pid;
   if ((pid = fork()) == 0) {
+    std::shared_ptr<unwindstack::MapInfo> empty_map;
     Init("backtrace=4 backtrace_full backtrace_dump_on_exit");
     BacktraceUnwindFake(
-      std::vector<unwindstack::LocalFrameData>{{nullptr, 0x1100, 0x100, "fake1", 10},
-                                               {nullptr, 0x1200, 0x200, "fake2", 20}});
-    unwindstack::MapInfo map_info{nullptr, nullptr, 0x10000, 0x20000, 0,
-                                  PROT_READ | PROT_EXEC, "/data/fake.so"};
+        std::vector<unwindstack::FrameData>{{0, 0x100, 0x1100, 0, "fake1", 10, empty_map},
+                                            {1, 0x200, 0x1200, 0, "fake2", 20, empty_map}});
+    std::shared_ptr<unwindstack::MapInfo> map_info =
+        unwindstack::MapInfo::Create(0x10000, 0x20000, 0, PROT_READ | PROT_EXEC, "/data/fake.so");
     BacktraceUnwindFake(
-      std::vector<unwindstack::LocalFrameData>{{&map_info, 0x1a000, 0xa000, "level1", 0},
-                                               {&map_info, 0x1b000, 0xb000, "level2", 10}});
+        std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "level1", 0, map_info},
+                                            {1, 0xb000, 0x1b000, 0, "level2", 10, map_info}});
     BacktraceUnwindFake(
-      std::vector<unwindstack::LocalFrameData>{{nullptr, 0x1a000, 0xa000, "func1", 0},
-                                               {nullptr, 0x1b000, 0xb000, "func2", 10},
-                                               {nullptr, 0x1c000, 0xc000, "", 30}});
+        std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "func1", 0, empty_map},
+                                            {1, 0xb000, 0x1b000, 0, "func2", 10, empty_map},
+                                            {2, 0xc000, 0x1c000, 0, "", 30, empty_map}});
 
     std::vector<void*> pointers;
     pointers.push_back(debug_malloc(300));
@@ -2060,6 +2064,7 @@
 }
 
 TEST_F(MallocDebugTest, debug_mallinfo) {
+  SKIP_WITH_HWASAN;
   Init("guard");
 
   void* pointer = debug_malloc(150);
@@ -2472,6 +2477,7 @@
 }
 
 TEST_F(MallocDebugTest, malloc_info_no_pointer_tracking) {
+  SKIP_WITH_HWASAN;
   Init("fill");
 
   TemporaryFile tf;
diff --git a/libc/malloc_hooks/tests/malloc_hooks_tests.cpp b/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
index 1858781..3ff2537 100644
--- a/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
+++ b/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
@@ -38,6 +38,7 @@
 
 #include <gtest/gtest.h>
 
+#include <android-base/test_utils.h>
 #include <bionic/malloc.h>
 #include <private/bionic_malloc_dispatch.h>
 #include <tests/utils.h>
@@ -178,6 +179,7 @@
 }
 
 TEST_F(MallocHooksTest, other_malloc_functions) {
+  SKIP_WITH_HWASAN; // HWASan does not implement mallinfo.
   RunTest("*.DISABLED_other_malloc_functions");
 }
 
@@ -350,6 +352,9 @@
   RunTest("*.DISABLED_aligned_alloc_hook_error");
 }
 
+// Allow deliberate call with non-power-of-two alignment in test code.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnon-power-of-two-alignment"
 TEST_F(MallocHooksTest, DISABLED_aligned_alloc_hook_error) {
   Init();
   ASSERT_TRUE(__memalign_hook != nullptr);
@@ -365,6 +370,7 @@
   EXPECT_FALSE(void_arg_ != nullptr)
       << "The memalign hook was called with a nullptr with an error.";
 }
+#pragma clang diagnostic pop
 
 #if !defined(__LP64__)
 TEST_F(MallocHooksTest, pvalloc_hook) {
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index b56ca74..f0f13d0 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -96,12 +96,42 @@
   // otherwise this mallopt() will internally decide whether to sample the
   // process. The program must be single threaded at the point when the
   // android_mallopt function is called.
-  //   arg = bool*
-  //   arg_size = sizeof(bool)
+  //   arg = android_mallopt_gwp_asan_options_t*
+  //   arg_size = sizeof(android_mallopt_gwp_asan_options_t)
   M_INITIALIZE_GWP_ASAN = 10,
 #define M_INITIALIZE_GWP_ASAN M_INITIALIZE_GWP_ASAN
 };
 
+typedef struct {
+  // The null-terminated name that the zygote is spawning. Because native
+  // SpecializeCommon (where the GWP-ASan mallopt() is called from) happens
+  // before argv[0] is set, we need the zygote to tell us the new app name.
+  const char* program_name = nullptr;
+
+  // An android_mallopt(M_INITIALIZE_GWP_ASAN) is always issued on process
+  // startup and app startup, regardless of whether GWP-ASan is desired or not.
+  // This allows the process/app's desire to be overwritten by the
+  // "libc.debug.gwp_asan.*.app_default" or "libc.debug.gwp_asan.*.<name>"
+  // system properties, as well as the "GWP_ASAN_*" environment variables.
+  //
+  // Worth noting, the "libc.debug.gwp_asan.*.app_default" sysprops *do not*
+  // apply to system apps. They use the "libc.debug.gwp_asan.*.system_default"
+  // sysprops.
+  enum Action {
+    // The app has opted-in to GWP-ASan, and should always have it enabled. This
+    // should only be used by apps.
+    TURN_ON_FOR_APP,
+    // System processes apps have GWP-ASan enabled by default, but use the
+    // process sampling method.
+    TURN_ON_WITH_SAMPLING,
+    // Non-system apps don't have GWP-ASan by default.
+    DONT_TURN_ON_UNLESS_OVERRIDDEN,
+    // Note: GWP-ASan cannot be disabled once it's been enabled.
+  };
+
+  Action desire = DONT_TURN_ON_UNLESS_OVERRIDDEN;
+} android_mallopt_gwp_asan_options_t;
+
 // Manipulates bionic-specific handling of memory allocation APIs such as
 // malloc. Only for use by the Android platform itself.
 //
diff --git a/libc/private/bionic_asm_arm64.h b/libc/private/bionic_asm_arm64.h
index ee51a8e..5d83d9b 100644
--- a/libc/private/bionic_asm_arm64.h
+++ b/libc/private/bionic_asm_arm64.h
@@ -72,7 +72,7 @@
     .popsection;
 
 #define NT_MEMTAG_LEVEL_MASK 3
-#define NT_MEMTAG_LEVEL_DEFAULT 0
+#define NT_MEMTAG_LEVEL_NONE 0
 #define NT_MEMTAG_LEVEL_ASYNC 1
 #define NT_MEMTAG_LEVEL_SYNC 2
 #define NT_MEMTAG_HEAP 4
diff --git a/libc/private/bionic_asm_note.h b/libc/private/bionic_asm_note.h
index 80b8f01..d8559ff 100644
--- a/libc/private/bionic_asm_note.h
+++ b/libc/private/bionic_asm_note.h
@@ -28,6 +28,6 @@
 
 #pragma once
 
-#define NT_TYPE_IDENT 1
-#define NT_TYPE_KUSER 3
-#define NT_TYPE_MEMTAG 4
+#define NT_ANDROID_TYPE_IDENT 1
+#define NT_ANDROID_TYPE_KUSER 3
+#define NT_ANDROID_TYPE_MEMTAG 4
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 352115a..243b220 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -44,6 +44,10 @@
 #define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
                          rv == __MB_ERR_INCOMPLETE_SEQUENCE)
 
+static inline __wur bool mbstate_is_initial(const mbstate_t* ps) {
+  return *(reinterpret_cast<const uint32_t*>(ps->__seq)) == 0;
+}
+
 static inline __wur size_t mbstate_bytes_so_far(const mbstate_t* ps) {
   return
       (ps->__seq[2] != 0) ? 3 :
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 80d645a..53fe3d5 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -129,7 +129,8 @@
   passwd_state_t passwd;
 
   char fdtrack_disabled;
-  char padding[3];
+  char bionic_systrace_disabled;
+  char padding[2];
 
   // Initialize the main thread's final object using its bootstrap object.
   void copy_from_bootstrap(const bionic_tls* boot __attribute__((unused))) {
diff --git a/libc/private/bsd_sys_param.h b/libc/private/bsd_sys_param.h
index 8c936c4..be5f692 100644
--- a/libc/private/bsd_sys_param.h
+++ b/libc/private/bsd_sys_param.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <inttypes.h>
+
 /* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */
 #define ALIGNBYTES (sizeof(uintptr_t) - 1)
 #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index c429ff2..08df2eb 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -1219,7 +1219,7 @@
     if (dup2(fds[child], desired_child_fd) == -1) _exit(127);
     close(fds[child]);
     if (bidirectional) dup2(STDOUT_FILENO, STDIN_FILENO);
-    execl(__bionic_get_shell_path(), "sh", "-c", cmd, nullptr);
+    execl(__bionic_get_shell_path(), "sh", "-c", "--", cmd, nullptr);
     _exit(127);
   }
 
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
index f71d70a..7ba835a 100644
--- a/libc/system_properties/contexts_split.cpp
+++ b/libc/system_properties/contexts_split.cpp
@@ -274,9 +274,6 @@
     // still need the system / platform properties to function.
     if (access("/vendor/etc/selinux/vendor_property_contexts", R_OK) != -1) {
       InitializePropertiesFromFile("/vendor/etc/selinux/vendor_property_contexts");
-    } else {
-      // Fallback to nonplat_* if vendor_* doesn't exist.
-      InitializePropertiesFromFile("/vendor/etc/selinux/nonplat_property_contexts");
     }
   } else {
     if (!InitializePropertiesFromFile("/plat_property_contexts")) {
@@ -284,9 +281,6 @@
     }
     if (access("/vendor_property_contexts", R_OK) != -1) {
       InitializePropertiesFromFile("/vendor_property_contexts");
-    } else {
-      // Fallback to nonplat_* if vendor_* doesn't exist.
-      InitializePropertiesFromFile("/nonplat_property_contexts");
     }
   }
 
diff --git a/libc/tzcode/strftime.c b/libc/tzcode/strftime.c
index c05f6b5..7c4be49 100644
--- a/libc/tzcode/strftime.c
+++ b/libc/tzcode/strftime.c
@@ -252,8 +252,8 @@
                                 pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
                 continue;
             case 'd':
-                                pt = _conv(t->tm_mday, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_mday, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'E':
             case 'O':
                 /*
@@ -274,22 +274,21 @@
                 modifier = *format;
                 goto label;
             case 'e':
-                pt = _conv(t->tm_mday, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_mday, getformat(modifier, " 2", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'F':
                 pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
                 continue;
             case 'H':
-                pt = _conv(t->tm_hour, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_hour, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'I':
-                pt = _conv((t->tm_hour % 12) ?
-                    (t->tm_hour % 12) : 12,
-                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12,
+                         getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'j':
-                pt = _conv(t->tm_yday + 1, getformat(modifier, "%03d", "%3d", "%d", "%03d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_yday + 1, getformat(modifier, "03", " 3", "  ", "03"), pt, ptlim);
+              continue;
             case 'k':
                 /*
                 ** This used to be...
@@ -301,7 +300,7 @@
                 ** "%l" have been swapped.
                 ** (ado, 1993-05-24)
                 */
-                pt = _conv(t->tm_hour, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
+                pt = _conv(t->tm_hour, getformat(modifier, " 2", " 2", "  ", "02"), pt, ptlim);
                 continue;
 #ifdef KITCHEN_SINK
             case 'K':
@@ -321,16 +320,15 @@
                 ** "%l" have been swapped.
                 ** (ado, 1993-05-24)
                 */
-                pt = _conv((t->tm_hour % 12) ?
-                    (t->tm_hour % 12) : 12,
-                    getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
+                pt = _conv((t->tm_hour % 12) ? (t->tm_hour % 12) : 12,
+                           getformat(modifier, " 2", " 2", "  ", "02"), pt, ptlim);
                 continue;
             case 'M':
-                pt = _conv(t->tm_min, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_min, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'm':
-                pt = _conv(t->tm_mon + 1, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_mon + 1, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'n':
                 pt = _add("\n", pt, ptlim, modifier);
                 continue;
@@ -348,13 +346,12 @@
                 pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
                 continue;
             case 'S':
-                pt = _conv(t->tm_sec, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(t->tm_sec, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 's':
                 {
                     struct tm   tm;
-                    char        buf[INT_STRLEN_MAXIMUM(
-                                time64_t) + 1];
+                    char buf[INT_STRLEN_MAXIMUM(time64_t) + 1] __attribute__((__uninitialized__));
                     time64_t    mkt;
 
                     tm = *t;
@@ -374,10 +371,9 @@
                 pt = _add("\t", pt, ptlim, modifier);
                 continue;
             case 'U':
-                pt = _conv((t->tm_yday + DAYSPERWEEK -
-                    t->tm_wday) / DAYSPERWEEK,
-                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv((t->tm_yday + DAYSPERWEEK - t->tm_wday) / DAYSPERWEEK,
+                         getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'u':
                 /*
                 ** From Arnold Robbins' strftime version 3.0:
@@ -385,9 +381,7 @@
                 ** [1 (Monday) - 7]"
                 ** (ado, 1993-05-24)
                 */
-                pt = _conv((t->tm_wday == 0) ?
-                    DAYSPERWEEK : t->tm_wday,
-                    "%d", pt, ptlim);
+                pt = _conv((t->tm_wday == 0) ? DAYSPERWEEK : t->tm_wday, "  ", pt, ptlim);
                 continue;
             case 'V':   /* ISO 8601 week number */
             case 'G':   /* ISO 8601 year (four digits) */
@@ -467,8 +461,7 @@
                             w = 53;
 #endif /* defined XPG4_1994_04_09 */
                     if (*format == 'V')
-                        pt = _conv(w, getformat(modifier, "%02d", "%2d", "%d", "%02d"),
-                               pt, ptlim);
+                      pt = _conv(w, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
                     else if (*format == 'g') {
                         *warnp = IN_ALL;
                         pt = _yconv(year, base,
@@ -488,15 +481,14 @@
                 pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
                 continue;
             case 'W':
-                pt = _conv((t->tm_yday + DAYSPERWEEK -
-                    (t->tm_wday ?
-                    (t->tm_wday - 1) :
-                    (DAYSPERWEEK - 1))) / DAYSPERWEEK,
-                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
-                continue;
+              pt = _conv(
+                  (t->tm_yday + DAYSPERWEEK - (t->tm_wday ? (t->tm_wday - 1) : (DAYSPERWEEK - 1))) /
+                      DAYSPERWEEK,
+                  getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
+              continue;
             case 'w':
-                pt = _conv(t->tm_wday, "%d", pt, ptlim);
-                continue;
+              pt = _conv(t->tm_wday, "  ", pt, ptlim);
+              continue;
             case 'X':
                 pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
                 continue;
@@ -602,7 +594,7 @@
                 diff /= SECSPERMIN;
                 diff = (diff / MINSPERHOUR) * 100 +
                     (diff % MINSPERHOUR);
-                pt = _conv(diff, getformat(modifier, "%04d", "%4d", "%d", "%04d"), pt, ptlim);
+                pt = _conv(diff, getformat(modifier, "04", " 4", "  ", "04"), pt, ptlim);
                 }
                 continue;
             case '+':
@@ -629,10 +621,40 @@
 static char *
 _conv(int n, const char *format, char *pt, const char *ptlim)
 {
-	char	buf[INT_STRLEN_MAXIMUM(int) + 1];
+  // The original implementation used snprintf(3) here, but rolling our own is
+  // about 5x faster. Seems like a good trade-off for so little code, especially
+  // for users like logcat that have a habit of formatting 10k times all at
+  // once...
 
-	snprintf(buf, sizeof(buf), format, n);
-	return _add(buf, pt, ptlim, 0);
+  // Format is '0' or ' ' for the fill character, followed by a single-digit
+  // width or ' ' for "whatever".
+  //   %d -> "  "
+  //  %2d -> " 2"
+  // %02d -> "02"
+  char fill = format[0];
+  int width = format[1] == ' ' ? 0 : format[1] - '0';
+
+  char buf[32] __attribute__((__uninitialized__));
+
+  // Terminate first, so we can walk backwards from the least-significant digit
+  // without having to later reverse the result.
+  char* p = &buf[31];
+  *--p = '\0';
+  char* end = p;
+
+  // Output digits backwards, from least-significant to most.
+  while (n >= 10) {
+    *--p = '0' + (n % 10);
+    n /= 10;
+  }
+  *--p = '0' + n;
+
+  // Fill if more digits are required by the format.
+  while ((end - p) < width) {
+    *--p = fill;
+  }
+
+  return _add(p, pt, ptlim, 0);
 }
 
 static char *
@@ -704,9 +726,11 @@
     if (convert_top) {
         if (lead == 0 && trail < 0)
             pt = _add("-0", pt, ptlim, modifier);
-        else    pt = _conv(lead, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
+        else
+          pt = _conv(lead, getformat(modifier, "02", " 2", "  ", "02"), pt, ptlim);
     }
     if (convert_yy)
-        pt = _conv(((trail < 0) ? -trail : trail), getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
+      pt = _conv(((trail < 0) ? -trail : trail), getformat(modifier, "02", " 2", "  ", "02"), pt,
+                 ptlim);
     return pt;
 }
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 6c21c5b..8e6f87d 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -57,7 +57,13 @@
 /* OpenBSD has this, but we can't really implement it correctly on Linux. */
 #define issetugid() 0
 
+#if !defined(ANDROID_HOST_MUSL)
 #define explicit_bzero(p, s) memset(p, 0, s)
+#endif
+
+#if defined(ANDROID_HOST_MUSL)
+#define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
+#endif
 
 /* OpenBSD has this in paths.h. But this directory doesn't normally exist.
  * Even when it does exist, only the 'shell' user has permissions.
diff --git a/libfdtrack/Android.bp b/libfdtrack/Android.bp
index fb28623..83ea7cb 100644
--- a/libfdtrack/Android.bp
+++ b/libfdtrack/Android.bp
@@ -38,4 +38,5 @@
     whole_static_libs: ["libBionicCtsGtestMain"],
     static_libs: ["liblog"],
     test_suites: ["device-tests"],
+    runtime_libs: ["libfdtrack"],
 }
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 2e9cfbc..2d114f2 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -31,6 +31,8 @@
 
 #include <array>
 #include <mutex>
+#include <string>
+#include <string_view>
 #include <thread>
 #include <utility>
 #include <vector>
@@ -43,11 +45,14 @@
 #include <android-base/thread_annotations.h>
 #include <async_safe/log.h>
 #include <bionic/reserved_signals.h>
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/Unwinder.h>
 
 struct FdEntry {
   std::mutex mutex;
-  std::vector<unwindstack::LocalFrameData> backtrace GUARDED_BY(mutex);
+  std::vector<unwindstack::FrameData> backtrace GUARDED_BY(mutex);
 };
 
 extern "C" void fdtrack_dump();
@@ -62,15 +67,21 @@
 // Backtraces for the first 4k file descriptors ought to be enough to diagnose an fd leak.
 static constexpr size_t kFdTableSize = 4096;
 
-// 32 frames, plus two to skip from fdtrack itself.
-static constexpr size_t kStackDepth = 34;
-static constexpr size_t kStackFrameSkip = 2;
+// Only unwind up to 32 frames outside of libfdtrack.so.
+static constexpr size_t kStackDepth = 32;
+
+// Skip any initial frames from libfdtrack.so.
+static std::vector<std::string> kSkipFdtrackLib [[clang::no_destroy]] = {"libfdtrack.so"};
 
 static bool installed = false;
 static std::array<FdEntry, kFdTableSize> stack_traces [[clang::no_destroy]];
-static unwindstack::LocalUnwinder& Unwinder() {
-  static android::base::NoDestructor<unwindstack::LocalUnwinder> unwinder;
-  return *unwinder.get();
+static unwindstack::LocalUpdatableMaps& Maps() {
+  static android::base::NoDestructor<unwindstack::LocalUpdatableMaps> maps;
+  return *maps.get();
+}
+static std::shared_ptr<unwindstack::Memory>& ProcessMemory() {
+  static android::base::NoDestructor<std::shared_ptr<unwindstack::Memory>> process_memory;
+  return *process_memory.get();
 }
 
 __attribute__((constructor)) static void ctor() {
@@ -89,7 +100,8 @@
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
   sigaction(BIONIC_SIGNAL_FDTRACK, &sa, nullptr);
 
-  if (Unwinder().Init()) {
+  if (Maps().Parse()) {
+    ProcessMemory() = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
     android_fdtrack_hook_t expected = nullptr;
     installed = android_fdtrack_compare_exchange_hook(&expected, &fd_hook);
   }
@@ -116,7 +128,12 @@
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
       std::lock_guard<std::mutex> lock(entry->mutex);
       entry->backtrace.clear();
-      Unwinder().Unwind(&entry->backtrace, kStackDepth);
+
+      std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+      unwindstack::RegsGetLocal(regs.get());
+      unwindstack::Unwinder unwinder(kStackDepth, &Maps(), regs.get(), ProcessMemory());
+      unwinder.Unwind(&kSkipFdtrackLib);
+      entry->backtrace = unwinder.ConsumeFrames();
     }
   } else if (event->type == ANDROID_FDTRACK_EVENT_TYPE_CLOSE) {
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
@@ -153,14 +170,13 @@
       continue;
     }
 
-    for (size_t i = kStackFrameSkip; i < entry->backtrace.size(); ++i) {
-      size_t j = i - kStackFrameSkip;
-      function_names[j] = entry->backtrace[i].function_name.c_str();
-      function_offsets[j] = entry->backtrace[i].function_offset;
+    for (size_t i = 0; i < entry->backtrace.size(); ++i) {
+      function_names[i] = entry->backtrace[i].function_name.c_str();
+      function_offsets[i] = entry->backtrace[i].function_offset;
     }
 
-    bool should_continue = callback(fd, function_names, function_offsets,
-                                    entry->backtrace.size() - kStackFrameSkip, arg);
+    bool should_continue =
+        callback(fd, function_names, function_offsets, entry->backtrace.size(), arg);
 
     entry->mutex.unlock();
 
@@ -200,8 +216,8 @@
     size_t count = 0;
 
     size_t stack_depth = 0;
-    const char* function_names[kStackDepth - kStackFrameSkip];
-    uint64_t function_offsets[kStackDepth - kStackFrameSkip];
+    const char* function_names[kStackDepth];
+    uint64_t function_offsets[kStackDepth];
   };
   struct StackList {
     size_t count = 0;
diff --git a/libm/Android.bp b/libm/Android.bp
index 6c3abd1..7469cde 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -30,8 +30,6 @@
     whole_static_libs: ["libarm-optimized-routines-math"],
 
     srcs: [
-        "upstream-freebsd/lib/msun/bsdsrc/b_exp.c",
-        "upstream-freebsd/lib/msun/bsdsrc/b_log.c",
         "upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c",
         "upstream-freebsd/lib/msun/src/catrig.c",
         "upstream-freebsd/lib/msun/src/catrigf.c",
@@ -112,6 +110,7 @@
         "upstream-freebsd/lib/msun/src/s_copysign.c",
         "upstream-freebsd/lib/msun/src/s_copysignf.c",
         "upstream-freebsd/lib/msun/src/s_cos.c",
+        "upstream-freebsd/lib/msun/src/s_cospi.c",
         "upstream-freebsd/lib/msun/src/s_cpow.c",
         "upstream-freebsd/lib/msun/src/s_cpowf.c",
         "upstream-freebsd/lib/msun/src/s_cpowl.c",
@@ -177,6 +176,7 @@
         "upstream-freebsd/lib/msun/src/s_significand.c",
         "upstream-freebsd/lib/msun/src/s_significandf.c",
         "upstream-freebsd/lib/msun/src/s_sin.c",
+        "upstream-freebsd/lib/msun/src/s_sinpi.c",
         "upstream-freebsd/lib/msun/src/s_sincos.c",
         "upstream-freebsd/lib/msun/src/s_tan.c",
         "upstream-freebsd/lib/msun/src/s_tanf.c",
@@ -307,7 +307,7 @@
             no_libcrt: true,
             shared: {
                 // For backwards-compatibility, some arm32 builtins are exported from libm.so.
-                static_libs: ["libclang_rt.builtins-arm-android-exported"],
+                static_libs: ["libclang_rt.builtins-exported"],
             },
         },
 
@@ -489,6 +489,8 @@
         "-D_BSD_SOURCE",
         "-DFLT_EVAL_METHOD=0",
         "-include freebsd-compat.h",
+        "-include fenv-access.h",
+        "-fno-builtin",
         "-fno-math-errno",
         "-Wall",
         "-Werror",
@@ -496,6 +498,7 @@
         "-Wno-missing-braces",
         "-Wno-parentheses",
         "-Wno-sign-compare",
+        "-Wno-static-in-inline",
         "-Wno-unknown-pragmas",
         "-Wno-unused-const-variable",
         "-Wno-unused-variable",
@@ -509,7 +512,11 @@
     tidy_checks: ["-cert-dcl16-c"],
 
     include_dirs: ["bionic/libc"],
-    system_shared_libs: ["libc"],
+    target: {
+        bionic: {
+            system_shared_libs: ["libc"],
+        },
+    },
 
     sanitize: {
         address: false,
@@ -545,6 +552,8 @@
     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 {
diff --git a/libm/NOTICE b/libm/NOTICE
index 62d253b..64d253a 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -281,6 +281,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2021 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) 1985, 1993
    The Regents of the University of California.  All rights reserved.
 
@@ -661,6 +689,14 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2005-2020 Rich Felker, et al.
+
+
+Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
+for all contributors to musl.
+
+-------------------------------------------------------------------
+
 Copyright (c) 2007 David Schultz
 All rights reserved.
 
@@ -1145,6 +1181,32 @@
 
 -------------------------------------------------------------------
 
+Copyright (c) 2017 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/fenv-access.h b/libm/fenv-access.h
new file mode 100644
index 0000000..7acb34d
--- /dev/null
+++ b/libm/fenv-access.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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 defined(__x86_64__) || defined(__i386__)
+#pragma STDC FENV_ACCESS ON
+#endif
diff --git a/libm/freebsd-compat.h b/libm/freebsd-compat.h
index f400f2a..7accc55 100644
--- a/libm/freebsd-compat.h
+++ b/libm/freebsd-compat.h
@@ -39,3 +39,7 @@
 
 // Similarly rename _scan_nan.
 #define _scan_nan __libm_scan_nan
+
+// FreeBSD exports these in <math.h> but we don't.
+double cospi(double);
+double sinpi(double);
diff --git a/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c b/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c
index 89a2905..c667293 100644
--- a/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c
+++ b/libm/upstream-freebsd/lib/msun/bsdsrc/b_exp.c
@@ -33,7 +33,6 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-
 /* EXP(X)
  * RETURN THE EXPONENTIAL OF X
  * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
@@ -41,14 +40,14 @@
  * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86.
  *
  * Required system supported functions:
- *	scalb(x,n)
+ *	ldexp(x,n)
  *	copysign(x,y)
- *	finite(x)
+ *	isfinite(x)
  *
  * Method:
  *	1. Argument Reduction: given the input x, find r and integer k such
  *	   that
- *	                   x = k*ln2 + r,  |r| <= 0.5*ln2 .
+ *	        x = k*ln2 + r,  |r| <= 0.5*ln2.
  *	   r will be represented as r := z+c for better accuracy.
  *
  *	2. Compute exp(r) by
@@ -69,105 +68,59 @@
  *	with 1,156,000 random arguments on a VAX, the maximum observed
  *	error was 0.869 ulps (units in the last place).
  */
+static const double
+    p1 =  1.6666666666666660e-01, /* 0x3fc55555, 0x55555553 */
+    p2 = -2.7777777777564776e-03, /* 0xbf66c16c, 0x16c0ac3c */
+    p3 =  6.6137564717940088e-05, /* 0x3f11566a, 0xb5c2ba0d */
+    p4 = -1.6534060280704225e-06, /* 0xbebbbd53, 0x273e8fb7 */
+    p5 =  4.1437773411069054e-08; /* 0x3e663f2a, 0x09c94b6c */
 
-#include "mathimpl.h"
+static const double
+    ln2hi = 0x1.62e42fee00000p-1,   /* High 32 bits round-down. */
+    ln2lo = 0x1.a39ef35793c76p-33;  /* Next 53 bits round-to-nearst. */
 
-static const double p1 = 0x1.555555555553ep-3;
-static const double p2 = -0x1.6c16c16bebd93p-9;
-static const double p3 = 0x1.1566aaf25de2cp-14;
-static const double p4 = -0x1.bbd41c5d26bf1p-20;
-static const double p5 = 0x1.6376972bea4d0p-25;
-static const double ln2hi = 0x1.62e42fee00000p-1;
-static const double ln2lo = 0x1.a39ef35793c76p-33;
-static const double lnhuge = 0x1.6602b15b7ecf2p9;
-static const double lntiny = -0x1.77af8ebeae354p9;
-static const double invln2 = 0x1.71547652b82fep0;
-
-#if 0
-double exp(x)
-double x;
-{
-	double  z,hi,lo,c;
-	int k;
-
-#if !defined(vax)&&!defined(tahoe)
-	if(x!=x) return(x);	/* x is NaN */
-#endif	/* !defined(vax)&&!defined(tahoe) */
-	if( x <= lnhuge ) {
-		if( x >= lntiny ) {
-
-		    /* argument reduction : x --> x - k*ln2 */
-
-			k=invln2*x+copysign(0.5,x);	/* k=NINT(x/ln2) */
-
-		    /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */
-
-			hi=x-k*ln2hi;
-			x=hi-(lo=k*ln2lo);
-
-		    /* return 2^k*[1+x+x*c/(2+c)]  */
-			z=x*x;
-			c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
-			return  scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k);
-
-		}
-		/* end of x > lntiny */
-
-		else
-		     /* exp(-big#) underflows to zero */
-		     if(finite(x))  return(scalb(1.0,-5000));
-
-		     /* exp(-INF) is zero */
-		     else return(0.0);
-	}
-	/* end of x < lnhuge */
-
-	else
-	/* exp(INF) is INF, exp(+big#) overflows to INF */
-	    return( finite(x) ?  scalb(1.0,5000)  : x);
-}
-#endif
+static const double
+    lnhuge =  0x1.6602b15b7ecf2p9,  /* (DBL_MAX_EXP + 9) * log(2.) */
+    lntiny = -0x1.77af8ebeae354p9,  /* (DBL_MIN_EXP - 53 - 10) * log(2.) */
+    invln2 =  0x1.71547652b82fep0;  /* 1 / log(2.) */
 
 /* returns exp(r = x + c) for |c| < |x| with no overlap.  */
 
-double __exp__D(x, c)
-double x, c;
+static double
+__exp__D(double x, double c)
 {
-	double  z,hi,lo;
+	double hi, lo, z;
 	int k;
 
-	if (x != x)	/* x is NaN */
+	if (x != x)	/* x is NaN. */
 		return(x);
-	if ( x <= lnhuge ) {
-		if ( x >= lntiny ) {
 
-		    /* argument reduction : x --> x - k*ln2 */
-			z = invln2*x;
-			k = z + copysign(.5, x);
+	if (x <= lnhuge) {
+		if (x >= lntiny) {
+			/* argument reduction: x --> x - k*ln2 */
+			z = invln2 * x;
+			k = z + copysign(0.5, x);
 
-		    /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */
+		    	/*
+			 * Express (x + c) - k * ln2 as hi - lo.
+			 * Let x = hi - lo rounded.
+			 */
+			hi = x - k * ln2hi;	/* Exact. */
+			lo = k * ln2lo - c;
+			x = hi - lo;
 
-			hi=(x-k*ln2hi);			/* Exact. */
-			x= hi - (lo = k*ln2lo-c);
-		    /* return 2^k*[1+x+x*c/(2+c)]  */
-			z=x*x;
-			c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
-			c = (x*c)/(2.0-c);
+			/* Return 2^k*[1+x+x*c/(2+c)]  */
+			z = x * x;
+			c = x - z * (p1 + z * (p2 + z * (p3 + z * (p4 +
+			    z * p5))));
+			c = (x * c) / (2 - c);
 
-			return  scalb(1.+(hi-(lo - c)), k);
+			return (ldexp(1 + (hi - (lo - c)), k));
+		} else {
+			/* exp(-INF) is 0. exp(-big) underflows to 0.  */
+			return (isfinite(x) ? ldexp(1., -5000) : 0);
 		}
-		/* end of x > lntiny */
-
-		else
-		     /* exp(-big#) underflows to zero */
-		     if(finite(x))  return(scalb(1.0,-5000));
-
-		     /* exp(-INF) is zero */
-		     else return(0.0);
-	}
-	/* end of x < lnhuge */
-
-	else
+	} else
 	/* exp(INF) is INF, exp(+big#) overflows to INF */
-	    return( finite(x) ?  scalb(1.0,5000)  : x);
+		return (isfinite(x) ? ldexp(1., 5000) : x);
 }
diff --git a/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c b/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c
index c164dfa..9d09ac7 100644
--- a/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c
+++ b/libm/upstream-freebsd/lib/msun/bsdsrc/b_log.c
@@ -33,10 +33,6 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <math.h>
-
-#include "mathimpl.h"
-
 /* Table-driven natural logarithm.
  *
  * This code was derived, with minor modifications, from:
@@ -44,25 +40,27 @@
  *	Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
  *	Math Software, vol 16. no 4, pp 378-400, Dec 1990).
  *
- * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
+ * Calculates log(2^m*F*(1+f/F)), |f/F| <= 1/256,
  * where F = j/128 for j an integer in [0, 128].
  *
  * log(2^m) = log2_hi*m + log2_tail*m
- * since m is an integer, the dominant term is exact.
+ * The leading term is exact, because m is an integer,
  * m has at most 10 digits (for subnormal numbers),
  * and log2_hi has 11 trailing zero bits.
  *
- * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
+ * log(F) = logF_hi[j] + logF_lo[j] is in table below.
  * logF_hi[] + 512 is exact.
  *
  * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
- * the leading term is calculated to extra precision in two
+ *
+ * The leading term is calculated to extra precision in two
  * parts, the larger of which adds exactly to the dominant
  * m and F terms.
+ *
  * There are two cases:
- *	1. when m, j are non-zero (m | j), use absolute
+ *	1. When m and j are non-zero (m | j), use absolute
  *	   precision for the leading term.
- *	2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
+ *	2. When m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
  *	   In this case, use a relative precision of 24 bits.
  * (This is done differently in the original paper)
  *
@@ -70,11 +68,21 @@
  *	0	return signalling -Inf
  *	neg	return signalling NaN
  *	+Inf	return +Inf
-*/
+ */
 
 #define N 128
 
-/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
+/*
+ * Coefficients in the polynomial approximation of log(1+f/F).
+ * Domain of x is [0,1./256] with 2**(-64.187) precision.
+ */
+static const double
+    A1 =  8.3333333333333329e-02, /* 0x3fb55555, 0x55555555 */
+    A2 =  1.2499999999943598e-02, /* 0x3f899999, 0x99991a98 */
+    A3 =  2.2321527525957776e-03; /* 0x3f624929, 0xe24e70be */
+
+/*
+ * Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
  * Used for generation of extend precision logarithms.
  * The constant 35184372088832 is 2^45, so the divide is exact.
  * It ensures correct reading of logF_head, even for inaccurate
@@ -82,12 +90,7 @@
  * right answer for integers less than 2^53.)
  * Values for log(F) were generated using error < 10^-57 absolute
  * with the bc -l package.
-*/
-static double	A1 = 	  .08333333333333178827;
-static double	A2 = 	  .01250000000377174923;
-static double	A3 =	 .002232139987919447809;
-static double	A4 =	.0004348877777076145742;
-
+ */
 static double logF_head[N+1] = {
 	0.,
 	.007782140442060381246,
@@ -351,118 +354,51 @@
 	 .00000000000025144230728376072,
 	-.00000000000017239444525614834
 };
-
-#if 0
-double
-#ifdef _ANSI_SOURCE
-log(double x)
-#else
-log(x) double x;
-#endif
-{
-	int m, j;
-	double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
-	volatile double u1;
-
-	/* Catch special cases */
-	if (x <= 0)
-		if (x == zero)	/* log(0) = -Inf */
-			return (-one/zero);
-		else		/* log(neg) = NaN */
-			return (zero/zero);
-	else if (!finite(x))
-		return (x+x);		/* x = NaN, Inf */
-
-	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
-	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
-
-	m = logb(x);
-	g = ldexp(x, -m);
-	if (m == -1022) {
-		j = logb(g), m += j;
-		g = ldexp(g, -j);
-	}
-	j = N*(g-1) + .5;
-	F = (1.0/N) * j + 1;	/* F*128 is an integer in [128, 512] */
-	f = g - F;
-
-	/* Approximate expansion for log(1+f/F) ~= u + q */
-	g = 1/(2*F+f);
-	u = 2*f*g;
-	v = u*u;
-	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
-
-    /* case 1: u1 = u rounded to 2^-43 absolute.  Since u < 2^-8,
-     * 	       u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
-     *         It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
-    */
-	if (m | j)
-		u1 = u + 513, u1 -= 513;
-
-    /* case 2:	|1-x| < 1/256. The m- and j- dependent terms are zero;
-     * 		u1 = u to 24 bits.
-    */
-	else
-		u1 = u, TRUNC(u1);
-	u2 = (2.0*(f - F*u1) - u1*f) * g;
-			/* u1 + u2 = 2f/(2F+f) to extra precision.	*/
-
-	/* log(x) = log(2^m*F*(1+f/F)) =				*/
-	/* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q);	*/
-	/* (exact) + (tiny)						*/
-
-	u1 += m*logF_head[N] + logF_head[j];		/* exact */
-	u2 = (u2 + logF_tail[j]) + q;			/* tiny */
-	u2 += logF_tail[N]*m;
-	return (u1 + u2);
-}
-#endif
-
 /*
  * Extra precision variant, returning struct {double a, b;};
- * log(x) = a+b to 63 bits, with a rounded to 26 bits.
+ * log(x) = a+b to 63 bits, with 'a' rounded to 24 bits.
  */
-struct Double
-#ifdef _ANSI_SOURCE
+static struct Double
 __log__D(double x)
-#else
-__log__D(x) double x;
-#endif
 {
 	int m, j;
-	double F, f, g, q, u, v, u2;
-	volatile double u1;
+	double F, f, g, q, u, v, u1, u2;
 	struct Double r;
 
-	/* Argument reduction: 1 <= g < 2; x/2^m = g;	*/
-	/* y = F*(1 + f/F) for |f| <= 2^-8		*/
-
-	m = logb(x);
-	g = ldexp(x, -m);
+	/*
+	 * Argument reduction: 1 <= g < 2; x/2^m = g;
+	 * y = F*(1 + f/F) for |f| <= 2^-8
+	 */
+	g = frexp(x, &m);
+	g *= 2;
+	m--;
 	if (m == -1022) {
-		j = logb(g), m += j;
+		j = ilogb(g);
+		m += j;
 		g = ldexp(g, -j);
 	}
-	j = N*(g-1) + .5;
-	F = (1.0/N) * j + 1;
+	j = N * (g - 1) + 0.5;
+	F = (1. / N) * j + 1;
 	f = g - F;
 
-	g = 1/(2*F+f);
-	u = 2*f*g;
-	v = u*u;
-	q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
-	if (m | j)
-		u1 = u + 513, u1 -= 513;
-	else
-		u1 = u, TRUNC(u1);
-	u2 = (2.0*(f - F*u1) - u1*f) * g;
+	g = 1 / (2 * F + f);
+	u = 2 * f * g;
+	v = u * u;
+	q = u * v * (A1 + v * (A2 + v * A3));
+	if (m | j) {
+		u1 = u + 513;
+		u1 -= 513;
+	} else {
+		u1 = (float)u;
+	}
+	u2 = (2 * (f - F * u1) - u1 * f) * g;
 
-	u1 += m*logF_head[N] + logF_head[j];
+	u1 += m * logF_head[N] + logF_head[j];
 
-	u2 +=  logF_tail[j]; u2 += q;
-	u2 += logF_tail[N]*m;
-	r.a = u1 + u2;			/* Only difference is here */
-	TRUNC(r.a);
+	u2 += logF_tail[j];
+	u2 += q;
+	u2 += logF_tail[N] * m;
+	r.a = (float)(u1 + u2);		/* Only difference is here. */
 	r.b = (u1 - r.a) + u2;
 	return (r);
 }
diff --git a/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c b/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c
index 5cb1f93..493ced3 100644
--- a/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c
+++ b/libm/upstream-freebsd/lib/msun/bsdsrc/b_tgamma.c
@@ -29,37 +29,46 @@
  * SUCH DAMAGE.
  */
 
+/*
+ * The original code, FreeBSD's old svn r93211, contained the following
+ * attribution:
+ *
+ *    This code by P. McIlroy, Oct 1992;
+ *
+ *    The financial support of UUNET Communications Services is greatfully
+ *    acknowledged.
+ *
+ *  The algorithm remains, but the code has been re-arranged to facilitate
+ *  porting to other precisions.
+ */
+
 /* @(#)gamma.c	8.1 (Berkeley) 6/4/93 */
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <float.h>
+
+#include "math.h"
+#include "math_private.h"
+
+/* Used in b_log.c and below. */
+struct Double {
+	double a;
+	double b;
+};
+
+#include "b_log.c"
+#include "b_exp.c"
+
 /*
- * This code by P. McIlroy, Oct 1992;
+ * The range is broken into several subranges.  Each is handled by its
+ * helper functions.
  *
- * The financial support of UUNET Communications Services is greatfully
- * acknowledged.
- */
-
-#include <math.h>
-#include "mathimpl.h"
-
-/* METHOD:
- * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x))
- * 	At negative integers, return NaN and raise invalid.
- *
- * x < 6.5:
- *	Use argument reduction G(x+1) = xG(x) to reach the
- *	range [1.066124,2.066124].  Use a rational
- *	approximation centered at the minimum (x0+1) to
- *	ensure monotonicity.
- *
- * x >= 6.5: Use the asymptotic approximation (Stirling's formula)
- *	adjusted for equal-ripples:
- *
- *	log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x))
- *
- *	Keep extra precision in multiplying (x-.5)(log(x)-1), to
- *	avoid premature round-off.
+ *         x >=   6.0: large_gam(x)
+ *   6.0 > x >= xleft: small_gam(x) where xleft = 1 + left + x0.
+ * xleft > x >   iota: smaller_gam(x) where iota = 1e-17.
+ *  iota > x >  -itoa: Handle x near 0.
+ * -iota > x         : neg_gam
  *
  * Special values:
  *	-Inf:			return NaN and raise invalid;
@@ -77,201 +86,224 @@
  *	Maximum observed error < 4ulp in 1,000,000 trials.
  */
 
-static double neg_gam(double);
-static double small_gam(double);
-static double smaller_gam(double);
-static struct Double large_gam(double);
-static struct Double ratfun_gam(double, double);
-
-/*
- * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval
- * [1.066.., 2.066..] accurate to 4.25e-19.
- */
-#define LEFT -.3955078125	/* left boundary for rat. approx */
-#define x0 .461632144968362356785	/* xmin - 1 */
-
-#define a0_hi 0.88560319441088874992
-#define a0_lo -.00000000000000004996427036469019695
-#define P0	 6.21389571821820863029017800727e-01
-#define P1	 2.65757198651533466104979197553e-01
-#define P2	 5.53859446429917461063308081748e-03
-#define P3	 1.38456698304096573887145282811e-03
-#define P4	 2.40659950032711365819348969808e-03
-#define Q0	 1.45019531250000000000000000000e+00
-#define Q1	 1.06258521948016171343454061571e+00
-#define Q2	-2.07474561943859936441469926649e-01
-#define Q3	-1.46734131782005422506287573015e-01
-#define Q4	 3.07878176156175520361557573779e-02
-#define Q5	 5.12449347980666221336054633184e-03
-#define Q6	-1.76012741431666995019222898833e-03
-#define Q7	 9.35021023573788935372153030556e-05
-#define Q8	 6.13275507472443958924745652239e-06
 /*
  * Constants for large x approximation (x in [6, Inf])
  * (Accurate to 2.8*10^-19 absolute)
  */
-#define lns2pi_hi 0.418945312500000
-#define lns2pi_lo -.000006779295327258219670263595
-#define Pa0	 8.33333333333333148296162562474e-02
-#define Pa1	-2.77777777774548123579378966497e-03
-#define Pa2	 7.93650778754435631476282786423e-04
-#define Pa3	-5.95235082566672847950717262222e-04
-#define Pa4	 8.41428560346653702135821806252e-04
-#define Pa5	-1.89773526463879200348872089421e-03
-#define Pa6	 5.69394463439411649408050664078e-03
-#define Pa7	-1.44705562421428915453880392761e-02
 
-static const double zero = 0., one = 1.0, tiny = 1e-300;
-
-double
-tgamma(x)
-	double x;
-{
-	struct Double u;
-
-	if (x >= 6) {
-		if(x > 171.63)
-			return (x / zero);
-		u = large_gam(x);
-		return(__exp__D(u.a, u.b));
-	} else if (x >= 1.0 + LEFT + x0)
-		return (small_gam(x));
-	else if (x > 1.e-17)
-		return (smaller_gam(x));
-	else if (x > -1.e-17) {
-		if (x != 0.0)
-			u.a = one - tiny;	/* raise inexact */
-		return (one/x);
-	} else if (!finite(x))
-		return (x - x);		/* x is NaN or -Inf */
-	else
-		return (neg_gam(x));
-}
+static const double zero = 0.;
+static const volatile double tiny = 1e-300;
 /*
+ * x >= 6
+ *
+ * Use the asymptotic approximation (Stirling's formula) adjusted fof
+ * equal-ripples:
+ *
+ * log(G(x)) ~= (x-0.5)*(log(x)-1) + 0.5(log(2*pi)-1) + 1/x*P(1/(x*x))
+ *
+ * Keep extra precision in multiplying (x-.5)(log(x)-1), to avoid
+ * premature round-off.
+ *
  * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error.
  */
-static struct Double
-large_gam(x)
-	double x;
-{
-	double z, p;
-	struct Double t, u, v;
+static const double
+    ln2pi_hi =  0.41894531250000000,
+    ln2pi_lo = -6.7792953272582197e-6,
+    Pa0 =  8.3333333333333329e-02, /* 0x3fb55555, 0x55555555 */
+    Pa1 = -2.7777777777735404e-03, /* 0xbf66c16c, 0x16c145ec */
+    Pa2 =  7.9365079044114095e-04, /* 0x3f4a01a0, 0x183de82d */
+    Pa3 = -5.9523715464225254e-04, /* 0xbf438136, 0x0e681f62 */
+    Pa4 =  8.4161391899445698e-04, /* 0x3f4b93f8, 0x21042a13 */
+    Pa5 = -1.9065246069191080e-03, /* 0xbf5f3c8b, 0x357cb64e */
+    Pa6 =  5.9047708485785158e-03, /* 0x3f782f99, 0xdaf5d65f */
+    Pa7 = -1.6484018705183290e-02; /* 0xbf90e12f, 0xc4fb4df0 */
 
-	z = one/(x*x);
-	p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7))))));
-	p = p/x;
+static struct Double
+large_gam(double x)
+{
+	double p, z, thi, tlo, xhi, xlo;
+	struct Double u;
+
+	z = 1 / (x * x);
+	p = Pa0 + z * (Pa1 + z * (Pa2 + z * (Pa3 + z * (Pa4 + z * (Pa5 +
+	    z * (Pa6 + z * Pa7))))));
+	p = p / x;
 
 	u = __log__D(x);
-	u.a -= one;
-	v.a = (x -= .5);
-	TRUNC(v.a);
-	v.b = x - v.a;
-	t.a = v.a*u.a;			/* t = (x-.5)*(log(x)-1) */
-	t.b = v.b*u.a + x*u.b;
-	/* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */
-	t.b += lns2pi_lo; t.b += p;
-	u.a = lns2pi_hi + t.b; u.a += t.a;
-	u.b = t.a - u.a;
-	u.b += lns2pi_hi; u.b += t.b;
+	u.a -= 1;
+
+	/* Split (x - 0.5) in high and low parts. */
+	x -= 0.5;
+	xhi = (float)x;
+	xlo = x - xhi;
+
+	/* Compute  t = (x-.5)*(log(x)-1) in extra precision. */
+	thi = xhi * u.a;
+	tlo = xlo * u.a + x * u.b;
+
+	/* Compute thi + tlo + ln2pi_hi + ln2pi_lo + p. */
+	tlo += ln2pi_lo;
+	tlo += p;
+	u.a = ln2pi_hi + tlo;
+	u.a += thi;
+	u.b = thi - u.a;
+	u.b += ln2pi_hi;
+	u.b += tlo;
 	return (u);
 }
 /*
+ * Rational approximation, A0 + x * x * P(x) / Q(x), on the interval
+ * [1.066.., 2.066..] accurate to 4.25e-19.
+ *
+ * Returns r.a + r.b = a0 + (z + c)^2 * p / q, with r.a truncated.
+ */
+static const double
+#if 0
+    a0_hi =  8.8560319441088875e-1,
+    a0_lo = -4.9964270364690197e-17,
+#else
+    a0_hi =  8.8560319441088875e-01, /* 0x3fec56dc, 0x82a74aef */
+    a0_lo = -4.9642368725563397e-17, /* 0xbc8c9deb, 0xaa64afc3 */
+#endif
+    P0 =  6.2138957182182086e-1,
+    P1 =  2.6575719865153347e-1,
+    P2 =  5.5385944642991746e-3,
+    P3 =  1.3845669830409657e-3,
+    P4 =  2.4065995003271137e-3,
+    Q0 =  1.4501953125000000e+0,
+    Q1 =  1.0625852194801617e+0,
+    Q2 = -2.0747456194385994e-1,
+    Q3 = -1.4673413178200542e-1,
+    Q4 =  3.0787817615617552e-2,
+    Q5 =  5.1244934798066622e-3,
+    Q6 = -1.7601274143166700e-3,
+    Q7 =  9.3502102357378894e-5,
+    Q8 =  6.1327550747244396e-6;
+
+static struct Double
+ratfun_gam(double z, double c)
+{
+	double p, q, thi, tlo;
+	struct Double r;
+
+	q = Q0 + z * (Q1 + z * (Q2 + z * (Q3 + z * (Q4 + z * (Q5 + 
+	    z * (Q6 + z * (Q7 + z * Q8)))))));
+	p = P0 + z * (P1 + z * (P2 + z * (P3 + z * P4)));
+	p = p / q;
+
+	/* Split z into high and low parts. */
+	thi = (float)z;
+	tlo = (z - thi) + c;
+	tlo *= (thi + z);
+
+	/* Split (z+c)^2 into high and low parts. */
+	thi *= thi;
+	q = thi;
+	thi = (float)thi;
+	tlo += (q - thi);
+
+	/* Split p/q into high and low parts. */
+	r.a = (float)p;
+	r.b = p - r.a;
+
+	tlo = tlo * p + thi * r.b + a0_lo;
+	thi *= r.a;				/* t = (z+c)^2*(P/Q) */
+	r.a = (float)(thi + a0_hi);
+	r.b = ((a0_hi - r.a) + thi) + tlo;
+	return (r);				/* r = a0 + t */
+}
+/*
+ * x < 6
+ *
+ * Use argument reduction G(x+1) = xG(x) to reach the range [1.066124,
+ * 2.066124].  Use a rational approximation centered at the minimum
+ * (x0+1) to ensure monotonicity.
+ *
  * Good to < 1 ulp.  (provably .90 ulp; .87 ulp on 1,000,000 runs.)
  * It also has correct monotonicity.
  */
+static const double
+    left = -0.3955078125,	/* left boundary for rat. approx */
+    x0 = 4.6163214496836236e-1;	/* xmin - 1 */
+
 static double
-small_gam(x)
-	double x;
+small_gam(double x)
 {
-	double y, ym1, t;
+	double t, y, ym1;
 	struct Double yy, r;
-	y = x - one;
-	ym1 = y - one;
-	if (y <= 1.0 + (LEFT + x0)) {
+
+	y = x - 1;
+	if (y <= 1 + (left + x0)) {
 		yy = ratfun_gam(y - x0, 0);
 		return (yy.a + yy.b);
 	}
-	r.a = y;
-	TRUNC(r.a);
-	yy.a = r.a - one;
-	y = ym1;
-	yy.b = r.b = y - yy.a;
+
+	r.a = (float)y;
+	yy.a = r.a - 1;
+	y = y - 1 ;
+	r.b = yy.b = y - yy.a;
+
 	/* Argument reduction: G(x+1) = x*G(x) */
-	for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) {
-		t = r.a*yy.a;
-		r.b = r.a*yy.b + y*r.b;
-		r.a = t;
-		TRUNC(r.a);
+	for (ym1 = y - 1; ym1 > left + x0; y = ym1--, yy.a--) {
+		t = r.a * yy.a;
+		r.b = r.a * yy.b + y * r.b;
+		r.a = (float)t;
 		r.b += (t - r.a);
 	}
+
 	/* Return r*tgamma(y). */
 	yy = ratfun_gam(y - x0, 0);
-	y = r.b*(yy.a + yy.b) + r.a*yy.b;
-	y += yy.a*r.a;
+	y = r.b * (yy.a + yy.b) + r.a * yy.b;
+	y += yy.a * r.a;
 	return (y);
 }
 /*
- * Good on (0, 1+x0+LEFT].  Accurate to 1ulp.
+ * Good on (0, 1+x0+left].  Accurate to 1 ulp.
  */
 static double
-smaller_gam(x)
-	double x;
+smaller_gam(double x)
 {
-	double t, d;
-	struct Double r, xx;
-	if (x < x0 + LEFT) {
-		t = x, TRUNC(t);
-		d = (t+x)*(x-t);
+	double d, rhi, rlo, t, xhi, xlo;
+	struct Double r;
+
+	if (x < x0 + left) {
+		t = (float)x;
+		d = (t + x) * (x - t);
 		t *= t;
-		xx.a = (t + x), TRUNC(xx.a);
-		xx.b = x - xx.a; xx.b += t; xx.b += d;
-		t = (one-x0); t += x;
-		d = (one-x0); d -= t; d += x;
-		x = xx.a + xx.b;
+		xhi = (float)(t + x);
+		xlo = x - xhi;
+		xlo += t;
+		xlo += d;
+		t = 1 - x0;
+		t += x;
+		d = 1 - x0;
+		d -= t;
+		d += x;
+		x = xhi + xlo;
 	} else {
-		xx.a =  x, TRUNC(xx.a);
-		xx.b = x - xx.a;
+		xhi = (float)x;
+		xlo = x - xhi;
 		t = x - x0;
-		d = (-x0 -t); d += x;
+		d = - x0 - t;
+		d += x;
 	}
+
 	r = ratfun_gam(t, d);
-	d = r.a/x, TRUNC(d);
-	r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b;
-	return (d + r.a/x);
+	d = (float)(r.a / x);
+	r.a -= d * xhi;
+	r.a -= d * xlo;
+	r.a += r.b;
+
+	return (d + r.a / x);
 }
 /*
- * returns (z+c)^2 * P(z)/Q(z) + a0
+ * x < 0
+ *
+ * Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x)).
+ * At negative integers, return NaN and raise invalid.
  */
-static struct Double
-ratfun_gam(z, c)
-	double z, c;
-{
-	double p, q;
-	struct Double r, t;
-
-	q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8)))))));
-	p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4)));
-
-	/* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */
-	p = p/q;
-	t.a = z, TRUNC(t.a);		/* t ~= z + c */
-	t.b = (z - t.a) + c;
-	t.b *= (t.a + z);
-	q = (t.a *= t.a);		/* t = (z+c)^2 */
-	TRUNC(t.a);
-	t.b += (q - t.a);
-	r.a = p, TRUNC(r.a);		/* r = P/Q */
-	r.b = p - r.a;
-	t.b = t.b*p + t.a*r.b + a0_lo;
-	t.a *= r.a;			/* t = (z+c)^2*(P/Q) */
-	r.a = t.a + a0_hi, TRUNC(r.a);
-	r.b = ((a0_hi-r.a) + t.a) + t.b;
-	return (r);			/* r = a0 + t */
-}
-
 static double
-neg_gam(x)
-	double x;
+neg_gam(double x)
 {
 	int sgn = 1;
 	struct Double lg, lsine;
@@ -280,23 +312,29 @@
 	y = ceil(x);
 	if (y == x)		/* Negative integer. */
 		return ((x - x) / zero);
+
 	z = y - x;
 	if (z > 0.5)
-		z = one - z;
-	y = 0.5 * y;
+		z = 1 - z;
+
+	y = y / 2;
 	if (y == ceil(y))
 		sgn = -1;
-	if (z < .25)
-		z = sin(M_PI*z);
+
+	if (z < 0.25)
+		z = sinpi(z);
 	else
-		z = cos(M_PI*(0.5-z));
+		z = cospi(0.5 - z);
+
 	/* Special case: G(1-x) = Inf; G(x) may be nonzero. */
 	if (x < -170) {
+
 		if (x < -190)
-			return ((double)sgn*tiny*tiny);
-		y = one - x;		/* exact: 128 < |x| < 255 */
+			return (sgn * tiny * tiny);
+
+		y = 1 - x;			/* exact: 128 < |x| < 255 */
 		lg = large_gam(y);
-		lsine = __log__D(M_PI/z);	/* = TRUNC(log(u)) + small */
+		lsine = __log__D(M_PI / z);	/* = TRUNC(log(u)) + small */
 		lg.a -= lsine.a;		/* exact (opposite signs) */
 		lg.b -= lsine.b;
 		y = -(lg.a + lg.b);
@@ -305,11 +343,58 @@
 		if (sgn < 0) y = -y;
 		return (y);
 	}
-	y = one-x;
-	if (one-y == x)
+
+	y = 1 - x;
+	if (1 - y == x)
 		y = tgamma(y);
 	else		/* 1-x is inexact */
-		y = -x*tgamma(-x);
+		y = - x * tgamma(-x);
+
 	if (sgn < 0) y = -y;
-	return (M_PI / (y*z));
+	return (M_PI / (y * z));
 }
+/*
+ * xmax comes from lgamma(xmax) - emax * log(2) = 0.
+ * static const float  xmax = 35.040095f
+ * static const double xmax = 171.624376956302725;
+ * ld80: LD80C(0xdb718c066b352e20, 10, 1.75554834290446291689e+03L),
+ * ld128: 1.75554834290446291700388921607020320e+03L,
+ *
+ * iota is a sloppy threshold to isolate x = 0.
+ */
+static const double xmax = 171.624376956302725;
+static const double iota = 0x1p-56;
+
+double
+tgamma(double x)
+{
+	struct Double u;
+
+	if (x >= 6) {
+		if (x > xmax)
+			return (x / zero);
+		u = large_gam(x);
+		return (__exp__D(u.a, u.b));
+	}
+
+	if (x >= 1 + left + x0)
+		return (small_gam(x));
+
+	if (x > iota)
+		return (smaller_gam(x));
+
+	if (x > -iota) {
+		if (x != 0.)
+			u.a = 1 - tiny;	/* raise inexact */
+		return (1 / x);
+	}
+
+	if (!isfinite(x))
+		return (x - x);		/* x is NaN or -Inf */
+
+	return (neg_gam(x));
+}
+
+#if (LDBL_MANT_DIG == 53)
+__weak_reference(tgamma, tgammal);
+#endif
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c b/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c
index fe57773..422357b 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_cosl.c
@@ -21,8 +21,8 @@
 #include "math_private.h"
 
 /*
- * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
- * |cos(x) - c(x))| < 2**-122.0
+ * Domain [-0.7854, 0.7854], range ~[-1.17e-39, 1.19e-39]:
+ * |cos(x) - c(x))| < 2**-129.3
  *
  * 113-bit precision requires more care than 64-bit precision, since
  * simple methods give a minimax polynomial with coefficient for x^2
@@ -31,21 +31,19 @@
  */
 static const double
 one = 1.0;
-
 static const long double
-C1 =  0.04166666666666666666666666666666658424671L,
-C2 = -0.001388888888888888888888888888863490893732L,
-C3 =  0.00002480158730158730158730158600795304914210L,
-C4 = -0.2755731922398589065255474947078934284324e-6L,
-C5 =  0.2087675698786809897659225313136400793948e-8L,
-C6 = -0.1147074559772972315817149986812031204775e-10L,
-C7 =  0.4779477332386808976875457937252120293400e-13L;
-
-static const double
-C8 = -0.1561920696721507929516718307820958119868e-15,
-C9 =  0.4110317413744594971475941557607804508039e-18,
-C10 = -0.8896592467191938803288521958313920156409e-21,
-C11 =  0.1601061435794535138244346256065192782581e-23;
+C1 =  4.16666666666666666666666666666666667e-02L,
+C2 = -1.38888888888888888888888888888888834e-03L,
+C3 =  2.48015873015873015873015873015446795e-05L,
+C4 = -2.75573192239858906525573190949988493e-07L,
+C5 =  2.08767569878680989792098886701451072e-09L,
+C6 = -1.14707455977297247136657111139971865e-11L,
+C7 =  4.77947733238738518870113294139830239e-14L,
+C8 = -1.56192069685858079920640872925306403e-16L,
+C9 =  4.11031762320473354032038893429515732e-19L,
+C10= -8.89679121027589608738005163931958096e-22L,
+C11=  1.61171797801314301767074036661901531e-24L,
+C12= -2.46748624357670948912574279501044295e-27L;
 
 long double
 __kernel_cosl(long double x, long double y)
@@ -54,7 +52,7 @@
 
 	z  = x*x;
 	r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+
-	    z*(C8+z*(C9+z*(C10+z*C11))))))))));
+	    z*(C8+z*(C9+z*(C10+z*(C11+z*C12)))))))))));
 	hz = 0.5*z;
 	w  = one-hz;
 	return w + (((one-w)-hz) + (z*r-x*y));
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
index 93a2a7c..4774a27 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
@@ -697,14 +697,15 @@
 invln2_hi =  1.4426950402557850e0;		/*  0x17154765000000.0p-52 */
 static const long double
 invln10_lo =  1.41498268538580090791605082294397000e-10L,	/*  0x137287195355baaafad33dc323ee3.0p-145L */
-invln2_lo =  6.33178418956604368501892137426645911e-10L;	/*  0x15c17f0bbbe87fed0691d3e88eb57.0p-143L */
+invln2_lo =  6.33178418956604368501892137426645911e-10L,	/*  0x15c17f0bbbe87fed0691d3e88eb57.0p-143L */
+invln10_lo_plus_hi = invln10_lo + invln10_hi,
+invln2_lo_plus_hi = invln2_lo + invln2_hi;
 
 long double
 log10l(long double x)
 {
 	struct ld r;
-	long double lo;
-	float hi;
+	long double hi, lo;
 
 	ENTERI();
 	DOPRINT_START(&x);
@@ -712,18 +713,17 @@
 	if (!r.lo_set)
 		RETURNPI(r.hi);
 	_2sumF(r.hi, r.lo);
-	hi = r.hi;
+	hi = (float)r.hi;
 	lo = r.lo + (r.hi - hi);
 	RETURN2PI(invln10_hi * hi,
-	    (invln10_lo + invln10_hi) * lo + invln10_lo * hi);
+	    invln10_lo_plus_hi * lo + invln10_lo * hi);
 }
 
 long double
 log2l(long double x)
 {
 	struct ld r;
-	long double lo;
-	float hi;
+	long double hi, lo;
 
 	ENTERI();
 	DOPRINT_START(&x);
@@ -731,10 +731,10 @@
 	if (!r.lo_set)
 		RETURNPI(r.hi);
 	_2sumF(r.hi, r.lo);
-	hi = r.hi;
+	hi = (float)r.hi;
 	lo = r.lo + (r.hi - hi);
 	RETURN2PI(invln2_hi * hi,
-	    (invln2_lo + invln2_hi) * lo + invln2_lo * hi);
+	    invln2_lo_plus_hi * lo + invln2_lo * hi);
 }
 
 #endif /* STRUCT_RETURN */
diff --git a/libm/upstream-freebsd/lib/msun/src/e_hypotl.c b/libm/upstream-freebsd/lib/msun/src/e_hypotl.c
index 9189b1f..fc43538 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_hypotl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_hypotl.c
@@ -82,7 +82,7 @@
 	        man_t manh, manl;
 		GET_LDBL_MAN(manh,manl,b);
 		if((manh|manl)==0) return a;
-		t1=0;
+		t1=1;
 		SET_HIGH_WORD(t1,ESW(MAX_EXP-2));	/* t1=2^(MAX_EXP-2) */
 		b *= t1;
 		a *= t1;
diff --git a/libm/upstream-freebsd/lib/msun/src/e_powf.c b/libm/upstream-freebsd/lib/msun/src/e_powf.c
index 53f1d37..122da45 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_powf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_powf.c
@@ -136,7 +136,7 @@
     /* |y| is huge */
 	if(iy>0x4d000000) { /* if |y| > 2**27 */
 	/* over/underflow if x is not close to one */
-	    if(ix<0x3f7ffff8) return (hy<0)? sn*huge*huge:sn*tiny*tiny;
+	    if(ix<0x3f7ffff6) return (hy<0)? sn*huge*huge:sn*tiny*tiny;
 	    if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny;
 	/* now |1-x| is tiny <= 2**-20, suffice to compute
 	   log(x) by x-x^2/2+x^3/3-x^4/4 */
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrt.c b/libm/upstream-freebsd/lib/msun/src/e_sqrt.c
index 12fb56e..37351a4 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sqrt.c
@@ -14,6 +14,18 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <float.h>
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef USE_BUILTIN_SQRT
+double
+__ieee754_sqrt(double x)
+{
+	return (__builtin_sqrt(x));
+}
+#else
 /* __ieee754_sqrt(x)
  * Return correctly rounded sqrt.
  *           ------------------------------------------
@@ -84,11 +96,6 @@
  *---------------
  */
 
-#include <float.h>
-
-#include "math.h"
-#include "math_private.h"
-
 static	const double	one	= 1.0, tiny=1.0e-300;
 
 double
@@ -187,6 +194,7 @@
 	INSERT_WORDS(z,ix0,ix1);
 	return z;
 }
+#endif
 
 #if (LDBL_MANT_DIG == 53)
 __weak_reference(sqrt, sqrtl);
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c b/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c
index 7eba4d0..06e5d62 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sqrtf.c
@@ -20,6 +20,13 @@
 #include "math.h"
 #include "math_private.h"
 
+#ifdef USE_BUILTIN_SQRTF
+float
+__ieee754_sqrtf(float x)
+{
+	return (__builtin_sqrtf(x));
+}
+#else
 static	const float	one	= 1.0, tiny=1.0e-30;
 
 float
@@ -87,3 +94,4 @@
 	SET_FLOAT_WORD(z,ix);
 	return z;
 }
+#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/k_cospi.h b/libm/upstream-freebsd/lib/msun/src/k_cospi.h
new file mode 100644
index 0000000..32985be
--- /dev/null
+++ b/libm/upstream-freebsd/lib/msun/src/k_cospi.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2017 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.
+ */
+
+/*
+ * The basic kernel for x in [0,0.25].  To use the kernel for cos(x), the
+ * argument to __kernel_cospi() must be multiplied by pi.
+ */
+
+static inline double
+__kernel_cospi(double x)
+{
+	double_t hi, lo;
+
+	hi = (float)x;
+	lo = x - hi;
+	lo = lo * (pi_lo + pi_hi) + hi * pi_lo;
+	hi *= pi_hi;
+	_2sumF(hi, lo);
+	return (__kernel_cos(hi, lo));
+}
+
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sincosl.h b/libm/upstream-freebsd/lib/msun/src/k_sincosl.h
index 4d4dc69..6425f14 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_sincosl.h
+++ b/libm/upstream-freebsd/lib/msun/src/k_sincosl.h
@@ -76,13 +76,6 @@
 #elif LDBL_MANT_DIG == 113	/* ld128 version of k_sincosl.c. */
 
 static const long double
-C1 =  0.04166666666666666666666666666666658424671L,
-C2 = -0.001388888888888888888888888888863490893732L,
-C3 =  0.00002480158730158730158730158600795304914210L,
-C4 = -0.2755731922398589065255474947078934284324e-6L,
-C5 =  0.2087675698786809897659225313136400793948e-8L,
-C6 = -0.1147074559772972315817149986812031204775e-10L,
-C7 =  0.4779477332386808976875457937252120293400e-13L,
 S1 = -0.16666666666666666666666666666666666606732416116558L,
 S2 =  0.0083333333333333333333333333333331135404851288270047L,
 S3 = -0.00019841269841269841269841269839935785325638310428717L,
@@ -93,15 +86,25 @@
 S8 =  0.28114572543451292625024967174638477283187397621303e-14L;
 
 static const double
-C8  = -0.1561920696721507929516718307820958119868e-15,
-C9  =  0.4110317413744594971475941557607804508039e-18,
-C10 = -0.8896592467191938803288521958313920156409e-21,
-C11 =  0.1601061435794535138244346256065192782581e-23,
 S9  = -0.82206352458348947812512122163446202498005154296863e-17,
 S10 =  0.19572940011906109418080609928334380560135358385256e-19,
 S11 = -0.38680813379701966970673724299207480965452616911420e-22,
 S12 =  0.64038150078671872796678569586315881020659912139412e-25;
 
+static const long double
+C1 =  4.16666666666666666666666666666666667e-02L,
+C2 = -1.38888888888888888888888888888888834e-03L,
+C3 =  2.48015873015873015873015873015446795e-05L,
+C4 = -2.75573192239858906525573190949988493e-07L,
+C5 =  2.08767569878680989792098886701451072e-09L,
+C6 = -1.14707455977297247136657111139971865e-11L,
+C7 =  4.77947733238738518870113294139830239e-14L,
+C8 = -1.56192069685858079920640872925306403e-16L,
+C9 =  4.11031762320473354032038893429515732e-19L,
+C10= -8.89679121027589608738005163931958096e-22L,
+C11=  1.61171797801314301767074036661901531e-24L,
+C12= -2.46748624357670948912574279501044295e-27L;
+
 static inline void
 __kernel_sincosl(long double x, long double y, int iy, long double *sn, 
     long double *cs)
@@ -120,12 +123,12 @@
 	if (iy == 0)
 		*sn = x + v * (S1 + z * r);
 	else
-		*cs = x - ((z * (y / 2 - v * r) - y) - v * S1);
+		*sn = x - ((z * (y / 2 - v * r) - y) - v * S1);
 
 	hz = z / 2;
 	w = 1 - hz;
 	r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * (C6 + 
-	    z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * C11))))))))));
+	    z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * (C11+z*C12)))))))))));
 
 	*cs =  w + (((1 - w) - hz) + (z * r - x * y));
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/k_sinpi.h b/libm/upstream-freebsd/lib/msun/src/k_sinpi.h
new file mode 100644
index 0000000..66152ba
--- /dev/null
+++ b/libm/upstream-freebsd/lib/msun/src/k_sinpi.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2017 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.
+ */
+
+/*
+ * The basic kernel for x in [0,0.25].  To use the kernel for sin(x), the
+ * argument to __kernel_sinpi() must be multiplied by pi.
+ */
+
+static inline double
+__kernel_sinpi(double x)
+{
+	double_t hi, lo;
+
+	hi = (float)x;
+	lo = x - hi;
+	lo = lo * (pi_lo + pi_hi) + hi * pi_lo;
+	hi *= pi_hi;
+	_2sumF(hi, lo);
+	return (__kernel_sin(hi, lo, 1));
+}
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexp.c b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
index 2ef8ba1..a1f853e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexp.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
@@ -30,6 +30,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <complex.h>
+#include <float.h>
 #include <math.h>
 
 #include "math_private.h"
@@ -41,7 +42,7 @@
 double complex
 cexp(double complex z)
 {
-	double x, y, exp_x;
+	double c, exp_x, s, x, y;
 	uint32_t hx, hy, lx, ly;
 
 	x = creal(z);
@@ -55,8 +56,10 @@
 		return (CMPLX(exp(x), y));
 	EXTRACT_WORDS(hx, lx, x);
 	/* cexp(0 + I y) = cos(y) + I sin(y) */
-	if (((hx & 0x7fffffff) | lx) == 0)
-		return (CMPLX(cos(y), sin(y)));
+	if (((hx & 0x7fffffff) | lx) == 0) {
+		sincos(y, &s, &c);
+		return (CMPLX(c, s));
+	}
 
 	if (hy >= 0x7ff00000) {
 		if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
@@ -86,6 +89,11 @@
 		 *  -  x = NaN (spurious inexact exception from y)
 		 */
 		exp_x = exp(x);
-		return (CMPLX(exp_x * cos(y), exp_x * sin(y)));
+		sincos(y, &s, &c);
+		return (CMPLX(exp_x * c, exp_x * s));
 	}
 }
+
+#if (LDBL_MANT_DIG == 53)
+__weak_reference(cexp, cexpl);
+#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
index b815c99..d905b74 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
@@ -41,7 +41,7 @@
 float complex
 cexpf(float complex z)
 {
-	float x, y, exp_x;
+	float c, exp_x, s, x, y;
 	uint32_t hx, hy;
 
 	x = crealf(z);
@@ -55,8 +55,10 @@
 		return (CMPLXF(expf(x), y));
 	GET_FLOAT_WORD(hx, x);
 	/* cexp(0 + I y) = cos(y) + I sin(y) */
-	if ((hx & 0x7fffffff) == 0)
-		return (CMPLXF(cosf(y), sinf(y)));
+	if ((hx & 0x7fffffff) == 0) {
+		sincosf(y, &s, &c);
+		return (CMPLXF(c, s));
+	}
 
 	if (hy >= 0x7f800000) {
 		if ((hx & 0x7fffffff) != 0x7f800000) {
@@ -86,6 +88,7 @@
 		 *  -  x = NaN (spurious inexact exception from y)
 		 */
 		exp_x = expf(x);
-		return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y)));
+		sincosf(y, &s, &c);
+		return (CMPLXF(exp_x * c, exp_x * s));
 	}
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cosl.c b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
index 46a2e86..3d06648 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
@@ -39,12 +39,17 @@
 #include <ieeefp.h>
 #endif
 
+#include "fpmath.h"
 #include "math.h"
 #include "math_private.h"
 #if LDBL_MANT_DIG == 64
 #include "../ld80/e_rem_pio2l.h"
+static const union IEEEl2bits
+pio4u = LD80C(0xc90fdaa22168c235, -00001,  7.85398163397448309628e-01L);
+#define	pio4	(pio4u.e)
 #elif LDBL_MANT_DIG == 113
 #include "../ld128/e_rem_pio2l.h"
+long double pio4 =  7.85398163397448309615660845819875721e-1L;
 #else
 #error "Unsupported long double format"
 #endif
@@ -71,7 +76,7 @@
 	ENTERI();
 
 	/* Optimize the case where x is already within range. */
-	if (z.e < M_PI_4)
+	if (z.e < pio4)
 		RETURNI(__kernel_cosl(z.e, 0));
 
 	e0 = __ieee754_rem_pio2l(x, y);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cospi.c b/libm/upstream-freebsd/lib/msun/src/s_cospi.c
new file mode 100644
index 0000000..860219e
--- /dev/null
+++ b/libm/upstream-freebsd/lib/msun/src/s_cospi.c
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 2017 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.
+ */
+
+/**
+ * cospi(x) computes cos(pi*x) without multiplication by pi (almost).  First,
+ * note that cospi(-x) = cospi(x), so the algorithm considers only |x|.  The
+ * method used depends on the magnitude of x.
+ *
+ * 1. For small |x|, cospi(x) = 1 with FE_INEXACT raised where a sloppy
+ *    threshold is used.  The threshold is |x| < 0x1pN with N = -(P/2+M).
+ *    P is the precision of the floating-point type and M = 2 to 4.
+ *
+ * 2. For |x| < 1, argument reduction is not required and sinpi(x) is 
+ *    computed by calling a kernel that leverages the kernels for sin(x)
+ *    ans cos(x).  See k_sinpi.c and k_cospi.c for details.
+ *
+ * 3. For 1 <= |x| < 0x1p(P-1), argument reduction is required where
+ *    |x| = j0 + r with j0 an integer and the remainder r satisfies
+ *    0 <= r < 1.  With the given domain, a simplified inline floor(x)
+ *    is used.  Also, note the following identity
+ *
+ *    cospi(x) = cos(pi*(j0+r))
+ *             = cos(pi*j0) * cos(pi*r) - sin(pi*j0) * sin(pi*r)
+ *             = cos(pi*j0) * cos(pi*r)
+ *             = +-cospi(r)
+ *
+ *    If j0 is even, then cos(pi*j0) = 1. If j0 is odd, then cos(pi*j0) = -1.
+ *    cospi(r) is then computed via an appropriate kernel.
+ *
+ * 4. For |x| >= 0x1p(P-1), |x| is integral and cospi(x) = 1.
+ *
+ * 5. Special cases:
+ *
+ *    cospi(+-0) = 1.
+ *    cospi(n.5) = 0 for n an integer.
+ *    cospi(+-inf) = nan.  Raises the "invalid" floating-point exception.
+ *    cospi(nan) = nan.  Raises the "invalid" floating-point exception.
+ */
+
+#include <float.h>
+#include "math.h"
+#include "math_private.h"
+
+static const double
+pi_hi = 3.1415926814079285e+00,	/* 0x400921fb 0x58000000 */
+pi_lo =-2.7818135228334233e-08;	/* 0xbe5dde97 0x3dcb3b3a */
+
+#include "k_cospi.h"
+#include "k_sinpi.h"
+
+volatile static const double vzero = 0;
+
+double
+cospi(double x)
+{
+	double ax, c;
+	uint32_t hx, ix, j0, lx;
+
+	EXTRACT_WORDS(hx, lx, x);
+	ix = hx & 0x7fffffff;
+	INSERT_WORDS(ax, ix, lx);
+
+	if (ix < 0x3ff00000) {			/* |x| < 1 */
+		if (ix < 0x3fd00000) {		/* |x| < 0.25 */
+			if (ix < 0x3e200000) {	/* |x| < 0x1p-29 */
+				if ((int)ax == 0)
+					return (1);
+			}
+			return (__kernel_cospi(ax));
+		}
+
+		if (ix < 0x3fe00000)		/* |x| < 0.5 */
+			c = __kernel_sinpi(0.5 - ax);
+		else if (ix < 0x3fe80000){	/* |x| < 0.75 */
+			if (ax == 0.5)
+				return (0);
+			c = -__kernel_sinpi(ax - 0.5);
+		} else
+			c = -__kernel_cospi(1 - ax);
+		return (c);
+	}
+
+	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);
+
+		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);
+			else 
+				c = __kernel_sinpi(0.5 - ax);
+		} else {
+			if (ix < 0x3fe80000) {	/* |x| < 0.75 */
+				if (ax == 0.5)
+					return (0);
+				c = -__kernel_sinpi(ax - 0.5);
+			} else
+				c = -__kernel_cospi(1 - ax);
+		}
+
+		if (j0 > 30)
+			x -= 0x1p30;
+		j0 = (uint32_t)x;
+		return (j0 & 1 ? -c : c);
+	}
+
+	if (ix >= 0x7f800000)
+		return (vzero / vzero);
+
+	/*
+	 * |x| >= 0x1p52 is always an even integer, so return 1.
+	 */
+	return (1);
+}
+
+#if LDBL_MANT_DIG == 53
+__weak_reference(cospi, cospil);
+#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
index 88afeb5..e5840a1 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
@@ -111,11 +111,13 @@
 	}
 
 	/*
-	 * ctanh(x + I NaN) = d(NaN) + I d(NaN)
-	 * ctanh(x +- I Inf) = dNaN + I dNaN
+	 * ctanh(+-0 + i NAN) = +-0 + i NaN
+	 * ctanh(+-0 +- i Inf) = +-0 + i NaN
+	 * ctanh(x + i NAN) = NaN + i NaN
+	 * ctanh(x +- i Inf) = NaN + i NaN
 	 */
 	if (!isfinite(y))
-		return (CMPLX(y - y, y - y));
+		return (CMPLX(x ? y - y : x, y - y));
 
 	/*
 	 * ctanh(+-huge +- I y) ~= +-1 +- I 2sin(2y)/exp(2x), using the
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
index d2bd0b6..c46f86d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
@@ -61,7 +61,7 @@
 	}
 
 	if (!isfinite(y))
-		return (CMPLXF(y - y, y - y));
+		return (CMPLXF(ix ? y - y : x, y - y));
 
 	if (ix >= 0x41300000) {	/* |x| >= 11 */
 		float exp_mx = expf(-fabsf(x));
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fma.c b/libm/upstream-freebsd/lib/msun/src/s_fma.c
index 41a6424..95cffd0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fma.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fma.c
@@ -35,6 +35,13 @@
 
 #include "math_private.h"
 
+#ifdef USE_BUILTIN_FMA
+double
+fma(double x, double y, double z)
+{
+	return (__builtin_fma(x, y, z));
+}
+#else
 /*
  * A struct dd represents a floating-point number with twice the precision
  * of a double.  We maintain the invariant that "hi" stores the 53 high-order
@@ -284,6 +291,7 @@
 	else
 		return (add_and_denormalize(r.hi, adj, spread));
 }
+#endif /* !USE_BUILTIN_FMA */
 
 #if (LDBL_MANT_DIG == 53)
 __weak_reference(fma, fmal);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
index 389cf1b..4591cc2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
@@ -34,6 +34,13 @@
 #include "math.h"
 #include "math_private.h"
 
+#ifdef USE_BUILTIN_FMAF
+float
+fmaf(float x, float y, float z)
+{
+	return (__builtin_fmaf(x, y, z));
+}
+#else
 /*
  * Fused multiply-add: Compute x * y + z with a single rounding error.
  *
@@ -69,3 +76,4 @@
 		SET_LOW_WORD(adjusted_result, lr + 1);
 	return (adjusted_result);
 }
+#endif /* !USE_BUILTIN_FMAF */
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmax.c b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
index 0c234bc..b53b1e6 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmax.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
@@ -34,6 +34,13 @@
 
 #include "fpmath.h"
 
+#ifdef USE_BUILTIN_FMAX
+double
+fmax(double x, double y)
+{
+	return (__builtin_fmax(x, y));
+}
+#else
 double
 fmax(double x, double y)
 {
@@ -54,6 +61,7 @@
 
 	return (x > y ? x : y);
 }
+#endif
 
 #if (LDBL_MANT_DIG == 53)
 __weak_reference(fmax, fmaxl);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
index 8e9d1ba..8d3d14f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
@@ -33,6 +33,13 @@
 
 #include "fpmath.h"
 
+#ifdef USE_BUILTIN_FMAXF
+float
+fmaxf(float x, float y)
+{
+	return (__builtin_fmaxf(x, y));
+}
+#else
 float
 fmaxf(float x, float y)
 {
@@ -53,3 +60,4 @@
 
 	return (x > y ? x : y);
 }
+#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmin.c b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
index d7f24c1..53f36c1 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmin.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
@@ -34,6 +34,13 @@
 
 #include "fpmath.h"
 
+#ifdef USE_BUILTIN_FMIN
+double
+fmin(double x, double y)
+{
+	return (__builtin_fmin(x, y));
+}
+#else
 double
 fmin(double x, double y)
 {
@@ -54,6 +61,7 @@
 
 	return (x < y ? x : y);
 }
+#endif
 
 #if (LDBL_MANT_DIG == 53)
 __weak_reference(fmin, fminl);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminf.c b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
index 2583167..58b6a48 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
@@ -33,6 +33,13 @@
 
 #include "fpmath.h"
 
+#ifdef USE_BUILTIN_FMINF
+float
+fminf(float x, float y)
+{
+	return (__builtin_fminf(x, y));
+}
+#else
 float
 fminf(float x, float y)
 {
@@ -53,3 +60,4 @@
 
 	return (x < y ? x : y);
 }
+#endif
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lround.c b/libm/upstream-freebsd/lib/msun/src/s_lround.c
index 66d9183..1dd8e69 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lround.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lround.c
@@ -49,9 +49,11 @@
  * that everything is in range.  At compile time, INRANGE(x) should reduce to
  * two floating-point comparisons in the former case, or TRUE otherwise.
  */
+static const type type_min = (type)DTYPE_MIN;
+static const type type_max = (type)DTYPE_MAX;
 static const type dtype_min = (type)DTYPE_MIN - 0.5;
 static const type dtype_max = (type)DTYPE_MAX + 0.5;
-#define	INRANGE(x)	(dtype_max - (type)DTYPE_MAX != 0.5 || \
+#define	INRANGE(x)	(dtype_max - type_max != 0.5 || \
 			 ((x) > dtype_min && (x) < dtype_max))
 
 dtype
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbn.c b/libm/upstream-freebsd/lib/msun/src/s_scalbn.c
index b048b05..2d4f7a3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbn.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbn.c
@@ -1,66 +1,47 @@
-/* @(#)s_scalbn.c 5.1 93/09/24 */
 /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005-2020 Rich Felker, et al.
  *
- * 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.
- * ====================================================
+ * SPDX-License-Identifier: MIT
+ *
+ * Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
+ * for all contributors to musl.
  */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * scalbn (double x, int n)
- * scalbn(x,n) returns x* 2**n  computed by  exponent
- * manipulation rather than by actually performing an
- * exponentiation or a multiplication.
- */
-
 #include <float.h>
+#include <math.h>
+#include <stdint.h>
 
-#include "math.h"
-#include "math_private.h"
-
-static const double
-two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
-huge   = 1.0e+300,
-tiny   = 1.0e-300;
-
-double
-scalbn (double x, int n)
+double scalbn(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*/
+	union {double f; uint64_t i;} u;
+	double_t y = x;
+
+	if (n > 1023) {
+		y *= 0x1p1023;
+		n -= 1023;
+		if (n > 1023) {
+			y *= 0x1p1023;
+			n -= 1023;
+			if (n > 1023)
+				n = 1023;
+		}
+	} else if (n < -1022) {
+		/* make sure final n < -53 to avoid double
+		   rounding in the subnormal range */
+		y *= 0x1p-1022 * 0x1p53;
+		n += 1022 - 53;
+		if (n < -1022) {
+			y *= 0x1p-1022 * 0x1p53;
+			n += 1022 - 53;
+			if (n < -1022)
+				n = -1022;
+		}
 	}
-        k += 54;				/* subnormal result */
-	SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
-        return x*twom54;
+	u.i = (uint64_t)(0x3ff+n)<<52;
+	x = y * u.f;
+	return x;
 }
 
-#if (LDBL_MANT_DIG == 53)
+#if (LDBL_MANT_DIG == 53) && !defined(scalbn)
 __weak_reference(scalbn, ldexpl);
 __weak_reference(scalbn, scalbnl);
 #endif
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbnf.c b/libm/upstream-freebsd/lib/msun/src/s_scalbnf.c
index 21d001c..8cf1e01 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbnf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbnf.c
@@ -1,57 +1,41 @@
-/* s_scalbnf.c -- float version of s_scalbn.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
 /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005-2020 Rich Felker, et al.
  *
- * 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.
- * ====================================================
+ * SPDX-License-Identifier: MIT
+ *
+ * Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
+ * for all contributors to musl.
  */
+#include <math.h>
+#include <stdint.h>
 
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "math.h"
-#include "math_private.h"
-
-static const float
-two25   =  3.355443200e+07,	/* 0x4c000000 */
-twom25  =  2.9802322388e-08,	/* 0x33000000 */
-huge   = 1.0e+30,
-tiny   = 1.0e-30;
-
-float
-scalbnf (float x, int n)
+float scalbnf(float x, int n)
 {
-	int32_t k,ix;
-	GET_FLOAT_WORD(ix,x);
-        k = (ix&0x7f800000)>>23;		/* extract exponent */
-        if (k==0) {				/* 0 or subnormal x */
-            if ((ix&0x7fffffff)==0) return x; /* +-0 */
-	    x *= two25;
-	    GET_FLOAT_WORD(ix,x);
-	    k = ((ix&0x7f800000)>>23) - 25;
-            if (n< -50000) return tiny*x; 	/*underflow*/
-	    }
-        if (k==0xff) return x+x;		/* NaN or Inf */
-        k = k+n;
-        if (k >  0xfe) return huge*copysignf(huge,x); /* overflow  */
-        if (k > 0) 				/* normal result */
-	    {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
-        if (k <= -25) {
-            if (n > 50000) 	/* in case integer overflow in n+k */
-		return huge*copysignf(huge,x);	/*overflow*/
-	    else
-		return tiny*copysignf(tiny,x);	/*underflow*/
+	union {float f; uint32_t i;} u;
+	float_t y = x;
+
+	if (n > 127) {
+		y *= 0x1p127f;
+		n -= 127;
+		if (n > 127) {
+			y *= 0x1p127f;
+			n -= 127;
+			if (n > 127)
+				n = 127;
+		}
+	} else if (n < -126) {
+		y *= 0x1p-126f * 0x1p24f;
+		n += 126 - 24;
+		if (n < -126) {
+			y *= 0x1p-126f * 0x1p24f;
+			n += 126 - 24;
+			if (n < -126)
+				n = -126;
+		}
 	}
-        k += 25;				/* subnormal result */
-	SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
-        return x*twom25;
+	u.i = (uint32_t)(0x7f+n)<<23;
+	x = y * u.f;
+	return x;
 }
 
 __strong_reference(scalbnf, ldexpf);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbnl.c b/libm/upstream-freebsd/lib/msun/src/s_scalbnl.c
index 28b0cf9..6044c1b 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbnl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbnl.c
@@ -1,71 +1,49 @@
-/* @(#)s_scalbn.c 5.1 93/09/24 */
 /*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005-2020 Rich Felker, et al.
  *
- * 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.
- * ====================================================
+ * SPDX-License-Identifier: MIT
+ *
+ * Please see https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
+ * for all contributors to musl.
  */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
+#include <math.h>
+#include <float.h>
+#include "math_private.h"
+#include "fpmath.h"
 /*
  * scalbnl (long double x, int n)
  * scalbnl(x,n) returns x* 2**n  computed by  exponent
  * manipulation rather than by actually performing an
  * exponentiation or a multiplication.
  */
-
-/*
- * We assume that a long double has a 15-bit exponent.  On systems
- * where long double is the same as double, scalbnl() is an alias
- * for scalbn(), so we don't use this routine.
- */
-
-#include <float.h>
-#include <math.h>
-
-#include "fpmath.h"
-
-#if LDBL_MAX_EXP != 0x4000
-#error "Unsupported long double format"
-#endif
-
-static const long double
-huge = 0x1p16000L,
-tiny = 0x1p-16000L;
-
-long double
-scalbnl (long double x, int n)
+#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
+long double scalbnl(long double x, int n)
 {
 	union IEEEl2bits u;
-	int k;
-	u.e = x;
-        k = u.bits.exp;				/* extract exponent */
-        if (k==0) {				/* 0 or subnormal x */
-            if ((u.bits.manh|u.bits.manl)==0) return x;	/* +-0 */
-	    u.e *= 0x1p+128;
-	    k = u.bits.exp - 128;
-            if (n< -50000) return tiny*x; 	/*underflow*/
-	    }
-        if (k==0x7fff) return x+x;		/* NaN or Inf */
-        k = k+n;
-        if (k >= 0x7fff) return huge*copysignl(huge,x); /* overflow  */
-        if (k > 0) 				/* normal result */
-	    {u.bits.exp = k; return u.e;}
-        if (k <= -128) {
-            if (n > 50000) 	/* in case integer overflow in n+k */
-		return huge*copysign(huge,x);	/*overflow*/
-	    else
-		return tiny*copysign(tiny,x); 	/*underflow*/
-	}
-        k += 128;				/* subnormal result */
-	u.bits.exp = k;
-        return u.e*0x1p-128;
-}
 
+	if (n > 16383) {
+		x *= 0x1p16383L;
+		n -= 16383;
+		if (n > 16383) {
+			x *= 0x1p16383L;
+			n -= 16383;
+			if (n > 16383)
+				n = 16383;
+		}
+	} else if (n < -16382) {
+		x *= 0x1p-16382L * 0x1p113L;
+		n += 16382 - 113;
+		if (n < -16382) {
+			x *= 0x1p-16382L * 0x1p113L;
+			n += 16382 - 113;
+			if (n < -16382)
+				n = -16382;
+		}
+	}
+	u.e = 1.0;
+	u.xbits.expsign = 0x3fff + n;
+	return x * u.e;
+}
 __strong_reference(scalbnl, ldexpl);
+#endif
+
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sincosl.c b/libm/upstream-freebsd/lib/msun/src/s_sincosl.c
index aef36c2..3dd3457 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sincosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sincosl.c
@@ -50,11 +50,10 @@
 sincosl(long double x, long double *sn, long double *cs)
 {
 	union IEEEl2bits z;
-	int e0, sgn;
+	int e0;
 	long double y[2];
 
 	z.e = x;
-	sgn = z.bits.sign;
 	z.bits.sign = 0;
 
 	ENTERV();
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinpi.c b/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
new file mode 100644
index 0000000..858459a
--- /dev/null
+++ b/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2017 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.
+ */
+
+/**
+ * sinpi(x) computes sin(pi*x) without multiplication by pi (almost).  First,
+ * note that sinpi(-x) = -sinpi(x), so the algorithm considers only |x| and
+ * includes reflection symmetry by considering the sign of x on output.  The
+ * method used depends on the magnitude of x.
+ *
+ * 1. For small |x|, sinpi(x) = pi * x where a sloppy threshold is used.  The
+ *    threshold is |x| < 0x1pN with N = -(P/2+M).  P is the precision of the
+ *    floating-point type and M = 2 to 4.  To achieve high accuracy, pi is 
+ *    decomposed into high and low parts with the high part containing a
+ *    number of trailing zero bits.  x is also split into high and low parts.
+ *
+ * 2. For |x| < 1, argument reduction is not required and sinpi(x) is 
+ *    computed by calling a kernel that leverages the kernels for sin(x)
+ *    ans cos(x).  See k_sinpi.c and k_cospi.c for details.
+ *
+ * 3. For 1 <= |x| < 0x1p(P-1), argument reduction is required where
+ *    |x| = j0 + r with j0 an integer and the remainder r satisfies
+ *    0 <= r < 1.  With the given domain, a simplified inline floor(x)
+ *    is used.  Also, note the following identity
+ *
+ *    sinpi(x) = sin(pi*(j0+r))
+ *             = sin(pi*j0) * cos(pi*r) + cos(pi*j0) * sin(pi*r)
+ *             = cos(pi*j0) * sin(pi*r)
+ *             = +-sinpi(r)
+ *
+ *    If j0 is even, then cos(pi*j0) = 1. If j0 is odd, then cos(pi*j0) = -1.
+ *    sinpi(r) is then computed via an appropriate kernel.
+ *
+ * 4. For |x| >= 0x1p(P-1), |x| is integral and sinpi(x) = copysign(0,x).
+ *
+ * 5. Special cases:
+ *
+ *    sinpi(+-0) = +-0
+ *    sinpi(+-n) = +-0, for positive integers n.
+ *    sinpi(+-inf) = nan.  Raises the "invalid" floating-point exception.
+ *    sinpi(nan) = nan.  Raises the "invalid" floating-point exception.
+ */
+
+#include <float.h>
+#include "math.h"
+#include "math_private.h"
+
+static const double
+pi_hi = 3.1415926814079285e+00,	/* 0x400921fb 0x58000000 */
+pi_lo =-2.7818135228334233e-08;	/* 0xbe5dde97 0x3dcb3b3a */
+
+#include "k_cospi.h"
+#include "k_sinpi.h"
+
+volatile static const double vzero = 0;
+
+double
+sinpi(double x)
+{
+	double ax, hi, lo, s;
+	uint32_t hx, ix, j0, lx;
+
+	EXTRACT_WORDS(hx, lx, x);
+	ix = hx & 0x7fffffff;
+	INSERT_WORDS(ax, ix, lx);
+
+	if (ix < 0x3ff00000) {			/* |x| < 1 */
+		if (ix < 0x3fd00000) {		/* |x| < 0.25 */
+			if (ix < 0x3e200000) {	/* |x| < 0x1p-29 */
+				if (x == 0)
+					return (x);
+				/*
+				 * To avoid issues with subnormal values,
+				 * scale the computation and rescale on 
+				 * return.
+				 */
+				INSERT_WORDS(hi, hx, 0);
+				hi *= 0x1p53;
+				lo = x * 0x1p53 - hi;
+				s = (pi_lo + pi_hi) * lo + pi_lo * hi +
+				    pi_hi * hi;
+				return (s * 0x1p-53);
+			}
+
+			s = __kernel_sinpi(ax);
+			return ((hx & 0x80000000) ? -s : s);
+		}
+
+		if (ix < 0x3fe00000)		/* |x| < 0.5 */
+			s = __kernel_cospi(0.5 - ax);
+		else if (ix < 0x3fe80000)	/* |x| < 0.75 */
+			s = __kernel_cospi(ax - 0.5);
+		else
+			s = __kernel_sinpi(1 - ax);
+		return ((hx & 0x80000000) ? -s : s);
+	}
+
+	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);
+
+		ax -= x;
+		EXTRACT_WORDS(ix, lx, ax);
+
+		if (ix == 0)
+			s = 0;
+		else {
+			if (ix < 0x3fe00000) {		/* |x| < 0.5 */
+				if (ix < 0x3fd00000)	/* |x| < 0.25 */
+					s = __kernel_sinpi(ax);
+				else 
+					s = __kernel_cospi(0.5 - ax);
+			} else {
+				if (ix < 0x3fe80000)	/* |x| < 0.75 */
+					s = __kernel_cospi(ax - 0.5);
+				else
+					s = __kernel_sinpi(1 - ax);
+			}
+
+			if (j0 > 30)
+				x -= 0x1p30;
+			j0 = (uint32_t)x;
+			if (j0 & 1) s = -s;
+		}
+
+		return ((hx & 0x80000000) ? -s : s);
+	}
+
+	if (ix >= 0x7f800000)
+		return (vzero / vzero);
+
+	/*
+	 * |x| >= 0x1p52 is always an integer, so return +-0.
+	 */
+	return (copysign(0, x));
+}
+
+#if LDBL_MANT_DIG == 53
+__weak_reference(sinpi, sinpil);
+#endif
diff --git a/linker/Android.bp b/linker/Android.bp
index 4a5bf44..d5e7367 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -28,16 +28,11 @@
     name: "linker_wrapper",
     host_supported: true,
     device_supported: false,
+    enabled: false,
     target: {
         linux_bionic: {
             enabled: true,
         },
-        linux_glibc: {
-            enabled: false,
-        },
-        darwin: {
-            enabled: false,
-        },
     },
 
     cflags: [
@@ -55,22 +50,17 @@
     ],
     arch: {
         arm64: {
-            srcs: ["arch/arm64/begin.S"],
+            srcs: ["arch/arm64/linker_wrapper_begin.S"],
         },
         x86_64: {
-            srcs: ["arch/x86_64/begin.S"],
+            srcs: ["arch/x86_64/linker_wrapper_begin.S"],
         },
     },
 
-    prefix_symbols: "__dlwrap_",
-
     header_libs: ["libc_headers"],
 
     // We need to access Bionic private headers in the linker.
     include_dirs: ["bionic/libc"],
-
-    // b/182338959
-    bazel_module: { bp2build_available: false },
 }
 
 // ========================================================
@@ -374,34 +364,9 @@
                 "liblinker_debuggerd_stub",
             ],
         },
-        android_arm64: {
-            pgo: {
-                profile_file: "bionic/linker_arm_arm64.profdata",
-            },
-        },
-        android_arm: {
-            pgo: {
-                profile_file: "bionic/linker_arm_arm64.profdata",
-            },
-        },
-        android_x86_64: {
-            pgo: {
-                profile_file: "bionic/linker_x86_x86_64.profdata",
-            },
-        },
-        android_x86: {
-            pgo: {
-                profile_file: "bionic/linker_x86_x86_64.profdata",
-            },
-        },
     },
 
-    lto: {
-        never: true,
-    },
-    pgo: {
-        sampling: true,
-    },
+    afdo: true,
 }
 
 // ========================================================
@@ -411,7 +376,6 @@
 sh_binary {
     name: "ldd",
     src: "ldd.sh",
-    bazel_module: { bp2build_available: true },
 }
 
 // Used to generate binaries that can be backed by transparent hugepages.
@@ -495,6 +459,7 @@
 
 cc_test {
     name: "linker-unit-tests",
+    test_suites: ["device-tests"],
 
     cflags: [
         "-g",
diff --git a/linker/arch/arm64/linker_wrapper_begin.S b/linker/arch/arm64/linker_wrapper_begin.S
new file mode 100644
index 0000000..90c53a2
--- /dev/null
+++ b/linker/arch/arm64/linker_wrapper_begin.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define _start __dlwrap__start
+#include "begin.S"
diff --git a/linker/arch/arm_neon/linker_gnu_hash_neon.cpp b/linker/arch/arm_neon/linker_gnu_hash_neon.cpp
index 11cf5a3..159c66e 100644
--- a/linker/arch/arm_neon/linker_gnu_hash_neon.cpp
+++ b/linker/arch/arm_neon/linker_gnu_hash_neon.cpp
@@ -81,6 +81,8 @@
 //      return h;
 //    }
 //
+// This does an within-alignment out-of-bounds read for performance reasons.
+__attribute__((no_sanitize("hwaddress")))
 std::pair<uint32_t, uint32_t> calculate_gnu_hash_neon(const char* name) {
 
   // The input string may be misaligned by 0-7 bytes (K). This function loads the first aligned
diff --git a/linker/arch/x86_64/linker_wrapper_begin.S b/linker/arch/x86_64/linker_wrapper_begin.S
new file mode 100644
index 0000000..90c53a2
--- /dev/null
+++ b/linker/arch/x86_64/linker_wrapper_begin.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define _start __dlwrap__start
+#include "begin.S"
diff --git a/linker/linked_list.h b/linker/linked_list.h
index b8a8f0e..2741008 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -79,76 +79,89 @@
   typedef LinkedListIterator<T> iterator;
   typedef T* value_type;
 
-  LinkedList() : head_(nullptr), tail_(nullptr) {}
+  // Allocating the head/tail fields separately from the LinkedList struct saves memory in the
+  // Zygote (e.g. because adding an soinfo to a namespace doesn't dirty the page containing the
+  // soinfo).
+  struct LinkedListHeader {
+    LinkedListEntry<T>* head;
+    LinkedListEntry<T>* tail;
+  };
+
+  // The allocator returns a LinkedListEntry<T>* but we want to treat it as a LinkedListHeader
+  // struct instead.
+  static_assert(sizeof(LinkedListHeader) == sizeof(LinkedListEntry<T>));
+  static_assert(alignof(LinkedListHeader) == alignof(LinkedListEntry<T>));
+
+  constexpr LinkedList() : header_(nullptr) {}
   ~LinkedList() {
     clear();
+    if (header_ != nullptr) {
+      Allocator::free(reinterpret_cast<LinkedListEntry<T>*>(header_));
+    }
   }
 
   LinkedList(LinkedList&& that) noexcept {
-    this->head_ = that.head_;
-    this->tail_ = that.tail_;
-    that.head_ = that.tail_ = nullptr;
+    this->header_ = that.header_;
+    that.header_ = nullptr;
+  }
+
+  bool empty() const {
+    return header_ == nullptr || header_->head == nullptr;
   }
 
   void push_front(T* const element) {
+    alloc_header();
     LinkedListEntry<T>* new_entry = Allocator::alloc();
-    new_entry->next = head_;
+    new_entry->next = header_->head;
     new_entry->element = element;
-    head_ = new_entry;
-    if (tail_ == nullptr) {
-      tail_ = new_entry;
+    header_->head = new_entry;
+    if (header_->tail == nullptr) {
+      header_->tail = new_entry;
     }
   }
 
   void push_back(T* const element) {
+    alloc_header();
     LinkedListEntry<T>* new_entry = Allocator::alloc();
     new_entry->next = nullptr;
     new_entry->element = element;
-    if (tail_ == nullptr) {
-      tail_ = head_ = new_entry;
+    if (header_->tail == nullptr) {
+      header_->tail = header_->head = new_entry;
     } else {
-      tail_->next = new_entry;
-      tail_ = new_entry;
+      header_->tail->next = new_entry;
+      header_->tail = new_entry;
     }
   }
 
   T* pop_front() {
-    if (head_ == nullptr) {
-      return nullptr;
-    }
+    if (empty()) return nullptr;
 
-    LinkedListEntry<T>* entry = head_;
+    LinkedListEntry<T>* entry = header_->head;
     T* element = entry->element;
-    head_ = entry->next;
+    header_->head = entry->next;
     Allocator::free(entry);
 
-    if (head_ == nullptr) {
-      tail_ = nullptr;
+    if (header_->head == nullptr) {
+      header_->tail = nullptr;
     }
 
     return element;
   }
 
   T* front() const {
-    if (head_ == nullptr) {
-      return nullptr;
-    }
-
-    return head_->element;
+    return empty() ? nullptr : header_->head->element;
   }
 
   void clear() {
-    while (head_ != nullptr) {
-      LinkedListEntry<T>* p = head_;
-      head_ = head_->next;
+    if (empty()) return;
+
+    while (header_->head != nullptr) {
+      LinkedListEntry<T>* p = header_->head;
+      header_->head = header_->head->next;
       Allocator::free(p);
     }
 
-    tail_ = nullptr;
-  }
-
-  bool empty() {
-    return (head_ == nullptr);
+    header_->tail = nullptr;
   }
 
   template<typename F>
@@ -161,7 +174,7 @@
 
   template<typename F>
   bool visit(F action) const {
-    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+    for (LinkedListEntry<T>* e = head(); e != nullptr; e = e->next) {
       if (!action(e->element)) {
         return false;
       }
@@ -171,17 +184,18 @@
 
   template<typename F>
   void remove_if(F predicate) {
-    for (LinkedListEntry<T>* e = head_, *p = nullptr; e != nullptr;) {
+    if (empty()) return;
+    for (LinkedListEntry<T>* e = header_->head, *p = nullptr; e != nullptr;) {
       if (predicate(e->element)) {
         LinkedListEntry<T>* next = e->next;
         if (p == nullptr) {
-          head_ = next;
+          header_->head = next;
         } else {
           p->next = next;
         }
 
-        if (tail_ == e) {
-          tail_ = p;
+        if (header_->tail == e) {
+          header_->tail = p;
         }
 
         Allocator::free(e);
@@ -202,7 +216,7 @@
 
   template<typename F>
   T* find_if(F predicate) const {
-    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+    for (LinkedListEntry<T>* e = head(); e != nullptr; e = e->next) {
       if (predicate(e->element)) {
         return e->element;
       }
@@ -212,7 +226,7 @@
   }
 
   iterator begin() const {
-    return iterator(head_);
+    return iterator(head());
   }
 
   iterator end() const {
@@ -220,7 +234,7 @@
   }
 
   iterator find(T* value) const {
-    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+    for (LinkedListEntry<T>* e = head(); e != nullptr; e = e->next) {
       if (e->element == value) {
         return iterator(e);
       }
@@ -231,7 +245,7 @@
 
   size_t copy_to_array(T* array[], size_t array_length) const {
     size_t sz = 0;
-    for (LinkedListEntry<T>* e = head_; sz < array_length && e != nullptr; e = e->next) {
+    for (LinkedListEntry<T>* e = head(); sz < array_length && e != nullptr; e = e->next) {
       array[sz++] = e->element;
     }
 
@@ -239,7 +253,7 @@
   }
 
   bool contains(const T* el) const {
-    for (LinkedListEntry<T>* e = head_; e != nullptr; e = e->next) {
+    for (LinkedListEntry<T>* e = head(); e != nullptr; e = e->next) {
       if (e->element == el) {
         return true;
       }
@@ -260,7 +274,17 @@
   }
 
  private:
-  LinkedListEntry<T>* head_;
-  LinkedListEntry<T>* tail_;
+  void alloc_header() {
+    if (header_ == nullptr) {
+      header_ = reinterpret_cast<LinkedListHeader*>(Allocator::alloc());
+      header_->head = header_->tail = nullptr;
+    }
+  }
+
+  LinkedListEntry<T>* head() const {
+    return header_ != nullptr ? header_->head : nullptr;
+  }
+
+  LinkedListHeader* header_;
   DISALLOW_COPY_AND_ASSIGN(LinkedList);
 };
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 3488f5c..c6588d2 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3351,18 +3351,15 @@
 }
 
 // Given an `executable_path` starting with "/apex/<name>/bin/, return
-// "/linkerconfig/<name>/ld.config.txt" (or "/apex/<name>/etc/ld.config.txt", if
-// the former does not exist).
+// "/linkerconfig/<name>/ld.config.txt", which is the auto-generated config file for the APEX by the
+// linkerconfig tool.
 static std::string get_ld_config_file_apex_path(const char* executable_path) {
   std::vector<std::string> paths = android::base::Split(executable_path, "/");
   if (paths.size() >= 5 && paths[1] == "apex" && paths[3] == "bin") {
-    // Check auto-generated ld.config.txt first
     std::string generated_apex_config = "/linkerconfig/" + paths[2] + "/ld.config.txt";
     if (file_exists(generated_apex_config.c_str())) {
       return generated_apex_config;
     }
-
-    return std::string("/apex/") + paths[2] + "/etc/ld.config.txt";
   }
   return "";
 }
diff --git a/linker/linker.h b/linker/linker.h
index 74bdcc7..a803424 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -51,7 +51,7 @@
 #define ELFW(what) ELF32_ ## what
 #endif
 
-#define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE | DF_1_PIE)
+#define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE | DF_1_PIE | DF_1_ORIGIN)
 
 // Class used construct version dependency graph.
 class VersionTracker {
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index 5b68b1d..60e5e1c 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -31,6 +31,7 @@
 #include <inttypes.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 #include <sys/prctl.h>
 #include <unistd.h>
 
@@ -39,11 +40,6 @@
 static constexpr size_t kAllocateSize = PAGE_SIZE * 100;
 static_assert(kAllocateSize % PAGE_SIZE == 0, "Invalid kAllocateSize.");
 
-// the multiplier should be power of 2
-static constexpr size_t round_up(size_t size, size_t multiplier) {
-  return (size + (multiplier - 1)) & ~(multiplier-1);
-}
-
 struct LinkerBlockAllocatorPage {
   LinkerBlockAllocatorPage* next;
   uint8_t bytes[kAllocateSize - 16] __attribute__((aligned(16)));
@@ -54,13 +50,14 @@
   size_t num_free_blocks;
 };
 
+static_assert(kBlockSizeAlign >= alignof(FreeBlockInfo));
+static_assert(kBlockSizeMin == sizeof(FreeBlockInfo));
+
 LinkerBlockAllocator::LinkerBlockAllocator(size_t block_size)
-  : block_size_(
-      round_up(block_size < sizeof(FreeBlockInfo) ? sizeof(FreeBlockInfo) : block_size, 16)),
-    page_list_(nullptr),
-    free_block_list_(nullptr),
-    allocated_(0)
-{}
+    : block_size_(__BIONIC_ALIGN(MAX(block_size, kBlockSizeMin), kBlockSizeAlign)),
+      page_list_(nullptr),
+      free_block_list_(nullptr),
+      allocated_(0) {}
 
 void* LinkerBlockAllocator::alloc() {
   if (free_block_list_ == nullptr) {
diff --git a/linker/linker_block_allocator.h b/linker/linker_block_allocator.h
index 8ae4094..32656c7 100644
--- a/linker/linker_block_allocator.h
+++ b/linker/linker_block_allocator.h
@@ -33,6 +33,9 @@
 
 #include <android-base/macros.h>
 
+static constexpr size_t kBlockSizeAlign = sizeof(void*);
+static constexpr size_t kBlockSizeMin = sizeof(void*) * 2;
+
 struct LinkerBlockAllocatorPage;
 
 /*
diff --git a/linker/linker_block_allocator_test.cpp b/linker/linker_block_allocator_test.cpp
index 6fb2b26..56fbee8 100644
--- a/linker/linker_block_allocator_test.cpp
+++ b/linker/linker_block_allocator_test.cpp
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 
 #include <gtest/gtest.h>
 
@@ -44,12 +45,16 @@
 };
 
 /*
- * this one has size below allocator cap which is 2*sizeof(void*)
+ * this one has size below kBlockSizeAlign
  */
 struct test_struct_small {
-  char str[5];
+  char str[3];
 };
 
+struct test_struct_max_align {
+  char str[16];
+} __attribute__((aligned(16)));
+
 /*
  * 1009 byte struct (1009 is prime)
  */
@@ -58,54 +63,49 @@
 };
 
 static size_t kPageSize = sysconf(_SC_PAGE_SIZE);
-};
 
-TEST(linker_allocator, test_nominal) {
-  LinkerTypeAllocator<test_struct_nominal> allocator;
+template <typename Element>
+void linker_allocator_test_helper() {
+  LinkerTypeAllocator<Element> allocator;
 
-  test_struct_nominal* ptr1 = allocator.alloc();
+  Element* ptr1 = allocator.alloc();
   ASSERT_TRUE(ptr1 != nullptr);
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
-  test_struct_nominal* ptr2 = allocator.alloc();
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % kBlockSizeAlign);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % alignof(Element));
+  Element* ptr2 = allocator.alloc();
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % kBlockSizeAlign);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % alignof(Element));
   ASSERT_TRUE(ptr2 != nullptr);
-  // they should be next to each other.
-  ASSERT_EQ(reinterpret_cast<uint8_t*>(ptr1)+16, reinterpret_cast<uint8_t*>(ptr2));
 
-  ptr1->value = 42;
+  // they should be next to each other.
+  size_t dist = __BIONIC_ALIGN(MAX(sizeof(Element), kBlockSizeMin), kBlockSizeAlign);
+  ASSERT_EQ(reinterpret_cast<uint8_t*>(ptr1) + dist, reinterpret_cast<uint8_t*>(ptr2));
 
   allocator.free(ptr1);
   allocator.free(ptr2);
 }
 
+};  // anonymous namespace
+
+TEST(linker_allocator, test_nominal) {
+  linker_allocator_test_helper<test_struct_nominal>();
+}
+
 TEST(linker_allocator, test_small) {
-  LinkerTypeAllocator<test_struct_small> allocator;
+  linker_allocator_test_helper<test_struct_small>();
+}
 
-  char* ptr1 = reinterpret_cast<char*>(allocator.alloc());
-  char* ptr2 = reinterpret_cast<char*>(allocator.alloc());
-
-  ASSERT_TRUE(ptr1 != nullptr);
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
-  ASSERT_TRUE(ptr2 != nullptr);
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
-  ASSERT_EQ(ptr1+16, ptr2); // aligned to 16
+TEST(linker_allocator, test_max_align) {
+  linker_allocator_test_helper<test_struct_max_align>();
 }
 
 TEST(linker_allocator, test_larger) {
+  linker_allocator_test_helper<test_struct_larger>();
+
   LinkerTypeAllocator<test_struct_larger> allocator;
 
-  test_struct_larger* ptr1 = allocator.alloc();
-  test_struct_larger* ptr2 = allocator.alloc();
-
-  ASSERT_TRUE(ptr1 != nullptr);
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr1) % 16);
-  ASSERT_TRUE(ptr2 != nullptr);
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr2) % 16);
-
-  ASSERT_EQ(reinterpret_cast<uint8_t*>(ptr1) + 1024, reinterpret_cast<uint8_t*>(ptr2));
-
   // lets allocate until we reach next page.
-  size_t n = kPageSize/sizeof(test_struct_larger) + 1 - 2;
+  size_t n = kPageSize / sizeof(test_struct_larger) + 1;
 
   for (size_t i=0; i<n; ++i) {
     ASSERT_TRUE(allocator.alloc() != nullptr);
@@ -113,7 +113,6 @@
 
   test_struct_larger* ptr_to_free = allocator.alloc();
   ASSERT_TRUE(ptr_to_free != nullptr);
-  allocator.free(ptr1);
 }
 
 static void protect_all() {
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 2a690e9..9e5be34 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -39,6 +39,7 @@
 #include "linker_globals.h"
 #include "linker_phdr.h"
 #include "linker_relocate.h"
+#include "linker_relocs.h"
 #include "linker_tls.h"
 #include "linker_utils.h"
 
@@ -596,31 +597,66 @@
   }
 }
 
-// TODO: There is a similar ifunc resolver calling loop in libc_init_static.cpp, but that version
-// uses weak symbols, which don't work in the linker prior to its relocation. This version also
-// supports a load bias. When we stop supporting the gold linker in the NDK, then maybe we can use
-// non-weak definitions and merge the two loops.
 #if defined(USE_RELA)
-extern __LIBC_HIDDEN__ ElfW(Rela) __rela_iplt_start[], __rela_iplt_end[];
-
-static void call_ifunc_resolvers(ElfW(Addr) load_bias) {
-  for (ElfW(Rela) *r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
-    ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset + load_bias);
-    ElfW(Addr) resolver = r->r_addend + load_bias;
-    *offset = __bionic_call_ifunc_resolver(resolver);
-  }
-}
+using RelType = ElfW(Rela);
+const unsigned kRelTag = DT_RELA;
+const unsigned kRelSzTag = DT_RELASZ;
 #else
-extern __LIBC_HIDDEN__ ElfW(Rel) __rel_iplt_start[], __rel_iplt_end[];
+using RelType = ElfW(Rel);
+const unsigned kRelTag = DT_REL;
+const unsigned kRelSzTag = DT_RELSZ;
+#endif
 
-static void call_ifunc_resolvers(ElfW(Addr) load_bias) {
-  for (ElfW(Rel) *r = __rel_iplt_start; r != __rel_iplt_end; ++r) {
-    ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset + load_bias);
-    ElfW(Addr) resolver = *offset + load_bias;
+extern __LIBC_HIDDEN__ ElfW(Ehdr) __ehdr_start;
+
+static void call_ifunc_resolvers_for_section(RelType* begin, RelType* end) {
+  auto ehdr = reinterpret_cast<ElfW(Addr)>(&__ehdr_start);
+  for (RelType *r = begin; r != end; ++r) {
+    if (ELFW(R_TYPE)(r->r_info) != R_GENERIC_IRELATIVE) {
+      continue;
+    }
+    ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(ehdr + r->r_offset);
+#if defined(USE_RELA)
+    ElfW(Addr) resolver = ehdr + r->r_addend;
+#else
+    ElfW(Addr) resolver = ehdr + *offset;
+#endif
     *offset = __bionic_call_ifunc_resolver(resolver);
   }
 }
-#endif
+
+static void call_ifunc_resolvers() {
+  // Find the IRELATIVE relocations using the DT_JMPREL and DT_PLTRELSZ, or DT_RELA? and DT_RELA?SZ
+  // dynamic tags.
+  auto ehdr = reinterpret_cast<ElfW(Addr)>(&__ehdr_start);
+  auto* phdr = reinterpret_cast<ElfW(Phdr)*>(ehdr + __ehdr_start.e_phoff);
+  for (size_t i = 0; i != __ehdr_start.e_phnum; ++i) {
+    if (phdr[i].p_type != PT_DYNAMIC) {
+      continue;
+    }
+    auto *dyn = reinterpret_cast<ElfW(Dyn)*>(ehdr + phdr[i].p_vaddr);
+    ElfW(Addr) pltrel = 0, pltrelsz = 0, rel = 0, relsz = 0;
+    for (size_t j = 0, size = phdr[i].p_filesz / sizeof(ElfW(Dyn)); j != size; ++j) {
+      if (dyn[j].d_tag == DT_JMPREL) {
+        pltrel = dyn[j].d_un.d_ptr;
+      } else if (dyn[j].d_tag == DT_PLTRELSZ) {
+        pltrelsz = dyn[j].d_un.d_ptr;
+      } else if (dyn[j].d_tag == kRelTag) {
+        rel = dyn[j].d_un.d_ptr;
+      } else if (dyn[j].d_tag == kRelSzTag) {
+        relsz = dyn[j].d_un.d_ptr;
+      }
+    }
+    if (pltrel && pltrelsz) {
+      call_ifunc_resolvers_for_section(reinterpret_cast<RelType*>(ehdr + pltrel),
+                                       reinterpret_cast<RelType*>(ehdr + pltrel + pltrelsz));
+    }
+    if (rel && relsz) {
+      call_ifunc_resolvers_for_section(reinterpret_cast<RelType*>(ehdr + rel),
+                                       reinterpret_cast<RelType*>(ehdr + rel + relsz));
+    }
+  }
+}
 
 // Usable before ifunc resolvers have been called. This function is compiled with -ffreestanding.
 static void linker_memclr(void* dst, size_t cnt) {
@@ -682,14 +718,13 @@
   ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
 
   // string.h functions must not be used prior to calling the linker's ifunc resolvers.
-  const ElfW(Addr) load_bias = get_elf_exec_load_bias(elf_hdr);
-  call_ifunc_resolvers(load_bias);
+  call_ifunc_resolvers();
 
   soinfo tmp_linker_so(nullptr, nullptr, nullptr, 0, 0);
 
   tmp_linker_so.base = linker_addr;
   tmp_linker_so.size = phdr_table_get_load_size(phdr, elf_hdr->e_phnum);
-  tmp_linker_so.load_bias = load_bias;
+  tmp_linker_so.load_bias = get_elf_exec_load_bias(elf_hdr);
   tmp_linker_so.dynamic = nullptr;
   tmp_linker_so.phdr = phdr;
   tmp_linker_so.phnum = elf_hdr->e_phnum;
diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp
index ce29997..456d254 100644
--- a/linker/linker_memory.cpp
+++ b/linker/linker_memory.cpp
@@ -72,6 +72,10 @@
   return get_allocator().alloc(byte_count);
 }
 
+void* memalign(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/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 72be5f7..c7c7bfb 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -229,6 +229,12 @@
   auto get_addend_norel = [&]() -> ElfW(Addr) { return 0; };
 #endif
 
+  if (!IsGeneral && __predict_false(is_tls_reloc(r_type))) {
+    // Always process TLS relocations using the slow code path, so that STB_LOCAL symbols are
+    // diagnosed, and ifunc processing is skipped.
+    return process_relocation_general(relocator, reloc);
+  }
+
   if (IsGeneral && is_tls_reloc(r_type)) {
     if (r_sym == 0) {
       // By convention in ld.bfd and lld, an omitted symbol on a TLS relocation
@@ -242,8 +248,15 @@
       //  - https://groups.google.com/d/topic/generic-abi/dJ4_Y78aQ2M/discussion
       //  - https://sourceware.org/bugzilla/show_bug.cgi?id=17699
       sym = &relocator.si_symtab[r_sym];
-      DL_ERR("unexpected TLS reference to local symbol \"%s\" in \"%s\": sym type %d, rel type %u",
-             sym_name, relocator.si->get_realpath(), ELF_ST_TYPE(sym->st_info), r_type);
+      auto sym_type = ELF_ST_TYPE(sym->st_info);
+      if (sym_type == STT_SECTION) {
+        DL_ERR("unexpected TLS reference to local section in \"%s\": sym type %d, rel type %u",
+               relocator.si->get_realpath(), sym_type, r_type);
+      } else {
+        DL_ERR(
+            "unexpected TLS reference to local symbol \"%s\" in \"%s\": sym type %d, rel type %u",
+            sym_name, relocator.si->get_realpath(), sym_type, r_type);
+      }
       return false;
     } else if (!lookup_symbol<IsGeneral>(relocator, r_sym, sym_name, &found_in, &sym)) {
       return false;
diff --git a/linker/linker_wrapper.cpp b/linker/linker_wrapper.cpp
index fc673aa..5ee2d3e 100644
--- a/linker/linker_wrapper.cpp
+++ b/linker/linker_wrapper.cpp
@@ -28,11 +28,13 @@
 
 #include "private/KernelArgumentBlock.h"
 
-extern const char linker_offset;
+// The offset from the linker's original program header load addresses to
+// the load addresses when embedded into a binary.  Set by the extract_linker
+// tool.
+extern const char __dlwrap_linker_offset;
 
-// This will be replaced by host_bionic_inject, but must be non-zero
-// here so that it's placed in the data section.
-uintptr_t original_start = 42;
+// The real entry point of the binary to use after linker bootstrapping.
+__LIBC_HIDDEN__ extern "C" void _start();
 
 /* Find the load bias and base address of an executable or shared object loaded
  * by the kernel. The ELF file's PHDR table must have a PT_PHDR entry.
@@ -63,7 +65,7 @@
     reinterpret_cast<ElfW(Phdr)*>(args.getauxval(AT_PHDR)), args.getauxval(AT_PHNUM),
     &base_addr, &load_bias);
 
-  ElfW(Addr) linker_addr = base_addr + reinterpret_cast<uintptr_t>(&linker_offset);
+  ElfW(Addr) linker_addr = base_addr + reinterpret_cast<uintptr_t>(&__dlwrap_linker_offset);
   ElfW(Addr) linker_entry_offset = reinterpret_cast<ElfW(Ehdr)*>(linker_addr)->e_entry;
 
   for (ElfW(auxv_t)* v = args.auxv; v->a_type != AT_NULL; ++v) {
@@ -73,7 +75,7 @@
     }
     if (v->a_type == AT_ENTRY) {
       // Set AT_ENTRY to the proper entry point
-      v->a_un.a_val = base_addr + original_start;
+      v->a_un.a_val = reinterpret_cast<ElfW(Addr)>(&_start);
     }
   }
 
diff --git a/tests/Android.bp b/tests/Android.bp
index 476b8f5..a54ffb8 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -62,7 +62,10 @@
         // For glibc.
         "-D__STDC_LIMIT_MACROS",
     ],
-    header_libs: ["libcutils_headers"],
+    header_libs: [
+        "libcutils_headers",
+        "gwp_asan_headers"
+    ],
     // Ensure that the tests exercise shadow call stack support and
     // the hint space PAC/BTI instructions.
     arch: {
@@ -295,6 +298,29 @@
     },
 }
 
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-local-tls",
+    strip: {
+        none: true,
+    },
+    check_elf_files: false,
+    relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
+    arch: {
+        arm: {
+            srcs: ["prebuilt-elf-files/arm/libtest_invalid-local-tls.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-local-tls.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-local-tls.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so"],
+        },
+    },
+}
+
 // -----------------------------------------------------------------------------
 // All standard tests.
 // -----------------------------------------------------------------------------
@@ -320,6 +346,7 @@
         "__cxa_demangle_test.cpp",
         "alloca_test.cpp",
         "android_get_device_api_level.cpp",
+        "android_set_abort_message_test.cpp",
         "arpa_inet_test.cpp",
         "async_safe_test.cpp",
         "assert_test.cpp",
@@ -406,6 +433,7 @@
         "string_nofortify_test.cpp",
         "string_test.cpp",
         "string_posix_strerror_r_test.cpp",
+        "string_posix_strerror_r_wrapper.cpp",
         "strings_nofortify_test.cpp",
         "strings_test.cpp",
         "struct_layout_test.cpp",
@@ -468,6 +496,18 @@
                 "libsystemproperties",
             ],
         },
+        musl: {
+            exclude_srcs: [
+                // musl doesn't have error.h
+                "error_test.cpp",
+
+                // musl doesn't define noreturn for C++
+                "stdnoreturn_test.cpp",
+
+                // unsupported relocation type 37
+                "ifunc_test.cpp",
+            ],
+        },
     },
 
     static_libs: [
@@ -480,6 +520,12 @@
     },
 
     generated_headers: ["generated_android_ids"],
+
+    // Bug: http://b/218788252 IR verifier too strict for ifunc resolver that
+    // accept parameters.
+    lto: {
+        never: true,
+    },
 }
 
 cc_test_library {
@@ -552,6 +598,18 @@
     ],
 }
 
+cc_test_library {
+    name: "libBionicGwpAsanTests",
+    defaults: ["bionic_tests_defaults"],
+    srcs: [
+        "gwp_asan_test.cpp",
+    ],
+    include_dirs: [
+        "bionic/libc",
+    ],
+    static_libs: ["libbase"],
+}
+
 // -----------------------------------------------------------------------------
 // Fortify tests.
 // -----------------------------------------------------------------------------
@@ -586,6 +644,10 @@
         host: {
             clang_cflags: ["-D__clang__"],
         },
+        musl: {
+            // Musl doesn't have fortify
+            enabled: false,
+        },
     },
 }
 
@@ -707,10 +769,12 @@
 cc_test_library {
     name: "libBionicTests",
     defaults: ["bionic_tests_defaults"],
+    host_supported: false,
     whole_static_libs: [
         "libBionicStandardTests",
         "libBionicElfTlsTests",
         "libBionicFramePointerTests",
+        "libBionicGwpAsanTests",
         "libfortify1-tests-clang",
         "libfortify1-new-tests-clang",
         "libfortify2-tests-clang",
@@ -725,13 +789,13 @@
     name: "libBionicLoaderTests",
     defaults: [
         "bionic_tests_defaults",
-        "llvm-defaults",
     ],
     srcs: [
         "atexit_test.cpp",
         "dl_test.cpp",
         "dlfcn_symlink_support.cpp",
         "dlfcn_test.cpp",
+        "execinfo_test.cpp",
         "link_test.cpp",
         "pthread_dlfcn_test.cpp",
     ],
@@ -755,12 +819,6 @@
                 "libmeminfo",
                 "libprocinfo",
                 "libziparchive",
-                "libLLVMObject",
-                "libLLVMBitReader",
-                "libLLVMMC",
-                "libLLVMMCParser",
-                "libLLVMCore",
-                "libLLVMSupport",
             ],
         },
     },
@@ -774,13 +832,14 @@
     name: "libBionicCtsGtestMain",
     defaults: ["bionic_tests_defaults"],
     srcs: [
-        "gtest_globals_cts.cpp",
+        "gtest_globals.cpp",
         "gtest_main.cpp",
     ],
     shared: {
         enabled: false,
     },
     whole_static_libs: [
+        "libbase",
         "libgtest_isolated",
     ],
 }
@@ -849,21 +908,15 @@
                 "libziparchive",
                 "libz",
                 "libutils",
-                "libLLVMObject",
-                "libLLVMBitReader",
-                "libLLVMMC",
-                "libLLVMMCParser",
-                "libLLVMCore",
-                "libLLVMSupport",
             ],
             ldflags: [
-                "-Wl,--rpath,${ORIGIN}/../bionic-loader-test-libs",
+                "-Wl,--rpath,${ORIGIN}/bionic-loader-test-libs",
                 "-Wl,--enable-new-dtags",
             ],
         },
     },
 
-    required: [
+    data_bins: [
         "cfi_test_helper",
         "cfi_test_helper2",
         "elftls_dlopen_ie_error_helper",
@@ -882,6 +935,14 @@
         "ld_preload_test_helper",
         "ld_preload_test_helper_lib1",
         "ld_preload_test_helper_lib2",
+        "ns_hidden_child_helper",
+        "preinit_getauxval_test_helper",
+        "preinit_syscall_test_helper",
+        "thread_exit_cb_helper",
+        "tls_properties_helper",
+    ],
+
+    data_libs: [
         "libatest_simple_zip",
         "libcfi-test",
         "libcfi-test-bad",
@@ -893,9 +954,7 @@
         "libdlext_test_fd",
         "libdlext_test_norelro",
         "libdlext_test_recursive",
-        "libdlext_test_runpath_zip_zipaligned",
         "libdlext_test_zip",
-        "libdlext_test_zip_zipaligned",
         "libgnu-hash-table-library",
         "libns_hidden_child_app",
         "libns_hidden_child_global",
@@ -975,6 +1034,7 @@
         "libtest_init_fini_order_root",
         "libtest_init_fini_order_root2",
         "libtest_invalid-empty_shdr_table",
+        "libtest_invalid-local-tls",
         "libtest_invalid-rw_load_segment",
         "libtest_invalid-textrels",
         "libtest_invalid-textrels2",
@@ -1015,11 +1075,6 @@
         "libtest_with_dependency_loop_b",
         "libtest_with_dependency_loop_c",
         "libtestshared",
-        "ns_hidden_child_helper",
-        "preinit_getauxval_test_helper",
-        "preinit_syscall_test_helper",
-        "thread_exit_cb_helper",
-        "tls_properties_helper",
     ],
 }
 
@@ -1028,6 +1083,11 @@
     defaults: [
         "bionic_unit_tests_defaults",
     ],
+    test_suites: ["device-tests"],
+    data: [
+        ":libdlext_test_runpath_zip_zipaligned",
+        ":libdlext_test_zip_zipaligned",
+    ],
 }
 
 cc_test {
@@ -1070,6 +1130,7 @@
     name: "bionic-unit-tests-static",
     gtest: false,
     defaults: ["bionic_tests_defaults"],
+    test_suites: ["device-tests"],
     host_supported: false,
 
     srcs: [
@@ -1103,6 +1164,19 @@
 
     static_executable: true,
     stl: "libc++_static",
+    // Clang cannot build ifunc with LTO.
+    // http://b/203737712
+    lto: {
+        never: true,
+    },
+    data_bins: [
+        "heap_tagging_async_helper",
+        "heap_tagging_disabled_helper",
+        "heap_tagging_static_async_helper",
+        "heap_tagging_static_disabled_helper",
+        "heap_tagging_static_sync_helper",
+        "heap_tagging_sync_helper",
+    ],
 }
 
 // -----------------------------------------------------------------------------
@@ -1120,6 +1194,7 @@
         "dlfcn_symlink_support.cpp",
         "dlfcn_test.cpp",
         "dl_test.cpp",
+        "execinfo_test.cpp",
         "gtest_globals.cpp",
         "gtest_main.cpp",
         "pthread_dlfcn_test.cpp",
@@ -1170,6 +1245,13 @@
         linux_bionic: {
             enabled: false,
         },
+        musl: {
+            exclude_static_libs: [
+                // Musl doesn't have fortify
+                "libfortify1-tests-clang",
+                "libfortify2-tests-clang",
+            ],
+        },
     },
 }
 
diff --git a/tests/NOTICE b/tests/NOTICE
index a58cf46..8c3483c 100644
--- a/tests/NOTICE
+++ b/tests/NOTICE
@@ -354,3 +354,59 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2021 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) 2022 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
diff --git a/tests/SignalUtils.h b/tests/SignalUtils.h
index a2faf0a..f04ea59 100644
--- a/tests/SignalUtils.h
+++ b/tests/SignalUtils.h
@@ -19,7 +19,7 @@
 #include <signal.h>
 #include <string.h>
 
-#if defined(__GLIBC__)
+#if !defined(__BIONIC__)
 #define posix_spawnattr_getsigdefault64 posix_spawnattr_getsigdefault
 #define posix_spawnattr_getsigmask64 posix_spawnattr_getsigmask
 #define posix_spawnattr_setsigdefault64 posix_spawnattr_setsigdefault
diff --git a/tests/android_set_abort_message_test.cpp b/tests/android_set_abort_message_test.cpp
new file mode 100644
index 0000000..d6553de
--- /dev/null
+++ b/tests/android_set_abort_message_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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 <sys/cdefs.h>
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+extern "C" void android_set_abort_message(const char* msg);
+#endif
+
+TEST(android_set_abort_message_test, nullptr_check) {
+#if defined(__BIONIC__)
+  android_set_abort_message(nullptr);
+#else
+  GTEST_SKIP() << "This test is only supported on bionic.";
+#endif
+}
diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp
index 8dec2e3..7150854 100644
--- a/tests/arpa_inet_test.cpp
+++ b/tests/arpa_inet_test.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <sys/cdefs.h>
+
 #include <gtest/gtest.h>
 
 #include <arpa/inet.h>
@@ -160,6 +162,7 @@
 }
 
 TEST(arpa_inet, inet_nsap_addr) {
+#if !defined(ANDROID_HOST_MUSL)
   // inet_nsap_addr() doesn't seem to be documented anywhere, but it's basically
   // text to binary for arbitrarily-long strings like "0xdeadbeef". Any
   // '.', '+', or '/' characters are ignored as punctuation. The return value is
@@ -233,9 +236,13 @@
   ASSERT_EQ(0U, inet_nsap_addr("0x11.2g", buf, sizeof(buf)));
   // Invalid half-byte.
   ASSERT_EQ(0U, inet_nsap_addr("0x11.2", buf, sizeof(buf)));
+#else
+  GTEST_SKIP() << "musl doesn't have inet_nsap_addr";
+#endif
 }
 
 TEST(arpa_inet, inet_nsap_ntoa) {
+#if !defined(ANDROID_HOST_MUSL)
   // inet_nsap_ntoa() doesn't seem to be documented anywhere, but it's basically
   // binary to text for arbitrarily-long byte buffers.
   // The return value is a pointer to the buffer. No errors are possible.
@@ -243,10 +250,17 @@
   char dst[32];
   ASSERT_EQ(dst, inet_nsap_ntoa(6, bytes, dst));
   ASSERT_STREQ(dst, "0x01.0002.0EF0.20");
+#else
+  GTEST_SKIP() << "musl doesn't have inet_nsap_ntoa";
+#endif
 }
 
 TEST(arpa_inet, inet_nsap_ntoa__nullptr) {
+#if !defined(ANDROID_HOST_MUSL)
   // If you don't provide a destination, a static buffer is provided for you.
   const unsigned char bytes[] = {0x01, 0x00, 0x02, 0x0e, 0xf0, 0x20};
   ASSERT_STREQ("0x01.0002.0EF0.20", inet_nsap_ntoa(6, bytes, nullptr));
+#else
+  GTEST_SKIP() << "musl doesn't have inet_nsap_ntoa";
+#endif
 }
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index 6c4758e..f52387e 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -64,6 +64,10 @@
   async_safe_format_buffer(buf, sizeof(buf), "a%ldb", 70000L);
   EXPECT_STREQ("a70000b", buf);
 
+  errno = EINVAL;
+  async_safe_format_buffer(buf, sizeof(buf), "a%mZ");
+  EXPECT_STREQ("aInvalid argumentZ", buf);
+
   async_safe_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
   EXPECT_STREQ("a0xb0001234b", buf);
 
@@ -97,6 +101,30 @@
   async_safe_format_buffer(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
   EXPECT_STREQ("a005:5:05z", buf);
 
+  async_safe_format_buffer(buf, sizeof(buf), "a%#xZ", 34);
+  EXPECT_STREQ("a0x22Z", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#xZ", 0);
+  EXPECT_STREQ("a0Z", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#5xZ", 20);
+  EXPECT_STREQ("a 0x14Z", buf);
+
+  snprintf(buf, sizeof(buf), "a%#08.8xZ", 1);
+  EXPECT_STREQ("a0x00000001Z", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#oZ", 777);
+  EXPECT_STREQ("a01411Z", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#oZ", 0);
+  EXPECT_STREQ("a0Z", buf);
+
+  async_safe_format_buffer(buf, sizeof(buf), "a%#6oZ", 15);
+  EXPECT_STREQ("a   017Z", buf);
+
+  snprintf(buf, sizeof(buf), "a%#08.8oZ", 11);
+  EXPECT_STREQ("a00000013Z", buf);
+
   void* p = nullptr;
   async_safe_format_buffer(buf, sizeof(buf), "a%d,%pz", 5, p);
   EXPECT_STREQ("a5,0x0z", buf);
diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp
index 9a6ed9a..1c45946 100644
--- a/tests/cfi_test.cpp
+++ b/tests/cfi_test.cpp
@@ -19,7 +19,6 @@
 
 #include <vector>
 
-#include <android-base/silent_death_test.h>
 #include <gtest/gtest.h>
 
 #include "gtest_globals.h"
@@ -36,7 +35,45 @@
 size_t __cfi_shadow_size();
 }
 
-using cfi_test_DeathTest = SilentDeathTest;
+// Disables debuggerd stack traces to speed up death tests, make them less
+// noisy in logcat, and avoid expected deaths from showing up in stability
+// metrics.
+// We don't use the usual libbase class because (a) we don't care about most
+// of the signals it blocks but (b) we do need to block SIGILL, which normal
+// death tests shouldn't ever hit. (It's possible that a design where a
+// deathtest always declares its expected signals up front is a better one,
+// and maybe that's an interesting future direction for libbase.)
+//
+// We include SIGSEGV because there's a test that passes heap addresses to
+// __cfi_slowpath and we only map the executable code shadow as readable.
+// We don't always get SIGSEGV there though: if the heap allocation happens
+// to be close enough to an executable mapping that its shadow is in the
+// same page as the executable shadow, we'll get SIGILL/SIGTRAP.
+class cfi_test_DeathTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    struct sigaction64 action = {.sa_handler = SIG_DFL};
+    sigaction64(SIGILL, &action, &previous_sigill_);
+    sigaction64(SIGSEGV, &action, &previous_sigsegv_);
+    sigaction64(SIGTRAP, &action, &previous_sigtrap_);
+  }
+
+  void TearDown() override {
+    sigaction64(SIGTRAP, &previous_sigtrap_, nullptr);
+    sigaction64(SIGSEGV, &previous_sigsegv_, nullptr);
+    sigaction64(SIGILL, &previous_sigill_, nullptr);
+  }
+
+ private:
+  struct sigaction64 previous_sigill_;
+  struct sigaction64 previous_sigsegv_;
+  struct sigaction64 previous_sigtrap_;
+};
+
+static bool KilledByCfi(int status) {
+  return WIFSIGNALED(status) &&
+         (WTERMSIG(status) == SIGTRAP || WTERMSIG(status) == SIGILL || WTERMSIG(status) == SIGSEGV);
+}
 
 static void f() {}
 
@@ -102,7 +139,7 @@
   // It's possible that this allocation could wind up in the same CFI granule as
   // an unchecked library, which means the below might not crash. To force a
   // crash keep allocating up to a max until there is a crash.
-  EXPECT_DEATH(test_cfi_slowpath_with_alloc(), "");
+  EXPECT_EXIT(test_cfi_slowpath_with_alloc(), KilledByCfi, "");
 
   // Check all the addresses.
   const size_t bss_size = 1024 * 1024;
@@ -128,7 +165,7 @@
 
   // CFI check for a function inside the unloaded DSO. This is always invalid and gets the process
   // killed.
-  EXPECT_DEATH(__cfi_slowpath(45, reinterpret_cast<void*>(code_ptr)), "");
+  EXPECT_EXIT(__cfi_slowpath(45, reinterpret_cast<void*>(code_ptr)), KilledByCfi, "");
 #endif
 }
 
@@ -146,7 +183,7 @@
 // cfi_test_helper exports __cfi_check, which triggers CFI initialization at startup.
 TEST(cfi_test, early_init) {
 #if defined(__BIONIC__)
-  std::string helper = GetTestlibRoot() + "/cfi_test_helper/cfi_test_helper";
+  std::string helper = GetTestlibRoot() + "/cfi_test_helper";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
@@ -158,7 +195,7 @@
 // at startup.
 TEST(cfi_test, early_init2) {
 #if defined(__BIONIC__)
-  std::string helper = GetTestlibRoot() + "/cfi_test_helper2/cfi_test_helper2";
+  std::string helper = GetTestlibRoot() + "/cfi_test_helper2";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 5768f1f..40cb83f 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -164,6 +164,9 @@
     const char large_string[] = "Hello!!!";
     static_assert(sizeof(large_string) > sizeof(small_buffer), "");
 
+#if __clang_major__ > 13
+    // expected-error@+3{{will always overflow}}
+#endif
     // expected-error@+1{{string bigger than buffer}}
     EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
     // expected-error@+1{{string bigger than buffer}}
@@ -201,6 +204,9 @@
     static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
 
 #if _FORTIFY_SOURCE > 1
+#if __clang_major__ > 13
+    // expected-error@+4{{will always overflow}}
+#endif
     // expected-error@+2{{string bigger than buffer}}
 #endif
     EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
diff --git a/tests/dirent_test.cpp b/tests/dirent_test.cpp
index 56929d1..3ea9cbd 100644
--- a/tests/dirent_test.cpp
+++ b/tests/dirent_test.cpp
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <sys/cdefs.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -82,6 +83,7 @@
 }
 
 TEST(dirent, scandirat_scandirat64) {
+#if !defined(ANDROID_HOST_MUSL)
   // Get everything from /proc/self...
   dirent** entries;
   int entry_count = scandir("/proc/self", &entries, nullptr, alphasort);
@@ -111,6 +113,9 @@
   ASSERT_EQ(name_set, name_set_at64);
   ASSERT_EQ(unsorted_name_list, unsorted_name_list_at);
   ASSERT_EQ(unsorted_name_list, unsorted_name_list_at64);
+#else
+  GTEST_SKIP() << "musl doesn't have scandirat or scandirat64";
+#endif
 }
 
 static int is_version_filter(const dirent* de) {
@@ -140,6 +145,7 @@
 }
 
 TEST(dirent, scandirat_ENOENT) {
+#if !defined(ANDROID_HOST_MUSL)
   int root_fd = open("/", O_DIRECTORY | O_RDONLY);
   ASSERT_NE(-1, root_fd);
   dirent** entries;
@@ -147,9 +153,13 @@
   ASSERT_EQ(-1, scandirat(root_fd, "does-not-exist", &entries, nullptr, nullptr));
   ASSERT_EQ(ENOENT, errno);
   close(root_fd);
+#else
+  GTEST_SKIP() << "musl doesn't have scandirat or scandirat64";
+#endif
 }
 
 TEST(dirent, scandirat64_ENOENT) {
+#if !defined(ANDROID_HOST_MUSL)
   int root_fd = open("/", O_DIRECTORY | O_RDONLY);
   ASSERT_NE(-1, root_fd);
   dirent64** entries;
@@ -157,6 +167,9 @@
   ASSERT_EQ(-1, scandirat64(root_fd, "does-not-exist", &entries, nullptr, nullptr));
   ASSERT_EQ(ENOENT, errno);
   close(root_fd);
+#else
+  GTEST_SKIP() << "musl doesn't have scandirat or scandirat64";
+#endif
 }
 
 TEST(dirent, fdopendir_invalid) {
@@ -228,7 +241,7 @@
   CheckProcSelf(name_set);
 }
 
-TEST(dirent, readdir64) {
+TEST(dirent, readdir64_smoke) {
   DIR* d = opendir("/proc/self");
   ASSERT_TRUE(d != nullptr);
   std::set<std::string> name_set;
@@ -263,7 +276,7 @@
   CheckProcSelf(name_set);
 }
 
-TEST(dirent, readdir64_r) {
+TEST(dirent, readdir64_r_smoke) {
   DIR* d = opendir("/proc/self");
   ASSERT_TRUE(d != nullptr);
   std::set<std::string> name_set;
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index 47bf133..a61586b 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -34,6 +34,7 @@
 
 #include "gtest_globals.h"
 #include <android-base/file.h>
+#include <android-base/test_utils.h>
 #include "utils.h"
 
 extern "C" int main_global_default_serial() {
@@ -125,8 +126,7 @@
 TEST(dl, exec_linker_load_file) {
 #if defined(__BIONIC__)
   const char* path_to_linker = PathToLinker();
-  std::string helper = GetTestlibRoot() +
-      "/exec_linker_helper/exec_linker_helper";
+  std::string helper = GetTestlibRoot() + "/exec_linker_helper";
   std::string expected_output =
       "ctor: argc=1 argv[0]=" + helper + "\n" +
       "main: argc=1 argv[0]=" + helper + "\n" +
@@ -134,7 +134,8 @@
       "helper_func called\n";
   ExecTestHelper eth;
   eth.SetArgs({ path_to_linker, helper.c_str(), nullptr });
-  eth.Run([&]() { execve(path_to_linker, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
+  eth.Run([&]() { execve(path_to_linker, eth.GetArgs(), eth.GetEnv()); }, 0, nullptr);
+  ASSERT_EQ(expected_output, eth.GetOutput());
 #endif
 }
 
@@ -150,7 +151,8 @@
       "helper_func called\n";
   ExecTestHelper eth;
   eth.SetArgs({ path_to_linker, helper.c_str(), nullptr });
-  eth.Run([&]() { execve(path_to_linker, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
+  eth.Run([&]() { execve(path_to_linker, eth.GetArgs(), eth.GetEnv()); }, 0, nullptr);
+  ASSERT_EQ(expected_output, eth.GetOutput());
 #endif
 }
 
@@ -167,8 +169,7 @@
 TEST(dl, preinit_system_calls) {
 #if defined(__BIONIC__)
   SKIP_WITH_HWASAN << "hwasan not initialized in preinit_array, b/124007027";
-  std::string helper = GetTestlibRoot() +
-      "/preinit_syscall_test_helper/preinit_syscall_test_helper";
+  std::string helper = GetTestlibRoot() + "/preinit_syscall_test_helper";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
@@ -179,8 +180,7 @@
 TEST(dl, preinit_getauxval) {
 #if defined(__BIONIC__)
   SKIP_WITH_HWASAN << "hwasan not initialized in preinit_array, b/124007027";
-  std::string helper = GetTestlibRoot() +
-      "/preinit_getauxval_test_helper/preinit_getauxval_test_helper";
+  std::string helper = GetTestlibRoot() + "/preinit_getauxval_test_helper";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
@@ -194,8 +194,7 @@
 
 TEST(dl, exec_without_ld_preload) {
 #if defined(__BIONIC__)
-  std::string helper = GetTestlibRoot() +
-      "/ld_preload_test_helper/ld_preload_test_helper";
+  std::string helper = GetTestlibRoot() + "/ld_preload_test_helper";
   chmod(helper.c_str(), 0755);
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
@@ -205,8 +204,7 @@
 
 TEST(dl, exec_with_ld_preload) {
 #if defined(__BIONIC__)
-  std::string helper = GetTestlibRoot() +
-      "/ld_preload_test_helper/ld_preload_test_helper";
+  std::string helper = GetTestlibRoot() + "/ld_preload_test_helper";
   std::string env = std::string("LD_PRELOAD=") + GetTestlibRoot() + "/ld_preload_test_helper_lib2.so";
   chmod(helper.c_str(), 0755);
   ExecTestHelper eth;
@@ -232,12 +230,10 @@
 // The two libs are in ns2/ subdir.
 TEST(dl, exec_without_ld_config_file) {
 #if defined(__BIONIC__)
-  std::string error_message =
-      "CANNOT LINK EXECUTABLE \"" + GetTestlibRoot() +
-      "/ld_config_test_helper/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" "
-      "not found: needed by main executable\n";
-  std::string helper = GetTestlibRoot() +
-      "/ld_config_test_helper/ld_config_test_helper";
+  std::string error_message = "CANNOT LINK EXECUTABLE \"" + GetTestlibRoot() +
+                              "/ld_config_test_helper\": library \"ld_config_test_helper_lib1.so\" "
+                              "not found: needed by main executable\n";
+  std::string helper = GetTestlibRoot() + "/ld_config_test_helper";
   chmod(helper.c_str(), 0755);
   ExecTestHelper eth;
   eth.SetArgs({ helper.c_str(), nullptr });
@@ -252,13 +248,16 @@
   android_get_LD_LIBRARY_PATH(default_search_paths, sizeof(default_search_paths));
 
   std::ofstream fout(config_file, std::ios::out);
-  fout << "dir.test = " << GetTestlibRoot() << "/ld_config_test_helper/" << std::endl
+  fout << "dir.test = " << GetTestlibRoot() << "/" << std::endl
        << "[test]" << std::endl
        << "additional.namespaces = ns2" << std::endl
        << "namespace.default.search.paths = " << GetTestlibRoot() << std::endl
        << "namespace.default.links = ns2" << std::endl
-       << "namespace.default.link.ns2.shared_libs = libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so" << std::endl
-       << "namespace.ns2.search.paths = " << default_search_paths << ":" << GetTestlibRoot() << "/ns2" << std::endl;
+       << "namespace.default.link.ns2.shared_libs = "
+          "libc.so:libm.so:libdl.so:ld_config_test_helper_lib1.so"
+       << std::endl
+       << "namespace.ns2.search.paths = " << default_search_paths << ":" << GetTestlibRoot()
+       << "/ns2" << std::endl;
   fout.close();
 }
 #endif
@@ -288,8 +287,7 @@
   if (is_user_build()) {
     GTEST_SKIP() << "LD_CONFIG_FILE is not supported on user build";
   }
-  std::string helper = GetTestlibRoot() +
-      "/ld_config_test_helper/ld_config_test_helper";
+  std::string helper = GetTestlibRoot() + "/ld_config_test_helper";
   TemporaryFile config_file;
   create_ld_config_file(config_file.path);
   std::string env = std::string("LD_CONFIG_FILE=") + config_file.path;
@@ -325,8 +323,7 @@
   if (is_user_build()) {
     GTEST_SKIP() << "LD_CONFIG_FILE is not supported on user build";
   }
-  std::string helper = GetTestlibRoot() +
-      "/ld_config_test_helper/ld_config_test_helper";
+  std::string helper = GetTestlibRoot() + "/ld_config_test_helper";
   TemporaryFile config_file;
   create_ld_config_file(config_file.path);
   std::string env = std::string("LD_CONFIG_FILE=") + config_file.path;
@@ -363,11 +360,11 @@
     GTEST_SKIP() << "test requires user build";
   }
 
-  std::string error_message = std::string("CANNOT LINK EXECUTABLE ") +
-      "\"" + GetTestlibRoot() + "/ld_config_test_helper/ld_config_test_helper\": " +
+  std::string error_message =
+      std::string("CANNOT LINK EXECUTABLE ") + "\"" + GetTestlibRoot() +
+      "/ld_config_test_helper\": " +
       "library \"ld_config_test_helper_lib1.so\" not found: needed by main executable\n";
-  std::string helper = GetTestlibRoot() +
-      "/ld_config_test_helper/ld_config_test_helper";
+  std::string helper = GetTestlibRoot() + "/ld_config_test_helper";
   TemporaryFile config_file;
   create_ld_config_file(config_file.path);
   std::string env = std::string("LD_CONFIG_FILE=") + config_file.path;
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index e3caf0e..ea28822 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -714,7 +714,7 @@
 }
 
 std::string DlExtRelroSharingTest::FindMappingName(void* ptr) {
-  uint64_t addr = reinterpret_cast<uint64_t>(ptr);
+  uint64_t addr = reinterpret_cast<uint64_t>(untag_address(ptr));
   std::string found_name = "<not found>";
 
   EXPECT_TRUE(android::procinfo::ReadMapFile("/proc/self/maps",
@@ -2076,7 +2076,7 @@
 TEST(dlext, ns_hidden_child) {
   ExecTestHelper eth;
 
-  std::string helper = GetTestlibRoot() + "/ns_hidden_child_helper/ns_hidden_child_helper";
+  std::string helper = GetTestlibRoot() + "/ns_hidden_child_helper";
   chmod(helper.c_str(), 0755); // TODO: "x" lost in CTS, b/34945607
   std::string app_ns_dir = GetTestlibRoot() + "/ns_hidden_child_app";
   eth.SetArgs({ helper.c_str(), app_ns_dir.c_str(), nullptr });
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 35e12eb..940e726 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -17,10 +17,13 @@
 #include <gtest/gtest.h>
 
 #include <dlfcn.h>
+#include <elf.h>
 #include <limits.h>
-#include <stdio.h>
+#include <link.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <string.h>
+#include <sys/cdefs.h>
 #if __has_include(<sys/auxv.h>)
 #include <sys/auxv.h>
 #endif
@@ -37,24 +40,6 @@
 #include "dlfcn_symlink_support.h"
 #include "utils.h"
 
-#if defined(__BIONIC__) && (defined(__arm__) || defined(__i386__))
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-parameter"
-
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Object/Binary.h>
-#include <llvm/Object/ELFObjectFile.h>
-#include <llvm/Object/ObjectFile.h>
-
-#pragma clang diagnostic pop
-#endif //  defined(__ANDROID__) && (defined(__arm__) || defined(__i386__))
-
-// Declared manually because the macro definitions in <elf.h> conflict with LLVM headers.
-#ifdef __arm__
-typedef uintptr_t _Unwind_Ptr;
-extern "C" _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int*);
-#endif
-
 #define ASSERT_SUBSTR(needle, haystack) \
     ASSERT_PRED_FORMAT2(::testing::IsSubstring, needle, haystack)
 
@@ -273,6 +258,9 @@
   dlclose(handle);
 }
 
+// HWASan uses an ifunc to describe the location of its shadow memory,
+// so even though it's an unusual case, Android needs to support
+// "ifunc variables".
 TEST(dlfcn, ifunc_variable) {
   typedef const char* (*fn_ptr)();
 
@@ -1156,7 +1144,7 @@
 
 TEST(dlfcn, dlopen_symlink) {
   DlfcnSymlink symlink("dlopen_symlink");
-  const std::string symlink_name = basename(symlink.get_symlink_path().c_str());
+  const std::string symlink_name = android::base::Basename(symlink.get_symlink_path());
   void* handle1 = dlopen("libdlext_test.so", RTLD_NOW);
   void* handle2 = dlopen(symlink_name.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle1 != nullptr);
@@ -1259,6 +1247,7 @@
 }
 
 TEST(dlfcn, dlvsym_smoke) {
+#if !defined(ANDROID_HOST_MUSL)
   void* handle = dlopen("libtest_versioned_lib.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
   typedef int (*fn_t)();
@@ -1276,6 +1265,9 @@
   }
 
   dlclose(handle);
+#else
+  GTEST_SKIP() << "musl doesn't have dlvsym";
+#endif
 }
 
 // This preempts the implementation from libtest_versioned_lib.so
@@ -1537,75 +1529,35 @@
 #if defined(__BIONIC__)
 
 #if defined(__arm__)
-const llvm::ELF::Elf32_Dyn* to_dynamic_table(const char* p) {
-  return reinterpret_cast<const llvm::ELF::Elf32_Dyn*>(p);
-}
 
-// Duplicate these definitions here because they are android specific
-//  - note that we cannot include <elf.h> because #defines conflict with
-//    enum names provided by LLVM.
-//  - we also don't use llvm::ELF::DT_LOOS because its value is 0x60000000
-//    rather than the 0x6000000d we expect
-#define DT_LOOS 0x6000000d
-#define DT_ANDROID_REL (DT_LOOS + 2)
-#define DT_ANDROID_RELA (DT_LOOS + 4)
+void validate_compatibility_of_native_library(const std::string& soname, const std::string& path) {
+  // Grab the dynamic section in text form...
+  ExecTestHelper eth;
+  eth.SetArgs({"readelf", "-dW", path.c_str(), nullptr});
+  eth.Run([&]() { execvpe("readelf", eth.GetArgs(), eth.GetEnv()); }, 0, nullptr);
+  std::string output = eth.GetOutput();
 
-template<typename ELFT>
-void validate_compatibility_of_native_library(const std::string& soname,
-                                              const std::string& path, ELFT* elf) {
-  bool has_elf_hash = false;
-  bool has_android_rel = false;
-  bool has_rel = false;
-  // Find dynamic section and check that DT_HASH and there is no DT_ANDROID_REL
-  for (auto it = elf->section_begin(); it != elf->section_end(); ++it) {
-    const llvm::object::ELFSectionRef& section_ref = *it;
-    if (section_ref.getType() == llvm::ELF::SHT_DYNAMIC) {
-      llvm::StringRef data;
-      ASSERT_TRUE(!it->getContents(data)) << "unable to get SHT_DYNAMIC section data";
-      for (auto d = to_dynamic_table(data.data()); d->d_tag != llvm::ELF::DT_NULL; ++d) {
-        if (d->d_tag == llvm::ELF::DT_HASH) {
-          has_elf_hash = true;
-        } else if (d->d_tag == DT_ANDROID_REL || d->d_tag == DT_ANDROID_RELA) {
-          has_android_rel = true;
-        } else if (d->d_tag == llvm::ELF::DT_REL || d->d_tag == llvm::ELF::DT_RELA) {
-          has_rel = true;
-        }
-      }
+  // Check that there *is* a legacy DT_HASH (not just a GNU hash)...
+  ASSERT_TRUE(std::regex_search(output, std::regex("\\(HASH\\)"))) << output;
+  // Check that there is no DT_ANDROID_REL or DT_ANDROID_RELA...
+  ASSERT_FALSE(std::regex_search(output, std::regex("\\(ANDROID_REL\\)"))) << output;
+  ASSERT_FALSE(std::regex_search(output, std::regex("\\(ANDROID_RELA\\)"))) << output;
 
-      break;
-    }
-  }
-
-  ASSERT_TRUE(has_elf_hash) << path.c_str() << ": missing elf hash (DT_HASH)";
-  ASSERT_TRUE(!has_android_rel) << path.c_str() << ": has packed relocations";
-  // libdl.so is simple enough that it might not have any relocations, so
-  // exempt it from the DT_REL/DT_RELA check.
-  if (soname != "libdl.so") {
-    ASSERT_TRUE(has_rel) << path.c_str() << ": missing DT_REL/DT_RELA";
-  }
+  // Check that we have regular non-packed relocations.
+  // libdl.so is simple enough that it doesn't have any relocations.
+  ASSERT_TRUE(std::regex_search(output, std::regex("\\(RELA?\\)")) || soname == "libdl.so")
+      << output;
 }
 
 void validate_compatibility_of_native_library(const std::string& soname) {
   // On the systems with emulation system libraries would be of different
   // architecture.  Try to use alternate paths first.
   std::string path = std::string(ALTERNATE_PATH_TO_SYSTEM_LIB) + soname;
-  auto binary_or_error = llvm::object::createBinary(path);
-  if (!binary_or_error) {
+  if (access(path.c_str(), R_OK) != 0) {
     path = std::string(PATH_TO_SYSTEM_LIB) + soname;
-    binary_or_error = llvm::object::createBinary(path);
+    ASSERT_EQ(0, access(path.c_str(), R_OK));
   }
-  ASSERT_FALSE(!binary_or_error);
-
-  llvm::object::Binary* binary = binary_or_error.get().getBinary();
-
-  auto obj = llvm::dyn_cast<llvm::object::ObjectFile>(binary);
-  ASSERT_TRUE(obj != nullptr);
-
-  auto elf = llvm::dyn_cast<llvm::object::ELF32LEObjectFile>(obj);
-
-  ASSERT_TRUE(elf != nullptr);
-
-  validate_compatibility_of_native_library(soname, path, elf);
+  validate_compatibility_of_native_library(soname, path);
 }
 
 // This is a test for app compatibility workaround for arm apps
@@ -1702,6 +1654,21 @@
   ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
 }
 
+TEST(dlfcn, dlopen_invalid_local_tls) {
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-local-tls.so";
+
+  void* handle = dlopen(libpath.c_str(), RTLD_NOW);
+  ASSERT_TRUE(handle == nullptr);
+#if defined(__arm__)
+  const char* referent = "local section";
+#else
+  const char* referent = "local symbol \"tls_var_2\"";
+#endif
+  std::string expected_dlerror = std::string("dlopen failed: unexpected TLS reference to ") +
+                                 referent + " in \"" + libpath + "\"";
+  ASSERT_SUBSTR(expected_dlerror.c_str(), dlerror());
+}
+
 TEST(dlfcn, dlopen_df_1_global) {
   void* handle = dlopen("libtest_dlopen_df_1_global.so", RTLD_NOW);
   ASSERT_TRUE(handle != nullptr) << dlerror();
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index 277b2e3..82ccf82 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -27,9 +27,11 @@
  */
 
 #include <dlfcn.h>
-#include <gtest/gtest.h>
 #include <link.h>
 
+#include <android-base/file.h>
+#include <gtest/gtest.h>
+
 #include <thread>
 
 #include "gtest_globals.h"
@@ -66,8 +68,7 @@
 }
 
 TEST(elftls_dl, dlopen_ie_error) {
-  std::string helper = GetTestlibRoot() +
-      "/elftls_dlopen_ie_error_helper/elftls_dlopen_ie_error_helper";
+  std::string helper = GetTestlibRoot() + "/elftls_dlopen_ie_error_helper";
   std::string src_path = GetTestlibRoot() + "/libtest_elftls_shared_var_ie.so";
   std::string dst_path = GetTestlibRoot() + "/libtest_elftls_shared_var.so";
 #if defined(__BIONIC__)
@@ -356,7 +357,7 @@
 
       // This test is also run with glibc, where dlpi_name may have relative path components, so
       // examine just the basename when searching for the library.
-      if (strcmp(basename(info->dlpi_name), "libtest_elftls_dynamic.so") != 0) return 0;
+      if (strcmp(android::base::Basename(info->dlpi_name).c_str(), "libtest_elftls_dynamic.so") != 0) return 0;
 
       tls_info.found = true;
       tls_info.modid = info->dlpi_tls_modid;
diff --git a/tests/execinfo_test.cpp b/tests/execinfo_test.cpp
new file mode 100644
index 0000000..b8e1325
--- /dev/null
+++ b/tests/execinfo_test.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <string.h>
+
+#include <fstream>
+#include <regex>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/test_utils.h>
+
+TEST(execinfo, backtrace_errors) {
+  void* frames[20];
+  ASSERT_EQ(0, backtrace(frames, 0));
+  ASSERT_EQ(0, backtrace(frames, -1));
+}
+
+static constexpr int kMaxFrames = 50;
+
+// Disable optimizations so that these functions show up properly in
+// the backtrace.
+#pragma clang optimize off
+extern "C" __attribute__((__noinline__)) void CallTwo(std::vector<void*>& frames) {
+  int num_frames = backtrace(frames.data(), static_cast<int>(frames.size()));
+  ASSERT_LT(0, num_frames);
+  frames.resize(static_cast<size_t>(num_frames));
+}
+
+extern "C" __attribute__((__noinline__)) void CallOne(std::vector<void*>& frames) {
+  CallTwo(frames);
+}
+#pragma clang optimize on
+
+static std::string DumpFrames(std::vector<void*>& frames) {
+  std::string frame_data;
+  for (auto frame : frames) {
+    frame_data += android::base::StringPrintf("[%p]", frame);
+    Dl_info info;
+    if (dladdr(frame, &info) != 0 && info.dli_sname != nullptr) {
+      frame_data += ' ';
+      frame_data += info.dli_sname;
+    }
+    frame_data += '\n';
+  }
+  return frame_data;
+}
+
+static size_t FindFunction(std::vector<void*>& frames, uintptr_t func_addr) {
+  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) {
+      return i + 1;
+    }
+  }
+  return 0;
+}
+
+static void VerifyCalls(std::vector<void*>& frames, size_t* one_idx = nullptr,
+                        size_t* two_idx = nullptr) {
+  // Try and find the CallOne and CallTwo function addresses.
+  size_t call_one_idx = FindFunction(frames, reinterpret_cast<uintptr_t>(&CallOne));
+  ASSERT_TRUE(call_one_idx != 0) << DumpFrames(frames);
+  size_t call_two_idx = FindFunction(frames, reinterpret_cast<uintptr_t>(&CallTwo));
+  ASSERT_TRUE(call_two_idx != 0) << DumpFrames(frames);
+
+  ASSERT_LT(call_two_idx, call_one_idx) << "CallTwo function found after CallOne\n"
+                                        << DumpFrames(frames);
+
+  if (one_idx != nullptr) *one_idx = call_one_idx;
+  if (two_idx != nullptr) *two_idx = call_two_idx;
+}
+
+TEST(execinfo, backtrace) {
+  std::vector<void*> frames(kMaxFrames);
+  ASSERT_NO_FATAL_FAILURE(CallOne(frames));
+
+  // Verfiy that there are at least two frames.
+  ASSERT_LT(3U, frames.size()) << DumpFrames(frames);
+
+  VerifyCalls(frames);
+}
+
+TEST(execinfo, backtrace_cutoff_frames) {
+  // Verify the max frames is handled properly
+  std::vector<void*> frames(1);
+  ASSERT_NO_FATAL_FAILURE(CallOne(frames));
+  ASSERT_EQ(1U, frames.size()) << DumpFrames(frames);
+}
+
+TEST(execinfo, backtrace_symbols_errors) {
+  void* frames[kMaxFrames];
+  // glibc incorrectly returns memory when a zero is passed in.
+  // Since we know this works properly on bionic, only verify
+  // this there.
+#if defined(__BIONIC__)
+  ASSERT_EQ(nullptr, backtrace_symbols(frames, 0));
+#endif
+  ASSERT_EQ(nullptr, backtrace_symbols(frames, -1));
+}
+
+static void VerifyLineFormat(std::string& line) {
+  // Verify that the format of the line is one of these:
+  //   elf_file(FuncName+0xFuncAddr) [0xAddress]
+  //   elf_file(+0xRelAddress) [0xAddress]
+  //   elf_file [0xAddress]
+  //   [0xAddress]
+#if defined(__GLIBC__)
+  // For some reason, glibc will print a space before [0xAddress] for
+  // backtrace symbols, and no space for backtrace_symbols_fd. Allow this
+  // only for glibc.
+  std::regex format1("[^\\(\\s]+\\([^\\+]+\\+0x[0-9a-fA-F]+\\) ?\\[0x[0-9a-fA-F]+\\]");
+  std::regex format2("[^\\(\\s]+\\(+\\+0x[0-9a-fA-F]+\\) ?\\[0x[0-9a-fA-F]+\\]");
+  std::regex format3("[^\\(\\s]+ ?\\[0x[0-9a-fA-F]+\\]");
+#else
+  std::regex format1("[^\\(\\s]+\\([^\\+]+\\+0x[0-9a-fA-F]+\\) \\[0x[0-9a-fA-F]+\\]");
+  std::regex format2("[^\\(\\s]+\\(+\\+0x[0-9a-fA-F]+\\) \\[0x[0-9a-fA-F]+\\]");
+  std::regex format3("[^\\(\\s]+ \\[0x[0-9a-fA-F]+\\]");
+#endif
+  std::regex format4("\\[0x[0-9a-fA-F]+\\]");
+
+  EXPECT_TRUE(std::regex_match(line, format1) || std::regex_match(line, format2) ||
+              std::regex_match(line, format3) || std::regex_match(line, format4))
+      << "Unknown format of line:\n"
+      << line;
+}
+
+static void VerifyLineFormat(char* raw_line, size_t length) {
+  std::string line(raw_line, length);
+  VerifyLineFormat(line);
+}
+
+TEST(execinfo, backtrace_symbols) {
+  std::vector<void*> frames(kMaxFrames);
+  ASSERT_NO_FATAL_FAILURE(CallOne(frames));
+  ASSERT_LT(3U, frames.size()) << DumpFrames(frames);
+
+  char** symbols = backtrace_symbols(frames.data(), static_cast<int>(frames.size()));
+  ASSERT_TRUE(symbols != nullptr);
+  for (size_t i = 0; i < frames.size(); i++) {
+    ASSERT_TRUE(frames[i] != nullptr);
+    VerifyLineFormat(symbols[i], strlen(symbols[i]));
+  }
+
+  size_t call_one_idx;
+  size_t call_two_idx;
+  ASSERT_NO_FATAL_FAILURE(VerifyCalls(frames, &call_one_idx, &call_two_idx));
+  // Now verify that those frames contain the function names we expect.
+  SCOPED_TRACE(DumpFrames(frames));
+  ASSERT_MATCH(symbols[call_one_idx - 1], "\\(CallOne+");
+  ASSERT_MATCH(symbols[call_two_idx - 1], "\\(CallTwo+");
+  free(symbols);
+}
+
+TEST(execinfo, backtrace_symbols_fd_errors) {
+  void* frames[kMaxFrames];
+  frames[0] = reinterpret_cast<void*>(&backtrace_symbols);
+
+  {
+    TemporaryFile tf;
+    backtrace_symbols_fd(frames, 0, tf.fd);
+    close(tf.fd);
+    std::string content;
+    ASSERT_TRUE(android::base::ReadFileToString(tf.path, &content));
+    // Verify that no data is written to the file.
+    ASSERT_TRUE(content.empty());
+  }
+
+  {
+    TemporaryFile tf;
+    backtrace_symbols_fd(frames, -1, tf.fd);
+    close(tf.fd);
+    std::string content;
+    ASSERT_TRUE(android::base::ReadFileToString(tf.path, &content));
+    // Verify that no data is written to the file.
+    ASSERT_TRUE(content.empty());
+  }
+
+  // Verify that there isn't a crash.
+  backtrace_symbols_fd(frames, 0, -1);
+}
+
+TEST(execinfo, backtrace_symbols_fd) {
+  std::vector<void*> frames(kMaxFrames);
+  ASSERT_NO_FATAL_FAILURE(CallOne(frames));
+  ASSERT_LT(3U, frames.size()) << DumpFrames(frames);
+
+  TemporaryFile tf;
+  backtrace_symbols_fd(frames.data(), static_cast<int>(frames.size()), tf.fd);
+  close(tf.fd);
+
+  size_t call_one_idx;
+  size_t call_two_idx;
+  ASSERT_NO_FATAL_FAILURE(VerifyCalls(frames, &call_one_idx, &call_two_idx));
+
+  std::ifstream frame_stream(tf.path);
+  ASSERT_TRUE(frame_stream.is_open());
+  size_t num_lines = 0;
+  std::string line;
+  while (std::getline(frame_stream, line)) {
+    ASSERT_FALSE(line.empty());
+    VerifyLineFormat(line);
+    num_lines++;
+
+    if (num_lines == call_one_idx) {
+      EXPECT_MATCH(line, "\\(CallOne+");
+    } else if (num_lines == call_two_idx) {
+      EXPECT_MATCH(line, "\\(CallTwo+");
+    }
+  }
+  ASSERT_EQ(num_lines, frames.size()) << "Number of lines in file does not match number of frames.";
+}
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index a8a4cc5..d50a438 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -28,6 +28,8 @@
 // Glibc v2.19 doesn't include these in fcntl.h so host builds will fail without.
 #if !defined(FALLOC_FL_PUNCH_HOLE) || !defined(FALLOC_FL_KEEP_SIZE)
 #include <linux/falloc.h>
+#endif
+#if !defined(EXT4_SUPER_MAGIC)
 #include <linux/magic.h>
 #endif
 
diff --git a/tests/fenv_test.cpp b/tests/fenv_test.cpp
index d495970..c5b5eca 100644
--- a/tests/fenv_test.cpp
+++ b/tests/fenv_test.cpp
@@ -20,6 +20,7 @@
 
 #include <fenv.h>
 #include <stdint.h>
+#include <sys/cdefs.h>
 
 static void TestRounding(float expectation1, float expectation2) {
   // Volatile to prevent compile-time evaluation.
@@ -170,6 +171,7 @@
 }
 
 TEST(fenv, fedisableexcept_fegetexcept) {
+#if !defined(ANDROID_HOST_MUSL)
   feclearexcept(FE_ALL_EXCEPT);
   ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT));
 
@@ -178,9 +180,13 @@
   ASSERT_EQ(0, fegetexcept());
   ASSERT_EQ(0, feraiseexcept(FE_INVALID));
   ASSERT_EQ(FE_INVALID, fetestexcept(FE_ALL_EXCEPT));
+#else
+  GTEST_SKIP() << "musl doesn't have fegetexcept";
+#endif
 }
 
 TEST(fenv, feenableexcept_fegetexcept) {
+#if !defined(ANDROID_HOST_MUSL)
 #if defined(__aarch64__) || defined(__arm__)
   // ARM doesn't support this. They used to if you go back far enough, but it was removed in
   // the Cortex-A8 between r3p1 and r3p2.
@@ -213,4 +219,7 @@
 
   AssertChildExited(pid, -SIGFPE);
 #endif
+#else
+  GTEST_SKIP() << "musl doesn't have fegetexcept";
+#endif
 }
diff --git a/tests/ftw_test.cpp b/tests/ftw_test.cpp
index 200ed4b..6473f71 100644
--- a/tests/ftw_test.cpp
+++ b/tests/ftw_test.cpp
@@ -106,7 +106,7 @@
   ASSERT_EQ(0, ftw(root.path, check_ftw, 128));
 }
 
-TEST(ftw, ftw64) {
+TEST(ftw, ftw64_smoke) {
   TemporaryDir root;
   MakeTree(root.path);
   ASSERT_EQ(0, ftw64(root.path, check_ftw64, 128));
@@ -118,7 +118,7 @@
   ASSERT_EQ(0, nftw(root.path, check_nftw, 128, 0));
 }
 
-TEST(ftw, nftw64) {
+TEST(ftw, nftw64_smoke) {
   TemporaryDir root;
   MakeTree(root.path);
   ASSERT_EQ(0, nftw64(root.path, check_nftw64, 128, 0));
diff --git a/tests/getcwd_test.cpp b/tests/getcwd_test.cpp
index 97b1d4f..4fec40b 100644
--- a/tests/getcwd_test.cpp
+++ b/tests/getcwd_test.cpp
@@ -20,6 +20,8 @@
 #include <limits.h>
 #include <unistd.h>
 
+#include <android-base/test_utils.h>
+
 #include "utils.h"
 
 TEST(getcwd, auto_full) {
diff --git a/tests/glob_test.cpp b/tests/glob_test.cpp
index b48f2af..6ce5f2f 100644
--- a/tests/glob_test.cpp
+++ b/tests/glob_test.cpp
@@ -17,6 +17,8 @@
 #include <glob.h>
 
 #include <dirent.h>
+#include <sys/cdefs.h>
+
 #include <gtest/gtest.h>
 
 #include <string>
@@ -34,6 +36,7 @@
 // Helper for use with GLOB_ALTDIRFUNC to iterate over the elements of `fake_dir`.
 //
 
+#if !defined(ANDROID_HOST_MUSL)
 static std::vector<std::string> fake_dir;
 static size_t fake_dir_offset;
 static void fake_closedir(void*) {
@@ -65,6 +68,7 @@
   g->gl_lstat = fake_lstat;
   g->gl_stat = fake_stat;
 }
+#endif
 
 TEST(glob, glob_result_GLOB_NOMATCH) {
   glob_t g = {};
@@ -102,6 +106,7 @@
   globfree(&g);
 }
 
+#if !defined(ANDROID_HOST_MUSL)
 static std::string g_failure_path;
 static int g_failure_errno;
 static int test_error_callback_result;
@@ -110,8 +115,10 @@
   g_failure_errno = failure_errno;
   return test_error_callback_result;
 }
+#endif
 
 TEST(glob, glob_gl_errfunc) {
+#if !defined(ANDROID_HOST_MUSL)
   glob_t g = {};
   InstallFake(&g);
 
@@ -126,15 +133,22 @@
   ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, test_error_callback, &g));
   ASSERT_EQ("/opendir-fail/", g_failure_path);
   ASSERT_EQ(EINVAL, g_failure_errno);
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_GLOB_ERR) {
+#if !defined(ANDROID_HOST_MUSL)
   glob_t g = {};
   InstallFake(&g);
 
   ASSERT_EQ(GLOB_NOMATCH, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC, nullptr, &g));
 
   ASSERT_EQ(GLOB_ABORTED, glob("/opendir-fail/x*", GLOB_ALTDIRFUNC | GLOB_ERR, nullptr, &g));
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_GLOB_MARK) {
@@ -172,6 +186,7 @@
 }
 
 TEST(glob, glob_GLOB_NOSORT) {
+#if !defined(ANDROID_HOST_MUSL)
   fake_dir = { "c", "a", "d", "b" };
 
   glob_t g = {};
@@ -194,9 +209,13 @@
   ASSERT_STREQ("d", g.gl_pathv[2]);
   ASSERT_STREQ("b", g.gl_pathv[3]);
   ASSERT_EQ(nullptr, g.gl_pathv[4]);
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_GLOB_MAGCHAR) {
+#if !defined(ANDROID_HOST_MUSL)
   glob_t g = {};
   ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", 0, nullptr, &g));
   ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
@@ -206,8 +225,12 @@
   // We can lie, but glob(3) will turn that into truth...
   ASSERT_EQ(GLOB_NOMATCH, glob("/does-not-exist", GLOB_MAGCHAR, nullptr, &g));
   ASSERT_TRUE((g.gl_flags & GLOB_MAGCHAR) == 0);
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_MAGCHAR";
+#endif
 }
 
+#if !defined(ANDROID_HOST_MUSL)
 static void CheckGlob(const char* pattern, const std::vector<std::string>& expected_matches) {
   glob_t g = {};
   InstallFake(&g);
@@ -224,16 +247,22 @@
   }
   globfree(&g);
 }
+#endif
 
 TEST(glob, glob_globbing) {
+#if !defined(ANDROID_HOST_MUSL)
   fake_dir = { "f1", "f2", "f30", "f40" };
 
   CheckGlob("f?", { "f1", "f2" });
   CheckGlob("f??", { "f30", "f40" });
   CheckGlob("f*", { "f1", "f2", "f30", "f40" });
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
 
 TEST(glob, glob_globbing_rsc) {
+#if !defined(ANDROID_HOST_MUSL)
   // https://research.swtch.com/glob
   fake_dir = { "axbxcxdxe" };
   CheckGlob("a*b*c*d*e*", { "axbxcxdxe" });
@@ -246,4 +275,7 @@
 
   fake_dir = { std::string(100, 'a') };
   CheckGlob("a*a*a*a*b", {});
+#else
+  GTEST_SKIP() << "musl doesn't support GLOB_ALTDIRFUNC";
+#endif
 }
diff --git a/tests/gtest_globals.cpp b/tests/gtest_globals.cpp
index 5b5ede8..11b2dff 100644
--- a/tests/gtest_globals.cpp
+++ b/tests/gtest_globals.cpp
@@ -25,8 +25,8 @@
 
 std::string GetTestlibRoot() {
   // Typically the executable is /data/nativetest[64]/bionic-unit-tests/bionic-unit-tests, and the
-  // test libraries are in /data/nativetest[64]/bionic-loader-test-libs.
-  std::string path = android::base::GetExecutableDirectory() + "/..";
+  // test libraries are in /data/nativetest[64]/bionic-unit-tests/bionic-loader-test-libs.
+  std::string path = android::base::GetExecutableDirectory();
 
   std::string out_path;
   if (!android::base::Realpath(path.c_str(), &out_path)) {
diff --git a/tests/gtest_globals_cts.cpp b/tests/gtest_globals_cts.cpp
deleted file mode 100644
index 78bb3ca..0000000
--- a/tests/gtest_globals_cts.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "gtest_globals.h"
-
-std::string GetTestlibRoot() {
-  return "/data/local/tmp/lib/bionic-loader-test-libs";
-}
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
new file mode 100644
index 0000000..b2c7780
--- /dev/null
+++ b/tests/gwp_asan_test.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <string>
+
+#if defined(__BIONIC__)
+
+#include "gwp_asan/options.h"
+#include "platform/bionic/malloc.h"
+#include "utils.h"
+
+void RunGwpAsanTest(const char* test_name) {
+  ExecTestHelper eh;
+  eh.SetEnv({"GWP_ASAN_SAMPLE_RATE=1", "GWP_ASAN_PROCESS_SAMPLING=1", "GWP_ASAN_MAX_ALLOCS=40000",
+             nullptr});
+  std::string filter_arg = "--gtest_filter=";
+  filter_arg += test_name;
+  std::string exec(testing::internal::GetArgvs()[0]);
+  eh.SetArgs({exec.c_str(), "--gtest_also_run_disabled_tests", filter_arg.c_str(), nullptr});
+  eh.Run([&]() { execve(exec.c_str(), eh.GetArgs(), eh.GetEnv()); },
+         /* expected_exit_status */ 0,
+         // |expected_output_regex|, ensure at least one test ran:
+         R"(\[  PASSED  \] [1-9]+0? test)");
+}
+
+// This file implements "torture testing" under GWP-ASan, where we sample every
+// single allocation. The upper limit for the number of GWP-ASan allocations in
+// the torture mode is is generally 40,000, so that svelte devices don't
+// explode, as this uses ~163MiB RAM (4KiB per live allocation).
+TEST(gwp_asan_integration, malloc_tests_under_torture) {
+  RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
+}
+
+#endif  // defined(__BIONIC__)
diff --git a/tests/headers/posix/Android.bp b/tests/headers/posix/Android.bp
index 0809cdb..4a20d45 100644
--- a/tests/headers/posix/Android.bp
+++ b/tests/headers/posix/Android.bp
@@ -33,5 +33,8 @@
         darwin: {
             enabled: false,
         },
+        musl: {
+            enabled: false,
+        },
     },
 }
diff --git a/tests/headers/posix/stdio_h.c b/tests/headers/posix/stdio_h.c
index cbeb0bc..57be0a0 100644
--- a/tests/headers/posix/stdio_h.c
+++ b/tests/headers/posix/stdio_h.c
@@ -110,7 +110,8 @@
   FUNCTION(getchar_unlocked, int (*f)(void));
   FUNCTION(getdelim, ssize_t (*f)(char**, size_t*, int, FILE*));
   FUNCTION(getline, ssize_t (*f)(char**, size_t*, FILE*));
-  FUNCTION(gets, char* (*f)(char*));
+  // gets() was removed in C11.
+  // FUNCTION(gets, char* (*f)(char*));
   FUNCTION(open_memstream, FILE* (*f)(char**, size_t*));
   FUNCTION(pclose, int (*f)(FILE*));
   FUNCTION(perror, void (*f)(const char*));
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index 5f5904f..96c2ffd 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -26,6 +26,7 @@
 
 #include "SignalUtils.h"
 
+#include <android-base/test_utils.h>
 #include <bionic/malloc_tagged_pointers.h>
 
 static bool KernelSupportsTaggedPointers() {
@@ -52,6 +53,9 @@
   if (mte_supported()) {
     GTEST_SKIP() << "Tagged pointers are not used on MTE hardware.";
   }
+  if (running_with_hwasan()) {
+    GTEST_SKIP() << "Tagged heap pointers feature is disabled under HWASan.";
+  }
 
   void *x = malloc(1);
 
@@ -78,10 +82,20 @@
 #endif // defined(__BIONIC__)
 }
 
+namespace {
 #if defined(__BIONIC__) && defined(__aarch64__)
 void ExitWithSiCode(int, siginfo_t* info, void*) {
   _exit(info->si_code);
 }
+
+template <typename Pred>
+class Or {
+  Pred A, B;
+
+ public:
+  Or(Pred A, Pred B) : A(A), B(B) {}
+  bool operator()(int exit_status) { return A(exit_status) || B(exit_status); }
+};
 #endif
 
 TEST(heap_tagging_level, sync_async_bad_accesses_die) {
@@ -91,6 +105,7 @@
   }
 
   std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
+  volatile int sink ATTRIBUTE_UNUSED;
 
   // We assume that scudo is used on all MTE enabled hardware; scudo inserts a header with a
   // mismatching tag before each allocation.
@@ -101,6 +116,12 @@
         p[-1] = 42;
       },
       testing::ExitedWithCode(SEGV_MTESERR), "");
+  EXPECT_EXIT(
+      {
+        ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
+        sink = p[-1];
+      },
+      testing::ExitedWithCode(SEGV_MTESERR), "");
 
   EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
   EXPECT_EXIT(
@@ -108,17 +129,27 @@
         ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
         p[-1] = 42;
       },
-      testing::ExitedWithCode(SEGV_MTEAERR), "");
+      Or(testing::ExitedWithCode(SEGV_MTESERR), testing::ExitedWithCode(SEGV_MTEAERR)), "");
+  EXPECT_EXIT(
+      {
+        ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
+        sink = p[-1];
+      },
+      Or(testing::ExitedWithCode(SEGV_MTESERR), testing::ExitedWithCode(SEGV_MTEAERR)), "");
 
   EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
-  volatile int oob ATTRIBUTE_UNUSED = p[-1];
+  sink = p[-1];
 #else
   GTEST_SKIP() << "bionic/arm64 only";
 #endif
 }
+}  // namespace
 
 TEST(heap_tagging_level, none_pointers_untagged) {
 #if defined(__BIONIC__)
+  if (running_with_hwasan()) {
+    GTEST_SKIP() << "HWASan is unaffected by heap tagging level.";
+  }
   EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
   std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
   EXPECT_EQ(untag_address(p.get()), p.get());
@@ -135,7 +166,13 @@
 
   EXPECT_FALSE(SetHeapTaggingLevel(static_cast<HeapTaggingLevel>(12345)));
 
-  if (mte_supported() && running_with_mte()) {
+  if (running_with_hwasan()) {
+    // NONE -> ...
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI));
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC));
+    EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
+  } else if (mte_supported() && running_with_mte()) {
     // ASYNC -> ...
     EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI));
     EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
@@ -185,24 +222,34 @@
 
 TEST_P(MemtagNoteTest, SEGV) {
 #if defined(__BIONIC__) && defined(__aarch64__)
-  if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) {
-    GTEST_SKIP() << "requires MTE support";
-  }
+  // Note that we do not check running_with_hwasan() - what matters here is whether the test binary
+  // itself is built with HWASan.
+  bool withHWASAN = __has_feature(hwaddress_sanitizer);
+  bool withMTE = getauxval(AT_HWCAP2) & HWCAP2_MTE;
 
   const char* kNoteSuffix[] = {"disabled", "async", "sync"};
-  const char* kExpectedOutput[] = {"normal exit\n", "SEGV_MTEAERR\n", "SEGV_MTESERR\n"};
+  const char* kExpectedOutputHWASAN[] = {".*tag-mismatch.*", ".*tag-mismatch.*",
+                                         ".*tag-mismatch.*"};
+  // Note that we do not check the exact si_code of the "async" variant, as it may be auto-upgraded
+  // to asymm or even sync.
+  const char* kExpectedOutputMTE[] = {"normal exit\n", "SEGV_MTE[AS]ERR\n", "SEGV_MTESERR\n"};
+  const char* kExpectedOutputNonMTE[] = {"normal exit\n", "normal exit\n", "normal exit\n"};
+  const char** kExpectedOutput =
+      withHWASAN ? kExpectedOutputHWASAN : (withMTE ? kExpectedOutputMTE : kExpectedOutputNonMTE);
+  const int kExpectedExitStatus = withHWASAN ? -SIGABRT : 0;
 
   MemtagNote note = std::get<0>(GetParam());
   bool isStatic = std::get<1>(GetParam());
   std::string helper_base = std::string("heap_tagging_") + (isStatic ? "static_" : "") +
                             kNoteSuffix[static_cast<int>(note)] + "_helper";
-  fprintf(stderr, "=== %s\n", helper_base.c_str());
-  std::string helper = GetTestlibRoot() + "/" + helper_base + "/" + helper_base;
+  std::string helper = GetTestlibRoot() + "/" + helper_base;
   chmod(helper.c_str(), 0755);
   ExecTestHelper eth;
   eth.SetArgs({helper.c_str(), nullptr});
-  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0,
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, kExpectedExitStatus,
           kExpectedOutput[static_cast<int>(note)]);
+#else
+  GTEST_SKIP() << "bionic/arm64 only";
 #endif
 }
 
diff --git a/tests/leak_test.cpp b/tests/leak_test.cpp
index 4ebf41f..0a881e1 100644
--- a/tests/leak_test.cpp
+++ b/tests/leak_test.cpp
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include <sys/user.h>
 #include <unistd.h>
 
@@ -44,7 +45,7 @@
     alive = false;
     for (size_t i = 0; i < tid_count; ++i) {
       if (tids[i] != 0) {
-        if (tgkill(getpid(), tids[i], 0) == 0) {
+        if (syscall(__NR_tgkill, getpid(), tids[i], 0) == 0) {
           alive = true;
         } else {
           EXPECT_EQ(errno, ESRCH);
@@ -111,11 +112,17 @@
 TEST(pthread_leak, join) {
   SKIP_WITH_NATIVE_BRIDGE;  // http://b/37920774
 
+  // Warm up. HWASan allocates an extra page on the first iteration, but never after.
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(
+                   &thread, nullptr, [](void*) -> void* { return nullptr; }, nullptr));
+  ASSERT_EQ(0, pthread_join(thread, nullptr));
+
   LeakChecker lc;
 
   for (int i = 0; i < 100; ++i) {
-    pthread_t thread;
-    ASSERT_EQ(0, pthread_create(&thread, nullptr, [](void*) -> void* { return nullptr; }, nullptr));
+    ASSERT_EQ(0, pthread_create(
+                     &thread, nullptr, [](void*) -> void* { return nullptr; }, nullptr));
     ASSERT_EQ(0, pthread_join(thread, nullptr));
   }
 }
diff --git a/tests/libgen_basename_test.cpp b/tests/libgen_basename_test.cpp
index 91ae960..300282c 100644
--- a/tests/libgen_basename_test.cpp
+++ b/tests/libgen_basename_test.cpp
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
+#include <sys/cdefs.h>
+
 #ifndef _GNU_SOURCE
   #define _GNU_SOURCE 1
 #endif
 
+#if !defined(ANDROID_HOST_MUSL)
 #include <string.h>
 
 #if defined(basename)
@@ -28,10 +31,12 @@
   return basename(in);
 }
 
+#endif
+
 #include <libgen.h>
 
-#if !defined(basename)
-  #error basename should be defined at this point
+#if !defined(basename) && !defined(ANDROID_HOST_MUSL)
+#error basename should be defined at this point
 #endif
 
 static char* posix_basename(char* in) {
@@ -41,12 +46,14 @@
 #include <errno.h>
 #include <gtest/gtest.h>
 
+#if !defined(ANDROID_HOST_MUSL)
 static void __TestGnuBasename(const char* in, const char* expected_out, int line) {
   errno = 0;
   const char* out = gnu_basename(in);
   ASSERT_STREQ(expected_out, out) << "(" << line << "): " << in << std::endl;
   ASSERT_EQ(0, errno) << "(" << line << "): " << in << std::endl;
 }
+#endif
 
 static void __TestPosixBasename(const char* in, const char* expected_out, int line) {
   char* writable_in = (in != nullptr) ? strdup(in) : nullptr;
@@ -61,6 +68,7 @@
 #define TestPosixBasename(in, expected) __TestPosixBasename(in, expected, __LINE__)
 
 TEST(libgen_basename, gnu_basename) {
+#if !defined(ANDROID_HOST_MUSL)
   // GNU's basename doesn't accept NULL
   // TestGnuBasename(NULL, ".");
   TestGnuBasename("", "");
@@ -73,6 +81,9 @@
   TestGnuBasename("..", "..");
   TestGnuBasename("///", "");
   TestGnuBasename("//usr//lib//", "");
+#else
+  GTEST_SKIP() << "musl doesn't have GNU basename";
+  #endif
 }
 
 TEST(libgen_basename, posix_basename) {
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index fabcd04..0046ef6 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -1181,14 +1181,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dl_df_1_global.cpp"],
     ldflags: ["-Wl,-z,global"],
-
-    target: {
-        host: {
-            // TODO (dimitry): host ld.gold does not yet support -z global
-            // remove this line once it is updated.
-            ldflags: ["-fuse-ld=bfd"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -1209,14 +1201,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dl_df_1_global_dummy.cpp"],
     ldflags: ["-Wl,-z,global"],
-
-    target: {
-        host: {
-            // TODO (dimitry): host ld.gold does not yet support -z global
-            // remove this line once it is updated.
-            ldflags: ["-fuse-ld=bfd"],
-        },
-    },
 }
 
 // -----------------------------------------------------------------------------
@@ -1667,3 +1651,71 @@
      memtag_heap: false,
    },
 }
+
+cc_genrule {
+    name: "libdlext_test_zip_zipaligned",
+     out: ["bionic-loader-test-libs/libdlext_test_zip/libdlext_test_zip_zipaligned.zip"],
+    tools: [
+        "soong_zip",
+        "bionic_tests_zipalign",
+    ],
+    srcs: [
+        ":libdlext_test_zip",
+        ":libatest_simple_zip",
+        ":exec_linker_helper",
+        ":exec_linker_helper_lib",
+    ],
+    cmd: "mkdir -p $(genDir)/zipdir/libdir &&" +
+        " cp $(in) $(genDir)/zipdir/libdir/ &&" +
+        " touch $(genDir)/zipdir/empty_file.txt &&" +
+        " $(location soong_zip) -o $(out).unaligned -L 0 -C $(genDir)/zipdir -D $(genDir)/zipdir &&" +
+        " $(location bionic_tests_zipalign) 4096 $(out).unaligned $(out)",
+
+    bazel_module: {
+        // Depends on soong_zip, which is not available yet.
+        bp2build_available: false
+    },
+}
+
+cc_genrule {
+    name: "libdlext_test_runpath_zip_zipaligned",
+    out: ["bionic-loader-test-libs/libdlext_test_runpath_zip/libdlext_test_runpath_zip_zipaligned.zip"],
+    tools: [
+        "soong_zip",
+        "bionic_tests_zipalign",
+    ],
+    srcs: [
+        ":libtest_dt_runpath_d_zip",
+        ":libtest_dt_runpath_a",
+        ":libtest_dt_runpath_b",
+        ":libtest_dt_runpath_c",
+        ":libtest_dt_runpath_x",
+        ":libtest_dt_runpath_y",
+    ],
+    cmd: "mkdir -p $(genDir)/zipdir/libdir &&" +
+        " if [[ \"$$CC_MULTILIB\" = lib32 ]]; then" +
+        "  PRIVATE_LIB_OR_LIB64=lib;" +
+        " else" +
+        "  PRIVATE_LIB_OR_LIB64=lib64;" +
+        " fi &&" +
+        " if [[ -n \"$$CC_NATIVE_BRIDGE\" ]]; then" +
+        "  PRIVATE_LIB_OR_LIB64=$$PRIVATE_LIB_OR_LIB64/$$CC_NATIVE_BRIDGE;" +
+        " fi &&" +
+        " mkdir -p $(genDir)/zipdir/libdir/dt_runpath_a &&" +
+        " mkdir -p $(genDir)/zipdir/libdir/dt_runpath_b_c_x &&" +
+        " mkdir -p $(genDir)/zipdir/libdir/dt_runpath_y/$$PRIVATE_LIB_OR_LIB64 &&" +
+        " cp $(location :libtest_dt_runpath_d_zip) $(genDir)/zipdir/libdir &&" +
+        " cp $(location :libtest_dt_runpath_a) $(genDir)/zipdir/libdir/dt_runpath_a &&" +
+        " cp $(location :libtest_dt_runpath_b) $(genDir)/zipdir/libdir/dt_runpath_b_c_x &&" +
+        " cp $(location :libtest_dt_runpath_c) $(genDir)/zipdir/libdir/dt_runpath_b_c_x &&" +
+        " cp $(location :libtest_dt_runpath_x) $(genDir)/zipdir/libdir/dt_runpath_b_c_x &&" +
+        " cp $(location :libtest_dt_runpath_y) $(genDir)/zipdir/libdir/dt_runpath_y/$$PRIVATE_LIB_OR_LIB64 &&" +
+        " touch $(genDir)/zipdir/empty_file.txt &&" +
+        " $(location soong_zip) -o $(out).unaligned -L 0 -C $(genDir)/zipdir -D $(genDir)/zipdir &&" +
+        " $(location bionic_tests_zipalign) 4096 $(out).unaligned $(out)",
+
+    bazel_module: {
+        // Depends on soong_zip, which is not available yet.
+        bp2build_available: false
+    },
+}
diff --git a/tests/libs/Android.build.dlext_testzip.mk b/tests/libs/Android.build.dlext_testzip.mk
deleted file mode 100644
index 66ed343..0000000
--- a/tests/libs/Android.build.dlext_testzip.mk
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-# Copyright (C) 2014 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# -----------------------------------------------------------------------------
-# Library used by dlext tests - zipped and aligned
-# -----------------------------------------------------------------------------
-
-BIONIC_TESTS_ZIPALIGN := $(HOST_OUT_EXECUTABLES)/bionic_tests_zipalign
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_CLASS := NATIVE_TESTS
-LOCAL_MODULE := libdlext_test_zip_zipaligned
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-LOCAL_MODULE_SUFFIX := .zip
-LOCAL_MODULE_PATH := $($(bionic_2nd_arch_prefix)TARGET_OUT_DATA_NATIVE_TESTS)/bionic-loader-test-libs/libdlext_test_zip
-LOCAL_2ND_ARCH_VAR_PREFIX := $(bionic_2nd_arch_prefix)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-my_shared_libs := \
-  $(call intermediates-dir-for,SHARED_LIBRARIES,libdlext_test_zip,,,$(bionic_2nd_arch_prefix))/libdlext_test_zip.so \
-  $(call intermediates-dir-for,SHARED_LIBRARIES,libatest_simple_zip,,,$(bionic_2nd_arch_prefix))/libatest_simple_zip.so \
-  $(call intermediates-dir-for,NATIVE_TESTS,exec_linker_helper,,,$(bionic_2nd_arch_prefix))/exec_linker_helper \
-  $(call intermediates-dir-for,SHARED_LIBRARIES,exec_linker_helper_lib,,,$(bionic_2nd_arch_prefix))/exec_linker_helper_lib.so
-
-$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBS := $(my_shared_libs)
-$(LOCAL_BUILT_MODULE): $(my_shared_libs) $(BIONIC_TESTS_ZIPALIGN)
-	@echo "Aligning zip: $@"
-	$(hide) rm -rf $@.unaligned $@ $(dir $@)/zipdir && mkdir -p $(dir $@)/zipdir/libdir
-	$(hide) cp $(PRIVATE_SHARED_LIBS) $(dir $@)/zipdir/libdir
-	$(hide) touch $(dir $@)/zipdir/empty_file.txt
-	$(hide) (cd $(dir $@)/zipdir && zip -qrD0 ../$(notdir $@).unaligned .)
-	$(hide) $(BIONIC_TESTS_ZIPALIGN) 4096 $@.unaligned $@
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_CLASS := NATIVE_TESTS
-LOCAL_MODULE := libdlext_test_runpath_zip_zipaligned
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-LOCAL_MODULE_SUFFIX := .zip
-LOCAL_MODULE_PATH := $($(bionic_2nd_arch_prefix)TARGET_OUT_DATA_NATIVE_TESTS)/bionic-loader-test-libs/libdlext_test_runpath_zip
-LOCAL_2ND_ARCH_VAR_PREFIX := $(bionic_2nd_arch_prefix)
-
-include $(BUILD_SYSTEM)/base_rules.mk
-lib_d := $(call intermediates-dir-for,SHARED_LIBRARIES,libtest_dt_runpath_d_zip,,,$(bionic_2nd_arch_prefix))/libtest_dt_runpath_d_zip.so
-lib_a := $(call intermediates-dir-for,SHARED_LIBRARIES,libtest_dt_runpath_a,,,$(bionic_2nd_arch_prefix))/libtest_dt_runpath_a.so
-lib_b := $(call intermediates-dir-for,SHARED_LIBRARIES,libtest_dt_runpath_b,,,$(bionic_2nd_arch_prefix))/libtest_dt_runpath_b.so
-lib_c := $(call intermediates-dir-for,SHARED_LIBRARIES,libtest_dt_runpath_c,,,$(bionic_2nd_arch_prefix))/libtest_dt_runpath_c.so
-lib_x := $(call intermediates-dir-for,SHARED_LIBRARIES,libtest_dt_runpath_x,,,$(bionic_2nd_arch_prefix))/libtest_dt_runpath_x.so
-lib_y := $(call intermediates-dir-for,SHARED_LIBRARIES,libtest_dt_runpath_y,,,$(bionic_2nd_arch_prefix))/libtest_dt_runpath_y.so
-
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_D := $(lib_d)
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_A := $(lib_a)
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_B := $(lib_b)
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_C := $(lib_c)
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_X := $(lib_x)
-$(LOCAL_BUILT_MODULE) : PRIVATE_LIB_Y := $(lib_y)
-ifeq ($(TARGET_IS_64_BIT),true)
-  ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-    $(LOCAL_BUILT_MODULE) : PRIVATE_LIB_OR_LIB64 := $(if $(LOCAL_2ND_ARCH_VAR_PREFIX),lib/$(TARGET_2ND_ARCH),lib64)
-  else
-    $(LOCAL_BUILT_MODULE) : PRIVATE_LIB_OR_LIB64 := $(if $(LOCAL_2ND_ARCH_VAR_PREFIX),lib,lib64)
-  endif
-else
-  ifeq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-    $(LOCAL_BUILT_MODULE) : PRIVATE_LIB_OR_LIB64 := $(if $(LOCAL_2ND_ARCH_VAR_PREFIX),lib/$(TARGET_2ND_ARCH),lib)
-  else
-    $(LOCAL_BUILT_MODULE) : PRIVATE_LIB_OR_LIB64 := lib
-  endif
-endif
-$(LOCAL_BUILT_MODULE) : $(lib_d) $(lib_a) $(lib_b) $(lib_c) $(lib_x) $(lib_y) $(BIONIC_TESTS_ZIPALIGN)
-	@echo "Aligning zip: $@"
-	$(hide) rm -rf $@.unaligned $@ $(dir $@)/zipdir && mkdir -p $(dir $@)/zipdir/libdir && \
-    mkdir -p $(dir $@)/zipdir/libdir/dt_runpath_a && mkdir -p $(dir $@)/zipdir/libdir/dt_runpath_b_c_x && \
-    mkdir -p $(dir $@)/zipdir/libdir/dt_runpath_y/$(PRIVATE_LIB_OR_LIB64)
-	$(hide) cp $(PRIVATE_LIB_D) $(dir $@)/zipdir/libdir
-	$(hide) cp $(PRIVATE_LIB_A) $(dir $@)/zipdir/libdir/dt_runpath_a
-	$(hide) cp $(PRIVATE_LIB_B) $(dir $@)/zipdir/libdir/dt_runpath_b_c_x
-	$(hide) cp $(PRIVATE_LIB_C) $(dir $@)/zipdir/libdir/dt_runpath_b_c_x
-	$(hide) cp $(PRIVATE_LIB_X) $(dir $@)/zipdir/libdir/dt_runpath_b_c_x
-	$(hide) cp $(PRIVATE_LIB_Y) $(dir $@)/zipdir/libdir/dt_runpath_y/$(PRIVATE_LIB_OR_LIB64)
-	$(hide) touch $(dir $@)/zipdir/empty_file.txt
-	$(hide) (cd $(dir $@)/zipdir && zip -qrD0 ../$(notdir $@).unaligned .)
-	$(hide) $(BIONIC_TESTS_ZIPALIGN) 4096 $@.unaligned $@
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
deleted file mode 100644
index 08416ac..0000000
--- a/tests/libs/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-# -----------------------------------------------------------------------------
-# Library used by dlext tests - zipped and aligned
-# -----------------------------------------------------------------------------
-include $(CLEAR_VARS)
-bionic_2nd_arch_prefix :=
-include $(LOCAL_PATH)/Android.build.dlext_testzip.mk
-ifneq ($(TARGET_2ND_ARCH),)
-  bionic_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
-  include $(LOCAL_PATH)/Android.build.dlext_testzip.mk
-endif
diff --git a/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp b/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp
index 4b13eba..624ae74 100644
--- a/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp
+++ b/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp
@@ -43,11 +43,13 @@
 extern "C" const char* v1 = "unset";
 extern "C" const char* v2 = "set";
 
-extern "C" void* is_ctor_called_ifun() {
-  return g_flag == 0 ? &var_false : &var_true;
+typedef const char* (*fn_ptr)();
+
+extern "C" fn_ptr is_ctor_called_ifun() {
+  return (fn_ptr)(g_flag == 0 ? &var_false : &var_true);
 }
 
-extern "C" void* foo_ifunc() {
-   char* choice = getenv("IFUNC_CHOICE");
-   return choice == nullptr ? &v1 : &v2;
+extern "C" fn_ptr foo_ifunc() {
+  char* choice = getenv("IFUNC_CHOICE");
+  return (fn_ptr)(choice == nullptr ? &v1 : &v2);
 }
diff --git a/tests/libs/heap_tagging_helper.cpp b/tests/libs/heap_tagging_helper.cpp
index 1a970f2..16a8c8b 100644
--- a/tests/libs/heap_tagging_helper.cpp
+++ b/tests/libs/heap_tagging_helper.cpp
@@ -16,7 +16,9 @@
 
 #include <signal.h>
 #include <stdio.h>
+#include <sys/auxv.h>
 #include <sys/cdefs.h>
+#include <sys/mman.h>
 #include <unistd.h>
 #include <memory>
 
@@ -37,6 +39,11 @@
   _exit(0);
 }
 
+void action2(int signo, siginfo_t* info __unused, void*) {
+  fprintf(stderr, "unexpected signal %d\n", signo);
+  _exit(0);
+}
+
 __attribute__((optnone)) int main() {
   struct sigaction sa = {};
   sa.sa_sigaction = action;
@@ -47,6 +54,37 @@
   volatile int oob = p[-1];
   (void)oob;
 
+#if defined(__BIONIC__) && defined(__aarch64__)
+  // If we get here, bad access on system heap memory did not trigger a fault.
+  // This suggests that MTE is disabled. Make sure that explicitly tagged PROT_MTE memory does not
+  // trigger a fault either.
+  if (getauxval(AT_HWCAP2) & HWCAP2_MTE) {
+    sa.sa_sigaction = action2;
+    sigaction(SIGSEGV, &sa, nullptr);
+
+    size_t page_size = static_cast<size_t>(sysconf(_SC_PAGESIZE));
+    void* p = mmap(nullptr, page_size, PROT_READ | PROT_WRITE | PROT_MTE,
+                   MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+    if (!p) {
+      fprintf(stderr, "mmap failed\n");
+      return 1;
+    }
+
+    void* q = p;
+    __asm__ __volatile__(
+        ".arch_extension memtag\n"
+        "irg %[Ptr], %[Ptr], xzr\n"
+        "stg %[Ptr], [%[Ptr]]\n"
+        "addg %[Ptr], %[Ptr], 0, 1\n"
+        "str xzr, [%[Ptr]]\n"
+        : [Ptr] "+&r"(q)
+        :
+        : "memory");
+
+    munmap(p, page_size);
+  }
+#endif  // __aarch64__
+
   fprintf(stderr, "normal exit\n");
   return 0;
 }
diff --git a/tests/malloc_iterate_test.cpp b/tests/malloc_iterate_test.cpp
index e896c90..297f637 100644
--- a/tests/malloc_iterate_test.cpp
+++ b/tests/malloc_iterate_test.cpp
@@ -26,6 +26,7 @@
 
 #include <vector>
 
+#include <android-base/test_utils.h>
 #include <async_safe/log.h>
 #include <procinfo/process_map.h>
 
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index d73f243..69f8506 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/auxv.h>
+#include <sys/cdefs.h>
 #include <sys/prctl.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -40,6 +41,7 @@
 #include <tinyxml2.h>
 
 #include <android-base/file.h>
+#include <android-base/test_utils.h>
 
 #include "utils.h"
 
@@ -55,10 +57,14 @@
 
 #define HAVE_REALLOCARRAY 1
 
-#else
+#elif defined(__GLIBC__)
 
 #define HAVE_REALLOCARRAY __GLIBC_PREREQ(2, 26)
 
+#elif defined(ANDROID_HOST_MUSL)
+
+#define HAVE_REALLOCARRAY 1
+
 #endif
 
 TEST(malloc, malloc_std) {
@@ -655,10 +661,14 @@
 }
 
 TEST(malloc, mallopt_smoke) {
+#if !defined(ANDROID_HOST_MUSL)
   errno = 0;
   ASSERT_EQ(0, mallopt(-1000, 1));
   // mallopt doesn't set errno.
   ASSERT_EQ(0, errno);
+#else
+  GTEST_SKIP() << "musl doesn't have mallopt";
+#endif
 }
 
 TEST(malloc, mallopt_decay) {
@@ -691,7 +701,10 @@
   FILE* fp = fdopen(tf.fd, "w+");
   tf.release();
   ASSERT_TRUE(fp != nullptr);
-  ASSERT_EQ(0, malloc_info(0, fp));
+  if (malloc_info(0, fp) != 0) {
+    *allocator_scudo = false;
+    return;
+  }
   ASSERT_EQ(0, fclose(fp));
 
   std::string contents;
@@ -753,7 +766,7 @@
 }
 
 TEST(malloc, mallinfo) {
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) || defined(ANDROID_HOST_MUSL)
   SKIP_WITH_HWASAN << "hwasan does not implement mallinfo";
   static size_t sizes[] = {
     8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
@@ -797,6 +810,77 @@
 #endif
 }
 
+TEST(malloc, mallinfo2) {
+#if defined(__BIONIC__) || defined(ANDROID_HOST_MUSL)
+  SKIP_WITH_HWASAN << "hwasan does not implement mallinfo2";
+  static size_t sizes[] = {8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000};
+
+  constexpr static size_t kMaxAllocs = 50;
+
+  for (size_t size : sizes) {
+    // If some of these allocations are stuck in a thread cache, then keep
+    // looping until we make an allocation that changes the total size of the
+    // memory allocated.
+    // jemalloc implementations counts the thread cache allocations against
+    // total memory allocated.
+    void* ptrs[kMaxAllocs] = {};
+    bool pass = false;
+    for (size_t i = 0; i < kMaxAllocs; i++) {
+      struct mallinfo info = mallinfo();
+      struct mallinfo2 info2 = mallinfo2();
+      // Verify that mallinfo and mallinfo2 are exactly the same.
+      ASSERT_EQ(static_cast<size_t>(info.arena), info2.arena);
+      ASSERT_EQ(static_cast<size_t>(info.ordblks), info2.ordblks);
+      ASSERT_EQ(static_cast<size_t>(info.smblks), info2.smblks);
+      ASSERT_EQ(static_cast<size_t>(info.hblks), info2.hblks);
+      ASSERT_EQ(static_cast<size_t>(info.hblkhd), info2.hblkhd);
+      ASSERT_EQ(static_cast<size_t>(info.usmblks), info2.usmblks);
+      ASSERT_EQ(static_cast<size_t>(info.fsmblks), info2.fsmblks);
+      ASSERT_EQ(static_cast<size_t>(info.uordblks), info2.uordblks);
+      ASSERT_EQ(static_cast<size_t>(info.fordblks), info2.fordblks);
+      ASSERT_EQ(static_cast<size_t>(info.keepcost), info2.keepcost);
+
+      size_t allocated = info2.uordblks;
+      ptrs[i] = malloc(size);
+      ASSERT_TRUE(ptrs[i] != nullptr);
+
+      info = mallinfo();
+      info2 = mallinfo2();
+      // Verify that mallinfo and mallinfo2 are exactly the same.
+      ASSERT_EQ(static_cast<size_t>(info.arena), info2.arena);
+      ASSERT_EQ(static_cast<size_t>(info.ordblks), info2.ordblks);
+      ASSERT_EQ(static_cast<size_t>(info.smblks), info2.smblks);
+      ASSERT_EQ(static_cast<size_t>(info.hblks), info2.hblks);
+      ASSERT_EQ(static_cast<size_t>(info.hblkhd), info2.hblkhd);
+      ASSERT_EQ(static_cast<size_t>(info.usmblks), info2.usmblks);
+      ASSERT_EQ(static_cast<size_t>(info.fsmblks), info2.fsmblks);
+      ASSERT_EQ(static_cast<size_t>(info.uordblks), info2.uordblks);
+      ASSERT_EQ(static_cast<size_t>(info.fordblks), info2.fordblks);
+      ASSERT_EQ(static_cast<size_t>(info.keepcost), info2.keepcost);
+
+      size_t new_allocated = info2.uordblks;
+      if (allocated != new_allocated) {
+        size_t usable_size = malloc_usable_size(ptrs[i]);
+        // Only check if the total got bigger by at least allocation size.
+        // Sometimes the mallinfo2 numbers can go backwards due to compaction
+        // and/or freeing of cached data.
+        if (new_allocated >= allocated + usable_size) {
+          pass = true;
+          break;
+        }
+      }
+    }
+    for (void* ptr : ptrs) {
+      free(ptr);
+    }
+    ASSERT_TRUE(pass) << "For size " << size << " allocated bytes did not increase after "
+                      << kMaxAllocs << " allocations.";
+  }
+#else
+  GTEST_SKIP() << "glibc is broken";
+#endif
+}
+
 template <typename Type>
 void __attribute__((optnone)) VerifyAlignment(Type* floating) {
   size_t expected_alignment = alignof(Type);
@@ -863,7 +947,7 @@
 }
 #endif
 
-TEST(malloc, align_check) {
+void AlignCheck() {
   // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_445
   // for a discussion of type alignment.
   ASSERT_NO_FATAL_FAILURE(TestAllocateType<float>());
@@ -887,22 +971,35 @@
 
 #if defined(__ANDROID__)
   // On Android, there is a lot of code that expects certain alignments:
-  // - Allocations of a size that rounds up to a multiple of 16 bytes
-  //   must have at least 16 byte alignment.
-  // - Allocations of a size that rounds up to a multiple of 8 bytes and
-  //   not 16 bytes, are only required to have at least 8 byte alignment.
-  // This is regardless of whether it is in a 32 bit or 64 bit environment.
+  //  1. Allocations of a size that rounds up to a multiple of 16 bytes
+  //     must have at least 16 byte alignment.
+  //  2. Allocations of a size that rounds up to a multiple of 8 bytes and
+  //     not 16 bytes, are only required to have at least 8 byte alignment.
+  // In addition, on Android clang has been configured for 64 bit such that:
+  //  3. Allocations <= 8 bytes must be aligned to at least 8 bytes.
+  //  4. Allocations > 8 bytes must be aligned to at least 16 bytes.
+  // For 32 bit environments, only the first two requirements must be met.
 
   // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2293.htm for
   // a discussion of this alignment mess. The code below is enforcing
   // strong-alignment, since who knows what code depends on this behavior now.
+  // As mentioned before, for 64 bit this will enforce the higher
+  // requirement since clang expects this behavior on Android now.
   for (size_t i = 1; i <= 128; i++) {
+#if defined(__LP64__)
+    if (i <= 8) {
+      AndroidVerifyAlignment(i, 8);
+    } else {
+      AndroidVerifyAlignment(i, 16);
+    }
+#else
     size_t rounded = (i + 7) & ~7;
     if ((rounded % 16) == 0) {
       AndroidVerifyAlignment(i, 16);
     } else {
       AndroidVerifyAlignment(i, 8);
     }
+#endif
     if (::testing::Test::HasFatalFailure()) {
       return;
     }
@@ -910,6 +1007,10 @@
 #endif
 }
 
+TEST(malloc, align_check) {
+  AlignCheck();
+}
+
 // Jemalloc doesn't pass this test right now, so leave it as disabled.
 TEST(malloc, DISABLED_alloc_after_fork) {
   // Both of these need to be a power of 2.
@@ -1259,6 +1360,29 @@
 #endif
 }
 
+#if defined(__BIONIC__)
+using Action = android_mallopt_gwp_asan_options_t::Action;
+TEST(android_mallopt, DISABLED_multiple_enable_gwp_asan) {
+  android_mallopt_gwp_asan_options_t options;
+  options.program_name = "";  // Don't infer GWP-ASan options from sysprops.
+  options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
+  // GWP-ASan should already be enabled. Trying to enable or disable it should
+  // always pass.
+  ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options)));
+  options.desire = Action::TURN_ON_WITH_SAMPLING;
+  ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options)));
+}
+#endif  // defined(__BIONIC__)
+
+TEST(android_mallopt, multiple_enable_gwp_asan) {
+#if defined(__BIONIC__)
+  // Always enable GWP-Asan, with default options.
+  RunGwpAsanTest("*.DISABLED_multiple_enable_gwp_asan");
+#else
+  GTEST_SKIP() << "bionic extension";
+#endif
+}
+
 void TestHeapZeroing(int num_iterations, int (*get_alloc_size)(int iteration)) {
   std::vector<void*> allocs;
   constexpr int kMaxBytesToCheckZero = 64;
@@ -1342,7 +1466,7 @@
   ASSERT_EQ(0, sem_post(&sem));
 
   int my_tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
-  ASSERT_EQ(PR_MTE_TCF_NONE, my_tagged_addr_ctrl & PR_MTE_TCF_MASK);
+  ASSERT_EQ(static_cast<unsigned long>(PR_MTE_TCF_NONE), my_tagged_addr_ctrl & PR_MTE_TCF_MASK);
 
   void* retval;
   ASSERT_EQ(0, pthread_join(thread, &retval));
@@ -1355,6 +1479,8 @@
 
 TEST(malloc, allocation_slack) {
 #if defined(__BIONIC__)
+  SKIP_WITH_NATIVE_BRIDGE;  // http://b/189606147
+
   bool allocator_scudo;
   GetAllocatorVersion(&allocator_scudo);
   if (!allocator_scudo) {
@@ -1371,3 +1497,25 @@
   GTEST_SKIP() << "bionic extension";
 #endif
 }
+
+// Regression test for b/206701345 -- scudo bug, MTE only.
+// Fix: https://reviews.llvm.org/D105261
+// Fix: https://android-review.googlesource.com/c/platform/external/scudo/+/1763655
+TEST(malloc, realloc_mte_crash_b206701345) {
+  // We want to hit in-place realloc at the very end of an mmap-ed region.  Not
+  // all size classes allow such placement - mmap size has to be divisible by
+  // the block size. At the time of writing this could only be reproduced with
+  // 64 byte size class (i.e. 48 byte allocations), but that may change in the
+  // future. Try several different classes at the lower end.
+  std::vector<void*> ptrs(10000);
+  for (int i = 1; i < 32; ++i) {
+    size_t sz = 16 * i - 1;
+    for (void*& p : ptrs) {
+      p = realloc(malloc(sz), sz + 1);
+    }
+
+    for (void* p : ptrs) {
+      free(p);
+    }
+  }
+}
diff --git a/tests/math_test.cpp b/tests/math_test.cpp
index 9f7e65b..76b5078 100644
--- a/tests/math_test.cpp
+++ b/tests/math_test.cpp
@@ -62,6 +62,7 @@
 #include <float.h>
 #include <limits.h>
 #include <stdint.h>
+#include <sys/cdefs.h>
 
 #include <android-base/scopeguard.h>
 
@@ -201,7 +202,7 @@
 }
 
 TEST(MATH_TEST, __fpclassifyd) {
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
 #define __fpclassifyd __fpclassify
 #endif
   ASSERT_EQ(FP_INFINITE, __fpclassifyd(HUGE_VAL));
@@ -246,6 +247,8 @@
 TEST(MATH_TEST, __isfinite) {
 #if defined(__GLIBC__)
 #define __isfinite __finite
+#elif defined(ANDROID_HOST_MUSL)
+#define __isfinite isfinite
 #endif
   ASSERT_TRUE(__isfinite(123.0));
   ASSERT_FALSE(__isfinite(HUGE_VAL));
@@ -255,6 +258,8 @@
 TEST(MATH_TEST, __isfinitef) {
 #if defined(__GLIBC__)
 #define __isfinitef __finitef
+#elif defined(ANDROID_HOST_MUSL)
+#define __isfinitef isfinite
 #endif
   ASSERT_TRUE(__isfinitef(123.0f));
   ASSERT_FALSE(__isfinitef(HUGE_VALF));
@@ -264,6 +269,8 @@
 TEST(MATH_TEST, isfinitef) {
 #if defined(__GLIBC__)
 #define isfinitef __finitef
+#elif defined(ANDROID_HOST_MUSL)
+#define isfinitef isfinite
 #endif
   ASSERT_TRUE(isfinitef(123.0f));
   ASSERT_FALSE(isfinitef(HUGE_VALF));
@@ -273,6 +280,8 @@
 TEST(MATH_TEST, __isfinitel) {
 #if defined(__GLIBC__)
 #define __isfinitel __finitel
+#elif defined(ANDROID_HOST_MUSL)
+#define __isfinitel isfinite
 #endif
   ASSERT_TRUE(__isfinitel(123.0L));
   ASSERT_FALSE(__isfinitel(HUGE_VALL));
@@ -282,6 +291,8 @@
 TEST(MATH_TEST, isfinitel) {
 #if defined(__GLIBC__)
 #define isfinitel __finitel
+#elif defined(ANDROID_HOST_MUSL)
+#define isfinitel isfinite
 #endif
   ASSERT_TRUE(isfinitel(123.0L));
   ASSERT_FALSE(isfinitel(HUGE_VALL));
@@ -309,30 +320,45 @@
 extern "C" int isinfl(long double);
 
 TEST(MATH_TEST, __isinf) {
+#if defined(ANDROID_HOST_MUSL)
+#define __isinf isinf
+#endif
   ASSERT_FALSE(__isinf(123.0));
   ASSERT_TRUE(__isinf(HUGE_VAL));
   ASSERT_TRUE(__isinf(-HUGE_VAL));
 }
 
 TEST(MATH_TEST, __isinff) {
+#if defined(ANDROID_HOST_MUSL)
+#define __isinff isinf
+#endif
   ASSERT_FALSE(__isinff(123.0f));
   ASSERT_TRUE(__isinff(HUGE_VALF));
   ASSERT_TRUE(__isinff(-HUGE_VALF));
 }
 
 TEST(MATH_TEST, isinff) {
+#if defined(ANDROID_HOST_MUSL)
+#define isinff isinf
+#endif
   ASSERT_FALSE(isinff(123.0f));
   ASSERT_TRUE(isinff(HUGE_VALF));
   ASSERT_TRUE(isinff(-HUGE_VALF));
 }
 
 TEST(MATH_TEST, __isinfl) {
+#if defined(ANDROID_HOST_MUSL)
+#define __isinfl isinf
+#endif
   ASSERT_FALSE(__isinfl(123.0L));
   ASSERT_TRUE(__isinfl(HUGE_VALL));
   ASSERT_TRUE(__isinfl(-HUGE_VALL));
 }
 
 TEST(MATH_TEST, isinfl) {
+#if defined(ANDROID_HOST_MUSL)
+#define isinfl isinf
+#endif
   ASSERT_FALSE(isinfl(123.0L));
   ASSERT_TRUE(isinfl(HUGE_VALL));
   ASSERT_TRUE(isinfl(-HUGE_VALL));
@@ -352,26 +378,41 @@
 extern "C" int isnanl(long double);
 
 TEST(MATH_TEST, __isnan) {
+#if defined(ANDROID_HOST_MUSL)
+#define __isnan isnan
+#endif
   ASSERT_FALSE(__isnan(123.0));
   ASSERT_TRUE(__isnan(nan("")));
 }
 
 TEST(MATH_TEST, __isnanf) {
+#if defined(ANDROID_HOST_MUSL)
+#define __isnanf isnan
+#endif
   ASSERT_FALSE(__isnanf(123.0f));
   ASSERT_TRUE(__isnanf(nanf("")));
 }
 
 TEST(MATH_TEST, isnanf) {
+#if defined(ANDROID_HOST_MUSL)
+#define isnanf isnan
+#endif
   ASSERT_FALSE(isnanf(123.0f));
   ASSERT_TRUE(isnanf(nanf("")));
 }
 
 TEST(MATH_TEST, __isnanl) {
+#if defined(ANDROID_HOST_MUSL)
+#define __isnanl isnan
+#endif
   ASSERT_FALSE(__isnanl(123.0L));
   ASSERT_TRUE(__isnanl(nanl("")));
 }
 
 TEST(MATH_TEST, isnanl) {
+#if defined(ANDROID_HOST_MUSL)
+#define isnanl isnan
+#endif
   ASSERT_FALSE(isnanl(123.0L));
   ASSERT_TRUE(isnanl(nanl("")));
 }
@@ -1345,11 +1386,16 @@
 }
 
 TEST(MATH_TEST, significandl) {
+#if !defined(ANDROID_HOST_MUSL)
   ASSERT_DOUBLE_EQ(0.0L, significandl(0.0L));
   ASSERT_DOUBLE_EQ(1.2L, significandl(1.2L));
   ASSERT_DOUBLE_EQ(1.53125L, significandl(12.25L));
+#else
+  GTEST_SKIP() << "musl doesn't have significandl";
+#endif
 }
 
+
 TEST(MATH_TEST, scalb) {
   ASSERT_DOUBLE_EQ(12.0, scalb(3.0, 2.0));
 }
@@ -1383,11 +1429,19 @@
 }
 
 TEST(MATH_TEST, gamma) {
+#if !defined(ANDROID_HOST_MUSL)
   ASSERT_DOUBLE_EQ(log(24.0), gamma(5.0));
+#else
+  GTEST_SKIP() << "musl doesn't have gamma";
+#endif
 }
 
 TEST(MATH_TEST, gammaf) {
+#if !defined(ANDROID_HOST_MUSL)
   ASSERT_FLOAT_EQ(logf(24.0f), gammaf(5.0f));
+#else
+  GTEST_SKIP() << "musl doesn't have gammaf";
+#endif
 }
 
 TEST(MATH_TEST, gamma_r) {
diff --git a/tests/netdb_test.cpp b/tests/netdb_test.cpp
index a805693..1cb569c 100644
--- a/tests/netdb_test.cpp
+++ b/tests/netdb_test.cpp
@@ -19,10 +19,11 @@
 #include <gtest/gtest.h>
 
 #include <arpa/inet.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
 #include <netinet/in.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
 // https://code.google.com/p/android/issues/detail?id=13228
 TEST(netdb, freeaddrinfo_NULL) {
@@ -265,11 +266,18 @@
   ASSERT_EQ(0, hp->h_addr[0]);
 }
 
+#if defined(ANDROID_HOST_MUSL)
+// musl doesn't define NETDB_INTERNAL.  It also never sets *err to -1, but
+// since gethostbyname_r is a glibc extension, the difference in behavior
+// between musl and  glibc should probably be considered a bug in musl.
+#define NETDB_INTERNAL -1
+#endif
+
 TEST(netdb, gethostbyname_r_ERANGE) {
   hostent hent;
   hostent *hp;
   char buf[4]; // Use too small buffer.
-  int err;
+  int err = 0;
   int result = gethostbyname_r("localhost", &hent, buf, sizeof(buf), &hp, &err);
   EXPECT_EQ(NETDB_INTERNAL, err);
   EXPECT_EQ(ERANGE, result);
@@ -280,7 +288,7 @@
   hostent hent;
   hostent *hp;
   char buf[4]; // Use too small buffer.
-  int err;
+  int err = 0;
   int result = gethostbyname2_r("localhost", AF_INET, &hent, buf, sizeof(buf), &hp, &err);
   EXPECT_EQ(NETDB_INTERNAL, err);
   EXPECT_EQ(ERANGE, result);
@@ -292,7 +300,7 @@
   hostent hent;
   hostent *hp;
   char buf[4]; // Use too small buffer.
-  int err;
+  int err = 0;
   int result = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &hent, buf, sizeof(buf), &hp, &err);
   EXPECT_EQ(NETDB_INTERNAL, err);
   EXPECT_EQ(ERANGE, result);
diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp
index 437e180..b7dd7c5 100644
--- a/tests/netinet_in_test.cpp
+++ b/tests/netinet_in_test.cpp
@@ -17,6 +17,7 @@
 #include <netinet/in.h>
 
 #include <errno.h>
+#include <sys/cdefs.h>
 
 #include <gtest/gtest.h>
 
@@ -31,6 +32,7 @@
 static constexpr uint64_t be64 = 0xf0debc9a78563412;
 
 TEST(netinet_in, bindresvport) {
+#if !defined(ANDROID_HOST_MUSL)
   // This isn't something we can usually test (because you need to be root),
   // so just check the symbol's there.
   ASSERT_EQ(-1, bindresvport(-1, nullptr));
@@ -40,6 +42,9 @@
   errno = 0;
   ASSERT_EQ(-1, bindresvport(-1, &sin));
   ASSERT_EQ(EPFNOSUPPORT, errno);
+#else
+  GTEST_SKIP() << "musl doesn't support bindresvport";
+#endif
 }
 
 TEST(netinet_in, in6addr_any) {
diff --git a/tests/prebuilt-elf-files/arm/libtest_invalid-local-tls.so b/tests/prebuilt-elf-files/arm/libtest_invalid-local-tls.so
new file mode 100755
index 0000000..a42848d
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm/libtest_invalid-local-tls.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so b/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so
new file mode 100755
index 0000000..20c5765
--- /dev/null
+++ b/tests/prebuilt-elf-files/arm64/libtest_invalid-local-tls.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh b/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh
new file mode 100755
index 0000000..0f3e736
--- /dev/null
+++ b/tests/prebuilt-elf-files/gen-libtest_invalid-local-tls.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Bionic doesn't support the references to STB_LOCAL symbols of type STT_TLS
+# and STT_SECTION that ld.gold generates. Set NDK21E to the path to a copy of
+# NDK r21e, which still has ld.gold (unlike the platform build or newer NDKs).
+
+set -e
+
+cat >test.c <<EOF
+  static __thread int tls_var_1;
+  extern __thread int tls_var_2;
+  int* getaddr1() { return &tls_var_1; }
+  int* getaddr2() { return &tls_var_2; }
+EOF
+cat >test2.c <<EOF
+  __attribute__((visibility("hidden"))) __thread int tls_var_2;
+EOF
+
+build() {
+  arch=$1
+  target=$2
+  $NDK21E/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -O2 --target=$target \
+      -fpic -shared -o $arch/libtest_invalid-local-tls.so -fno-emulated-tls \
+      -fuse-ld=gold test.c test2.c
+}
+
+build arm armv7a-linux-androideabi29
+build arm64 aarch64-linux-android29
+build x86 i686-linux-android29
+build x86_64 x86_64-linux-android29
diff --git a/tests/prebuilt-elf-files/x86/libtest_invalid-local-tls.so b/tests/prebuilt-elf-files/x86/libtest_invalid-local-tls.so
new file mode 100755
index 0000000..879f6a1
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86/libtest_invalid-local-tls.so
Binary files differ
diff --git a/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so b/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so
new file mode 100755
index 0000000..5b689ba
--- /dev/null
+++ b/tests/prebuilt-elf-files/x86_64/libtest_invalid-local-tls.so
Binary files differ
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 1a00460..907a35c 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -23,6 +23,7 @@
 #include <pthread.h>
 #include <signal.h>
 #include <stdio.h>
+#include <sys/cdefs.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -844,6 +845,8 @@
     ASSERT_EQ(pshared_value_array[i], pshared);
   }
 
+#if !defined(ANDROID_HOST_MUSL)
+  // musl doesn't have pthread_rwlockattr_setkind_np
   int kind_array[] = {PTHREAD_RWLOCK_PREFER_READER_NP,
                       PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP};
   for (size_t i = 0; i < sizeof(kind_array) / sizeof(kind_array[0]); ++i) {
@@ -852,6 +855,7 @@
     ASSERT_EQ(0, pthread_rwlockattr_getkind_np(&attr, &kind));
     ASSERT_EQ(kind_array[i], kind);
   }
+#endif
 
   ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr));
 }
@@ -1235,6 +1239,8 @@
 #endif  // __BIONIC__
 }
 
+#if !defined(ANDROID_HOST_MUSL)
+// musl doesn't have pthread_rwlockattr_setkind_np
 class RwlockKindTestHelper {
  private:
   struct ThreadArg {
@@ -1302,8 +1308,10 @@
     delete arg;
   }
 };
+#endif
 
 TEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_READER_NP) {
+#if !defined(ANDROID_HOST_MUSL)
   RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_READER_NP);
   ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock));
 
@@ -1319,9 +1327,13 @@
 
   ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock));
   ASSERT_EQ(0, pthread_join(writer_thread, nullptr));
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_rwlockattr_setkind_np";
+#endif
 }
 
 TEST(pthread, pthread_rwlock_kind_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) {
+#if !defined(ANDROID_HOST_MUSL)
   RwlockKindTestHelper helper(PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
   ASSERT_EQ(0, pthread_rwlock_rdlock(&helper.lock));
 
@@ -1338,6 +1350,9 @@
   ASSERT_EQ(0, pthread_rwlock_unlock(&helper.lock));
   ASSERT_EQ(0, pthread_join(writer_thread, nullptr));
   ASSERT_EQ(0, pthread_join(reader_thread, nullptr));
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_rwlockattr_setkind_np";
+#endif
 }
 
 static int g_once_fn_call_count = 0;
@@ -1478,6 +1493,7 @@
   };
   std::atomic<Progress> progress;
   pthread_t thread;
+  timespec ts;
   std::function<int (pthread_cond_t* cond, pthread_mutex_t* mutex)> wait_function;
 
  protected:
@@ -1509,11 +1525,10 @@
       clockid_t clock,
       std::function<int(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* timeout)>
           wait_function) {
-    timespec ts;
     ASSERT_EQ(0, clock_gettime(clock, &ts));
     ts.tv_sec += 1;
 
-    StartWaitingThread([&wait_function, &ts](pthread_cond_t* cond, pthread_mutex_t* mutex) {
+    StartWaitingThread([&wait_function, this](pthread_cond_t* cond, pthread_mutex_t* mutex) {
       return wait_function(cond, mutex, &ts);
     });
 
@@ -2152,6 +2167,9 @@
   ASSERT_EQ(0, memcmp(&lock_normal, &m1.lock, sizeof(pthread_mutex_t)));
   pthread_mutex_destroy(&lock_normal);
 
+#if !defined(ANDROID_HOST_MUSL)
+  // musl doesn't support PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP or
+  // PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.
   pthread_mutex_t lock_errorcheck = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
   PthreadMutex m2(PTHREAD_MUTEX_ERRORCHECK);
   ASSERT_EQ(0, memcmp(&lock_errorcheck, &m2.lock, sizeof(pthread_mutex_t)));
@@ -2161,6 +2179,7 @@
   PthreadMutex m3(PTHREAD_MUTEX_RECURSIVE);
   ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t)));
   ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive));
+#endif
 }
 
 class MutexWakeupHelper {
diff --git a/tests/resolv_test.cpp b/tests/resolv_test.cpp
index 5743239..0cd8e63 100644
--- a/tests/resolv_test.cpp
+++ b/tests/resolv_test.cpp
@@ -28,6 +28,8 @@
 
 #include <resolv.h>
 
+#include <sys/cdefs.h>
+
 #include <gtest/gtest.h>
 
 TEST(resolv, b64_pton_28035006) {
@@ -60,13 +62,21 @@
 }
 
 TEST(resolv, p_class) {
+#if !defined(ANDROID_HOST_MUSL)
   ASSERT_STREQ("IN", p_class(ns_c_in));
   ASSERT_STREQ("BADCLASS", p_class(-1));
+#else
+  GTEST_SKIP() << "musl doesn't have p_class";
+#endif
 }
 
 TEST(resolv, p_type) {
+#if !defined(ANDROID_HOST_MUSL)
   ASSERT_STREQ("AAAA", p_type(ns_t_aaaa));
   ASSERT_STREQ("BADTYPE", p_type(-1));
+#else
+  GTEST_SKIP() << "musl doesn't have p_type";
+#endif
 }
 
 TEST(resolv, res_init) {
@@ -74,5 +84,9 @@
 }
 
 TEST(resolv, res_randomid) {
+#if !defined(ANDROID_HOST_MUSL)
   res_randomid();
+#else
+  GTEST_SKIP() << "musl doesn't have res_randomid";
+#endif
 }
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index ee126eb..472aa20 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -22,6 +22,7 @@
 #include <unistd.h>
 
 #include <android-base/silent_death_test.h>
+#include <android-base/test_utils.h>
 
 #include "SignalUtils.h"
 
@@ -273,6 +274,7 @@
 }
 
 TEST(setjmp, bug_152210274) {
+  SKIP_WITH_HWASAN; // b/227390656
   // Ensure that we never have a mangled value in the stack pointer.
 #if defined(__BIONIC__)
   struct sigaction sa = {.sa_flags = SA_SIGINFO, .sa_sigaction = [](int, siginfo_t*, void*) {}};
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index ffbb667..5bda8b3 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -16,6 +16,7 @@
 
 #include <errno.h>
 #include <signal.h>
+#include <sys/cdefs.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -554,8 +555,12 @@
 }
 
 TEST(signal, sys_siglist) {
+#if !defined(ANDROID_HOST_MUSL)
   ASSERT_TRUE(sys_siglist[0] == nullptr);
   ASSERT_STREQ("Hangup", sys_siglist[SIGHUP]);
+#else
+  GTEST_SKIP() << "musl doesn't have sys_siglist";
+#endif
 }
 
 TEST(signal, limits) {
@@ -582,7 +587,7 @@
 
 TEST(signal, sigqueue) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
@@ -590,17 +595,22 @@
 }
 
 TEST(signal, pthread_sigqueue_self) {
+#if !defined(ANDROID_HOST_MUSL)
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, pthread_sigqueue(pthread_self(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_sigqueue";
+#endif
 }
 
 TEST(signal, pthread_sigqueue_other) {
+#if !defined(ANDROID_HOST_MUSL)
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
 
   sigset_t mask;
   sigfillset(&mask);
@@ -621,6 +631,9 @@
   ASSERT_EQ(0, errno);
   pthread_join(thread, nullptr);
   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
+#else
+  GTEST_SKIP() << "musl doesn't have pthread_sigqueue";
+#endif
 }
 
 TEST(signal, sigwait_SIGALRM) {
@@ -633,7 +646,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -652,7 +665,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGRTMIN.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGRTMIN.
@@ -671,7 +684,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -693,7 +706,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGRTMIN.
-  sigval_t sigval = {.sival_int = 1};
+  sigval sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGRTMIN.
@@ -715,7 +728,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = { .sival_int = 1 };
+  sigval sigval = { .sival_int = 1 };
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -736,7 +749,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval = { .sival_int = 1 };
+  sigval sigval = { .sival_int = 1 };
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGALRM.
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index d7ed970..a9563b8 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -18,6 +18,8 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/cdefs.h>
+
 #include <gtest/gtest.h>
 
 #include "SignalUtils.h"
@@ -31,7 +33,7 @@
 # if !defined(POSIX_SPAWN_SETSID)
 #  define POSIX_SPAWN_SETSID 0
 # endif
-#else
+#elif defined(__BIONIC__)
 #include <platform/bionic/reserved_signals.h>
 #endif
 
@@ -379,7 +381,7 @@
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGMASK) {
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
   GTEST_SKIP() << "glibc doesn't ignore the same signals.";
 #else
   // Block SIGBUS in the parent...
@@ -417,7 +419,7 @@
 }
 
 TEST(spawn, posix_spawn_POSIX_SPAWN_SETSIGDEF) {
-#if defined(__GLIBC__)
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
   GTEST_SKIP() << "glibc doesn't ignore the same signals.";
 #else
   // Ignore SIGALRM and SIGCONT in the parent...
@@ -506,3 +508,42 @@
 
   AssertChildExited(pid, 99);
 }
+
+TEST(spawn, posix_spawn_dup2_CLOEXEC) {
+  int fds[2];
+  ASSERT_NE(-1, pipe(fds));
+
+  posix_spawn_file_actions_t fa;
+  ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
+
+  int fd = open("/proc/version", O_RDONLY | O_CLOEXEC);
+  ASSERT_NE(-1, fd);
+
+  ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
+  ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
+  // dup2() is a no-op when the two fds are the same, so this won't clear
+  // O_CLOEXEC unless we're doing extra work to make that happen.
+  ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fd, fd));
+
+  // Read /proc/self/fd/<fd> in the child...
+  std::string fdinfo_path = android::base::StringPrintf("/proc/self/fd/%d", fd);
+  ExecTestHelper eth;
+  eth.SetArgs({"cat", fdinfo_path.c_str(), nullptr});
+  pid_t pid;
+  ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), &fa, nullptr, eth.GetArgs(), eth.GetEnv()));
+  ASSERT_EQ(0, posix_spawn_file_actions_destroy(&fa));
+  ASSERT_EQ(0, close(fds[1]));
+  std::string content;
+  ASSERT_TRUE(android::base::ReadFdToString(fds[0], &content));
+  ASSERT_EQ(0, close(fds[0]));
+
+  // ...and compare that to the parent. This is overkill really, since the very
+  // fact that the child had a valid file descriptor strongly implies that we
+  // removed O_CLOEXEC, but we may as well check that the child ended up with
+  // the *right* file descriptor :-)
+  std::string expected;
+  ASSERT_TRUE(android::base::ReadFdToString(fd, &expected));
+  ASSERT_EQ(expected, content);
+
+  AssertChildExited(pid, 0);
+}
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 5736e17..87031f6 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -19,14 +19,15 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <locale.h>
 #include <math.h>
 #include <stdio.h>
-#include <sys/types.h>
+#include <sys/cdefs.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 #include <wchar.h>
-#include <locale.h>
 
 #include <string>
 #include <thread>
@@ -363,10 +364,13 @@
 
 TEST_F(STDIO_DEATHTEST, snprintf_n) {
 #if defined(__BIONIC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
   // http://b/14492135 and http://b/31832608.
   char buf[32];
   int i = 1234;
   EXPECT_DEATH(snprintf(buf, sizeof(buf), "a %n b", &i), "%n not allowed on Android");
+#pragma GCC diagnostic pop
 #else
   GTEST_SKIP() << "glibc does allow %n";
 #endif
@@ -2740,8 +2744,8 @@
 }
 
 TEST(STDIO_TEST, renameat2) {
-#if defined(__GLIBC__)
-  GTEST_SKIP() << "glibc doesn't have renameat2 until 2.28";
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
+  GTEST_SKIP() << "glibc doesn't have renameat2 until 2.28 and musl doesn't have renameat2";
 #else
   TemporaryDir td;
   android::base::unique_fd dirfd{open(td.path, O_PATH)};
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 6c7966d..465e61a 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -22,6 +22,7 @@
 #include <pthread.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <sys/cdefs.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -32,6 +33,7 @@
 #include <android-base/file.h>
 #include <android-base/macros.h>
 #include <android-base/silent_death_test.h>
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 
 #include "math_data_test.h"
@@ -454,7 +456,7 @@
   ASSERT_EXIT(TestBug57421_main(), ::testing::ExitedWithCode(0), "");
 }
 
-TEST(stdlib, mkostemp64) {
+TEST(stdlib, mkostemp64_smoke) {
   MyTemporaryFile tf([](char* path) { return mkostemp64(path, O_CLOEXEC); });
   ASSERT_TRUE(CloseOnExec(tf.fd));
 }
@@ -464,7 +466,7 @@
   ASSERT_TRUE(CloseOnExec(tf.fd));
 }
 
-TEST(stdlib, mkstemp64) {
+TEST(stdlib, mkstemp64_smoke) {
   MyTemporaryFile tf(mkstemp64);
   struct stat64 sb;
   ASSERT_EQ(0, fstat64(tf.fd, &sb));
@@ -495,6 +497,30 @@
   ASSERT_NE(0, system(nullptr));
 }
 
+// https://austingroupbugs.net/view.php?id=1440
+TEST(stdlib, system_minus) {
+  // Create a script with a name that starts with a '-'.
+  TemporaryDir td;
+  std::string script = std::string(td.path) + "/-minus";
+  ASSERT_TRUE(android::base::WriteStringToFile("#!" BIN_DIR "sh\nexit 66\n", script));
+
+  // Set $PATH so we can find it.
+  setenv("PATH", td.path, 1);
+  // Make it executable so we can run it.
+  ASSERT_EQ(0, chmod(script.c_str(), 0555));
+
+  int status = system("-minus");
+  EXPECT_TRUE(WIFEXITED(status));
+  EXPECT_EQ(66, WEXITSTATUS(status));
+
+  // While we're here and have all the setup, let's test popen(3) too...
+  FILE* fp = popen("-minus", "r");
+  ASSERT_TRUE(fp != nullptr);
+  status = pclose(fp);
+  EXPECT_TRUE(WIFEXITED(status));
+  EXPECT_EQ(66, WEXITSTATUS(status));
+}
+
 TEST(stdlib, atof) {
   ASSERT_DOUBLE_EQ(1.23, atof("1.23"));
 }
@@ -632,6 +658,13 @@
   AssertChildExited(pid, 99);
 }
 
+#if defined(ANDROID_HOST_MUSL)
+// musl doesn't have getpt
+int getpt() {
+  return posix_openpt(O_RDWR|O_NOCTTY);
+}
+#endif
+
 TEST(stdlib, pty_smoke) {
   // getpt returns a pty with O_RDWR|O_NOCTTY.
   int fd = getpt();
@@ -961,8 +994,8 @@
 }
 
 TEST(stdlib, getprogname) {
-#if defined(__GLIBC__)
-  GTEST_SKIP() << "glibc doesn't have getprogname()";
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
+  GTEST_SKIP() << "glibc and musl don't have getprogname()";
 #else
   // You should always have a name.
   ASSERT_TRUE(getprogname() != nullptr);
@@ -972,8 +1005,8 @@
 }
 
 TEST(stdlib, setprogname) {
-#if defined(__GLIBC__)
-  GTEST_SKIP() << "glibc doesn't have setprogname()";
+#if defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
+  GTEST_SKIP() << "glibc and musl don't have setprogname()";
 #else
   // setprogname() only takes the basename of what you give it.
   setprogname("/usr/bin/muppet");
diff --git a/tests/string_posix_strerror_r_test.cpp b/tests/string_posix_strerror_r_test.cpp
index 596684b..e4becaa 100644
--- a/tests/string_posix_strerror_r_test.cpp
+++ b/tests/string_posix_strerror_r_test.cpp
@@ -14,51 +14,52 @@
  * limitations under the License.
  */
 
-#undef _GNU_SOURCE
-#include <features.h> // Get __BIONIC__ or __GLIBC__ so we can tell what we're using.
-
-#if defined(__GLIBC__)
-
-// At the time of writing, libcxx -- which is dragged in by gtest -- assumes
-// declarations from glibc of things that aren't available without _GNU_SOURCE.
-// This means we can't even build this test (which is a problem because that
-// means it doesn't get included in CTS).
-// For glibc 2.15, the symbols in question are:
-//   at_quick_exit, quick_exit, vasprintf, strtoll_l, strtoull_l, and strtold_l.
-
-# if __GLIBC_PREREQ(2, 19)
-#  error check whether we can build this now...
-# endif
-
-#else
-
-#include <string.h>
-
 #include <errno.h>
 #include <gtest/gtest.h>
 
+// Defined in string_posix_strerror_r_wrapper.cpp as a wrapper around the posix
+// strerror_r to work around an incompatibility between libc++ (required by
+// gtest) and !_GNU_SOURCE.
+int posix_strerror_r(int errnum, char* buf, size_t buflen);
+
 TEST(string, posix_strerror_r) {
   char buf[256];
 
   // Valid.
-  ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
+  ASSERT_EQ(0, posix_strerror_r(0, buf, sizeof(buf)));
+#if defined(ANDROID_HOST_MUSL)
+  ASSERT_STREQ("No error information", buf);
+#else
   ASSERT_STREQ("Success", buf);
-  ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
+#endif
+  ASSERT_EQ(0, posix_strerror_r(1, buf, sizeof(buf)));
   ASSERT_STREQ("Operation not permitted", buf);
 
+#if defined(__BIONIC__) || defined(ANDROID_HOST_MUSL)
   // Invalid.
-  ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
+  ASSERT_EQ(0, posix_strerror_r(-1, buf, sizeof(buf)));
+# if defined(__BIONIC__)
   ASSERT_STREQ("Unknown error -1", buf);
-  ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
+# else
+  ASSERT_STREQ("No error information", buf);
+# endif
+  ASSERT_EQ(0, posix_strerror_r(1234, buf, sizeof(buf)));
+# if defined(__BIONIC__)
   ASSERT_STREQ("Unknown error 1234", buf);
+# else
+  ASSERT_STREQ("No error information", buf);
+# endif
+#else
+  // glibc returns EINVAL for unknown errors
+  ASSERT_EQ(EINVAL, posix_strerror_r(-1, buf, sizeof(buf)));
+  ASSERT_EQ(EINVAL, posix_strerror_r(1234, buf, sizeof(buf)));
+#endif
 
   // Buffer too small.
   errno = 0;
   memset(buf, 0, sizeof(buf));
-  ASSERT_EQ(-1, strerror_r(4567, buf, 2));
-  ASSERT_STREQ("U", buf);
-  // The POSIX strerror_r sets errno to ERANGE (the GNU one doesn't).
-  ASSERT_EQ(ERANGE, errno);
+  ASSERT_EQ(ERANGE, posix_strerror_r(EPERM, buf, 2));
+  ASSERT_STREQ("O", buf);
+  // POSIX strerror_r returns an error without updating errno.
+  ASSERT_EQ(0, errno);
 }
-
-#endif
diff --git a/tests/string_posix_strerror_r_wrapper.cpp b/tests/string_posix_strerror_r_wrapper.cpp
new file mode 100644
index 0000000..78d5d90
--- /dev/null
+++ b/tests/string_posix_strerror_r_wrapper.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef _GNU_SOURCE
+#include <string.h>
+
+// At the time of writing, libcxx -- which is dragged in by gtest -- assumes
+// declarations from glibc of things that aren't available without _GNU_SOURCE.
+// This means we can't even build a test that directly calls the posix
+// strerror_r.  Add a wrapper in a separate file that doesn't use any gtest.
+// For glibc 2.15, the symbols in question are:
+//   at_quick_exit, quick_exit, vasprintf, strtoll_l, strtoull_l, and strtold_l.
+
+int posix_strerror_r(int errnum, char* buf, size_t buflen) {
+  return strerror_r(errnum, buf, buflen);
+}
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 22be852..8d3fb68 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -23,6 +23,7 @@
 #include <malloc.h>
 #include <math.h>
 #include <stdint.h>
+#include <sys/cdefs.h>
 
 #include <algorithm>
 #include <vector>
@@ -95,6 +96,7 @@
 }
 
 TEST(STRING_TEST, gnu_strerror_r) {
+#if !defined(ANDROID_HOST_MUSL)
   char buf[256];
 
   // Note that glibc doesn't necessarily write into the buffer.
@@ -122,6 +124,9 @@
   ASSERT_STREQ("U", buf);
   // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
   ASSERT_EQ(0, errno);
+#else
+  GTEST_SKIP() << "musl doesn't have GNU strerror_r";
+#endif
 }
 
 TEST(STRING_TEST, strsignal) {
@@ -1473,14 +1478,17 @@
   RunSingleBufferOverreadTest(DoStrrchrTest);
 }
 
+#if !defined(ANDROID_HOST_MUSL)
 static void TestBasename(const char* in, const char* expected_out) {
   errno = 0;
   const char* out = basename(in);
   ASSERT_STREQ(expected_out, out) << in;
   ASSERT_EQ(0, errno) << in;
 }
+#endif
 
 TEST(STRING_TEST, __gnu_basename) {
+#if !defined(ANDROID_HOST_MUSL)
   TestBasename("", "");
   TestBasename("/usr/lib", "lib");
   TestBasename("/usr/", "");
@@ -1490,6 +1498,9 @@
   TestBasename("..", "..");
   TestBasename("///", "");
   TestBasename("//usr//lib//", "");
+#else
+  GTEST_SKIP() << "musl doesn't have GNU basename";
+#endif
 }
 
 TEST(STRING_TEST, strnlen_147048) {
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 00fd4d5..0123ed9 100644
--- a/tests/struct_layout_test.cpp
+++ b/tests/struct_layout_test.cpp
@@ -69,7 +69,8 @@
   CHECK_OFFSET(bionic_tls, group, 11952);
   CHECK_OFFSET(bionic_tls, passwd, 12040);
   CHECK_OFFSET(bionic_tls, fdtrack_disabled, 12192);
-  CHECK_OFFSET(bionic_tls, padding, 12193);
+  CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
+  CHECK_OFFSET(bionic_tls, padding, 12194);
 #else
   CHECK_SIZE(pthread_internal_t, 668);
   CHECK_OFFSET(pthread_internal_t, next, 0);
@@ -110,7 +111,8 @@
   CHECK_OFFSET(bionic_tls, group, 10892);
   CHECK_OFFSET(bionic_tls, passwd, 10952);
   CHECK_OFFSET(bionic_tls, fdtrack_disabled, 11076);
-  CHECK_OFFSET(bionic_tls, padding, 11077);
+  CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 11077);
+  CHECK_OFFSET(bionic_tls, padding, 11078);
 #endif  // __LP64__
 #undef CHECK_SIZE
 #undef CHECK_OFFSET
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
index 5e0a0b0..4a64742 100644
--- a/tests/sys_procfs_test.cpp
+++ b/tests/sys_procfs_test.cpp
@@ -16,6 +16,7 @@
 
 #include <gtest/gtest.h>
 
+#include <ucontext.h> // for NGREG on musl
 #include <sys/procfs.h>
 
 TEST(sys_procfs, types) {
diff --git a/tests/sys_resource_test.cpp b/tests/sys_resource_test.cpp
index b1e8b1a..0247fcb 100644
--- a/tests/sys_resource_test.cpp
+++ b/tests/sys_resource_test.cpp
@@ -89,7 +89,7 @@
   ASSERT_EQ(123U, l32_.rlim_cur);
 }
 
-TEST_F(SysResourceTest, setrlimit64) {
+TEST_F(SysResourceTest, setrlimit64_smoke) {
   l64_.rlim_cur = 456U;
   ASSERT_EQ(0, setrlimit64(RLIMIT_CORE, &l64_));
   CheckResourceLimits();
@@ -103,7 +103,7 @@
   ASSERT_EQ(pr_l32_.rlim_max, pr_l32_.rlim_cur);
 }
 
-TEST_F(SysResourceTest, prlimit64) {
+TEST_F(SysResourceTest, prlimit64_smoke) {
   pr_l64_.rlim_cur = pr_l64_.rlim_max;
   ASSERT_EQ(0, prlimit64(0, RLIMIT_CORE, &pr_l64_, nullptr));
   CheckResourceLimits();
diff --git a/tests/sys_sendfile_test.cpp b/tests/sys_sendfile_test.cpp
index 4cddd0d..1ec6c9f 100644
--- a/tests/sys_sendfile_test.cpp
+++ b/tests/sys_sendfile_test.cpp
@@ -43,7 +43,7 @@
   ASSERT_STREQ("ll", buf);
 }
 
-TEST(sys_sendfile, sendfile64) {
+TEST(sys_sendfile, sendfile64_smoke) {
   TemporaryFile src_file;
   ASSERT_EQ(5, TEMP_FAILURE_RETRY(write(src_file.fd, "hello", 5)));
 
diff --git a/tests/sys_statvfs_test.cpp b/tests/sys_statvfs_test.cpp
index bff9e20..1761e6a 100644
--- a/tests/sys_statvfs_test.cpp
+++ b/tests/sys_statvfs_test.cpp
@@ -43,7 +43,7 @@
   Check(sb);
 }
 
-TEST(sys_statvfs, statvfs64) {
+TEST(sys_statvfs, statvfs64_smoke) {
   struct statvfs64 sb;
   ASSERT_EQ(0, statvfs64("/proc", &sb));
   Check(sb);
@@ -57,7 +57,7 @@
   Check(sb);
 }
 
-TEST(sys_statvfs, fstatvfs64) {
+TEST(sys_statvfs, fstatvfs64_smoke) {
   struct statvfs64 sb;
   int fd = open("/proc", O_RDONLY);
   ASSERT_EQ(0, fstatvfs64(fd, &sb));
diff --git a/tests/sys_sysinfo_test.cpp b/tests/sys_sysinfo_test.cpp
index ea35b4e..cca2f44 100644
--- a/tests/sys_sysinfo_test.cpp
+++ b/tests/sys_sysinfo_test.cpp
@@ -42,4 +42,10 @@
   struct sysinfo si;
   memset(&si, 0, sizeof(si));
   ASSERT_EQ(0, sysinfo(&si));
+
+  ASSERT_GT(si.uptime, 10);  // You're not running CTS within 10s of booting!
+  ASSERT_GT(uint64_t(si.totalram) * si.mem_unit, uint64_t(512 * 1024 * 1024));
+  ASSERT_GE(si.totalram, si.freeram);
+  ASSERT_GE(si.totalswap, si.freeswap);
+  ASSERT_GT(si.procs, 2);  // There's at least this test and init running!
 }
diff --git a/tests/sys_time_test.cpp b/tests/sys_time_test.cpp
index 5dda7ab..07394d6 100644
--- a/tests/sys_time_test.cpp
+++ b/tests/sys_time_test.cpp
@@ -132,6 +132,11 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
+// Musl doesn't define __NR_gettimeofday on 32-bit architectures.
+#if !defined(__NR_gettimeofday)
+#define __NR_gettimeofday __NR_gettimeofday_time32
+#endif
+
 TEST(sys_time, gettimeofday) {
   // Try to ensure that our vdso gettimeofday is working.
   timeval tv1;
diff --git a/tests/sys_ttydefaults_test.cpp b/tests/sys_ttydefaults_test.cpp
index fa4f7c7..73aa448 100644
--- a/tests/sys_ttydefaults_test.cpp
+++ b/tests/sys_ttydefaults_test.cpp
@@ -20,7 +20,7 @@
 #include <termios.h>
 
 TEST(sys_ttydefaults, flags) {
-  int i;
+  [[maybe_unused]] int i;
   i = TTYDEF_IFLAG;
   i = TTYDEF_OFLAG;
   i = TTYDEF_LFLAG;
diff --git a/tests/sys_types_test.cpp b/tests/sys_types_test.cpp
index 0793be2..0559664 100644
--- a/tests/sys_types_test.cpp
+++ b/tests/sys_types_test.cpp
@@ -16,6 +16,7 @@
 
 #include <gtest/gtest.h>
 
+#include <fcntl.h> // for loff_t on musl
 #include <sys/types.h>
 
 TEST(sys_types, type_sizes) {
diff --git a/tests/sys_uio_test.cpp b/tests/sys_uio_test.cpp
index 8460041..aac08e7 100644
--- a/tests/sys_uio_test.cpp
+++ b/tests/sys_uio_test.cpp
@@ -16,7 +16,11 @@
 
 #include <gtest/gtest.h>
 
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
 #include <sys/uio.h>
+#include <unistd.h>
 
 #include <android-base/file.h>
 
@@ -68,6 +72,42 @@
   TestPreadVPwriteV(preadv64, pwritev64);
 }
 
+template <typename ReadFn, typename WriteFn>
+void TestPreadV2PwriteV2(ReadFn read_fn, WriteFn write_fn) {
+  TemporaryFile tf;
+
+  char buf[] = "world";
+  iovec ios[] = {{buf, 5}};
+
+  ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 5, 0)) << strerror(errno);
+  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR));
+
+  strcpy(buf, "hello");
+  ASSERT_EQ(5, write_fn(tf.fd, ios, 1, 0, 0)) << strerror(errno);
+  ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_CUR));
+
+  ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 5, 0)) << strerror(errno);
+  ASSERT_STREQ("world", buf);
+  ASSERT_EQ(5, read_fn(tf.fd, ios, 1, 0, 0)) << strerror(errno);
+  ASSERT_STREQ("hello", buf);
+}
+
+TEST(sys_uio, preadv2_pwritev2) {
+#if defined(__BIONIC__)
+  TestPreadV2PwriteV2(preadv2, pwritev2);
+#else
+  GTEST_SKIP() << "preadv2/pwritev2 not available";
+#endif
+}
+
+TEST(sys_uio, preadv64v2_pwritev64v2) {
+#if defined(__BIONIC__)
+  TestPreadV2PwriteV2(preadv64v2, pwritev64v2);
+#else
+  GTEST_SKIP() << "preadv2/pwritev2 not available";
+#endif
+}
+
 TEST(sys_uio, process_vm_readv) {
   ASSERT_EQ(0, process_vm_readv(0, nullptr, 0, nullptr, 0, 0));
 
diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp
index f82f505..242f8d4 100644
--- a/tests/sys_vfs_test.cpp
+++ b/tests/sys_vfs_test.cpp
@@ -51,7 +51,7 @@
   ASSERT_EQ(ENOENT, errno);
 }
 
-TEST(sys_vfs, statfs64) {
+TEST(sys_vfs, statfs64_smoke) {
   struct statfs64 sb;
   ASSERT_EQ(0, statfs64("/proc", &sb));
   Check(sb);
@@ -79,7 +79,7 @@
   ASSERT_EQ(EBADF, errno);
 }
 
-TEST(sys_vfs, fstatfs64) {
+TEST(sys_vfs, fstatfs64_smoke) {
   struct statfs64 sb;
   int fd = open("/proc", O_RDONLY);
   ASSERT_EQ(0, fstatfs64(fd, &sb));
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index b16fe16..5fc4cad 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -20,6 +20,7 @@
 #include <gtest/gtest.h>
 #include <pthread.h>
 #include <signal.h>
+#include <sys/cdefs.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -282,6 +283,7 @@
 }
 
 TEST(time, strptime_l) {
+#if !defined(ANDROID_HOST_MUSL)
   setenv("TZ", "UTC", 1);
 
   struct tm t;
@@ -296,6 +298,9 @@
   strptime_l("09:41:53", "%T", &t, LC_GLOBAL_LOCALE);
   strftime_l(buf, sizeof(buf), "%H:%M:%S", &t, LC_GLOBAL_LOCALE);
   EXPECT_STREQ("09:41:53", buf);
+#else
+  GTEST_SKIP() << "musl doesn't support strptime_l";
+#endif
 }
 
 TEST(time, strptime_F) {
@@ -469,11 +474,11 @@
   ASSERT_EQ(0, timer_settime(t, 0, &ts, nullptr));
 }
 
-static void NoOpNotifyFunction(sigval_t) {
+static void NoOpNotifyFunction(sigval) {
 }
 
 TEST(time, timer_create) {
-  sigevent_t se;
+  sigevent se;
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = NoOpNotifyFunction;
@@ -502,7 +507,7 @@
 }
 
 TEST(time, timer_create_SIGEV_SIGNAL) {
-  sigevent_t se;
+  sigevent se;
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_SIGNAL;
   se.sigev_signo = SIGUSR1;
@@ -530,7 +535,7 @@
  private:
   std::atomic<int> value;
   timer_t timer_id;
-  sigevent_t se;
+  sigevent se;
   bool timer_valid;
 
   void Create() {
@@ -540,7 +545,7 @@
   }
 
  public:
-  explicit Counter(void (*fn)(sigval_t)) : value(0), timer_valid(false) {
+  explicit Counter(void (*fn)(sigval)) : value(0), timer_valid(false) {
     memset(&se, 0, sizeof(se));
     se.sigev_notify = SIGEV_THREAD;
     se.sigev_notify_function = fn;
@@ -575,12 +580,12 @@
     return current_value != value;
   }
 
-  static void CountNotifyFunction(sigval_t value) {
+  static void CountNotifyFunction(sigval value) {
     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
     ++cd->value;
   }
 
-  static void CountAndDisarmNotifyFunction(sigval_t value) {
+  static void CountAndDisarmNotifyFunction(sigval value) {
     Counter* cd = reinterpret_cast<Counter*>(value.sival_ptr);
     ++cd->value;
 
@@ -644,7 +649,7 @@
   ASSERT_EQ(EINVAL, errno);
 
   // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
-  sigevent_t se;
+  sigevent se;
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = NoOpNotifyFunction;
@@ -715,7 +720,7 @@
   volatile bool complete;
 };
 
-static void TimerDeleteCallback(sigval_t value) {
+static void TimerDeleteCallback(sigval value) {
   TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
 
   tdd->tid = gettid();
@@ -725,7 +730,7 @@
 
 TEST(time, timer_delete_from_timer_thread) {
   TimerDeleteData tdd;
-  sigevent_t se;
+  sigevent se;
 
   memset(&se, 0, sizeof(se));
   se.sigev_notify = SIGEV_THREAD;
@@ -756,6 +761,11 @@
 #endif
 }
 
+// Musl doesn't define __NR_clock_gettime on 32-bit architectures.
+#if !defined(__NR_clock_gettime)
+#define __NR_clock_gettime __NR_clock_gettime32
+#endif
+
 TEST(time, clock_gettime) {
   // Try to ensure that our vdso clock_gettime is working.
   timespec ts0;
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index 48c500d..4dc6314 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -36,6 +36,7 @@
   // 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);
 
@@ -87,11 +88,7 @@
   EXPECT_EQ('\xe2', bytes[0]);
   EXPECT_EQ('\x82', bytes[1]);
   EXPECT_EQ('\xac', bytes[2]);
-}
-
-TEST(uchar, c16rtomb_surrogate) {
-  char bytes[MB_LEN_MAX];
-
+  // 4-byte UTF-8 from a surrogate pair...
   memset(bytes, 0, sizeof(bytes));
   EXPECT_EQ(0U, c16rtomb(bytes, 0xdbea, nullptr));
   EXPECT_EQ(4U, c16rtomb(bytes, 0xdfcd, nullptr));
@@ -143,16 +140,16 @@
   // 3-byte UTF-8.
   ASSERT_EQ(3U, mbrtoc16(&out, "\xe2\x82\xac" "def", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0x20ac), out);
-}
-
-TEST(uchar, mbrtoc16_surrogate) {
-  char16_t 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(static_cast<char16_t>(0xdbea), out);
   ASSERT_EQ(4U, mbrtoc16(&out, "\xf4\x8a\xaf\x8d" "ef", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
+  // Illegal 5-byte UTF-8.
+  errno = 0;
+  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc16(&out, "\xf8\xa1\xa2\xa3\xa4", 5, nullptr));
+  ASSERT_EQ(EILSEQ, errno);
 }
 
 TEST(uchar, mbrtoc16_reserved_range) {
@@ -194,6 +191,7 @@
 
   // Invalid 2-byte
   ASSERT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "\xc2", 1, ps));
+  errno = 0;
   ASSERT_EQ(static_cast<size_t>(-1), mbrtoc16(&out, "\x20" "cdef", 5, ps));
   ASSERT_EQ(EILSEQ, errno);
 }
@@ -247,6 +245,7 @@
   EXPECT_EQ('\xad', bytes[2]);
   EXPECT_EQ('\xa2', bytes[3]);
   // Invalid code point.
+  errno = 0;
   EXPECT_EQ(static_cast<size_t>(-1), c32rtomb(bytes, 0xffffffff, nullptr));
   EXPECT_EQ(EILSEQ, errno);
 }
@@ -307,10 +306,12 @@
   ASSERT_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);
 #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);
 }
@@ -340,6 +341,7 @@
 
   // Invalid 2-byte
   ASSERT_EQ(static_cast<size_t>(-2), mbrtoc32(&out, "\xc2", 1, ps));
+  errno = 0;
   ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(&out, "\x20" "cdef", 5, ps));
   ASSERT_EQ(EILSEQ, errno);
 }
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 7d1e612..6d7e687 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -183,7 +183,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(UNISTD_TEST, truncate64) {
+TEST(UNISTD_TEST, truncate64_smoke) {
   TemporaryFile tf;
   ASSERT_EQ(0, close(tf.fd));
   ASSERT_EQ(0, truncate64(tf.path, 123));
@@ -203,7 +203,7 @@
   ASSERT_EQ(123, sb.st_size);
 }
 
-TEST(UNISTD_TEST, ftruncate64) {
+TEST(UNISTD_TEST, ftruncate64_smoke) {
   TemporaryFile tf;
   ASSERT_EQ(0, ftruncate64(tf.fd, 123));
   ASSERT_EQ(0, close(tf.fd));
@@ -688,9 +688,9 @@
 __attribute__((noinline)) static void HwasanReadMemory(const char* p, size_t size) {
   // Read memory byte-by-byte. This will blow up if the pointer tag in p does not match any memory
   // tag in [p, p+size).
-  volatile char z;
+  char z;
   for (size_t i = 0; i < size; ++i) {
-    z = p[i];
+    DoNotOptimize(z = p[i]);
   }
 }
 
@@ -739,7 +739,7 @@
   // Does uname(2) agree?
   utsname buf;
   ASSERT_EQ(0, uname(&buf));
-  ASSERT_EQ(0, strncmp(hostname, buf.nodename, SYS_NMLN));
+  ASSERT_EQ(0, strncmp(hostname, buf.nodename, sizeof(buf.nodename)));
   ASSERT_GT(strlen(hostname), 0U);
 
   // Do we correctly detect truncation?
@@ -852,7 +852,9 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_MONOTONIC_CLOCK);
 #endif
   EXPECT_GT(_POSIX_NO_TRUNC, 0);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(_POSIX_VERSION, _POSIX_PRIORITY_SCHEDULING);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_RAW_SOCKETS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_READER_WRITER_LOCKS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_REALTIME_SIGNALS);
@@ -861,8 +863,10 @@
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SEMAPHORES);
   EXPECT_GT(_POSIX_SHELL, 0);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SPAWN);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(-1, _POSIX_SPORADIC_SERVER);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_SYNCHRONIZED_IO);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREADS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKADDR);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_ATTR_STACKSIZE);
@@ -871,27 +875,37 @@
 #endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PRIORITY_SCHEDULING);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_PROCESS_SHARED);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(-1, _POSIX_THREAD_ROBUST_PRIO_PROTECT);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_THREAD_SAFE_FUNCTIONS);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(-1, _POSIX_THREAD_SPORADIC_SERVER);
+#endif
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMEOUTS);
   EXPECT_EQ(_POSIX_VERSION, _POSIX_TIMERS);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(-1, _POSIX_TRACE);
   EXPECT_EQ(-1, _POSIX_TRACE_EVENT_FILTER);
   EXPECT_EQ(-1, _POSIX_TRACE_INHERIT);
   EXPECT_EQ(-1, _POSIX_TRACE_LOG);
   EXPECT_EQ(-1, _POSIX_TYPED_MEMORY_OBJECTS);
+#endif
   EXPECT_NE(-1, _POSIX_VDISABLE);
 
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_VERSION);
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_C_BIND);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(_POSIX_VERSION, _POSIX2_CHAR_TERM);
+#endif
 
   EXPECT_EQ(700, _XOPEN_VERSION);
   EXPECT_EQ(1, _XOPEN_ENH_I18N);
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(1, _XOPEN_REALTIME);
   EXPECT_EQ(1, _XOPEN_REALTIME_THREADS);
   EXPECT_EQ(1, _XOPEN_SHM);
+#endif
   EXPECT_EQ(1, _XOPEN_UNIX);
 
 #if defined(__BIONIC__)
@@ -1515,11 +1529,21 @@
 }
 
 TEST(UNISTD_TEST, exec_argv0_null) {
-  // http://b/33276926
+  // http://b/33276926 and http://b/227498625.
+  //
+  // With old kernels, bionic will see the null pointer and use "<unknown>" but
+  // with new (5.18+) kernels, the kernel will already have substituted the
+  // empty string, so we don't make any assertion here about what (if anything)
+  // comes before the first ':'.
+  //
+  // If this ever causes trouble, we could change bionic to replace _either_ the
+  // null pointer or the empty string. We could also use the actual name from
+  // readlink() on /proc/self/exe if we ever had reason to disallow programs
+  // from trying to hide like this.
   char* args[] = {nullptr};
   char* envs[] = {nullptr};
   ASSERT_EXIT(execve("/system/bin/run-as", args, envs), testing::ExitedWithCode(1),
-              "<unknown>: usage: run-as");
+              ": usage: run-as");
 }
 
 TEST(UNISTD_TEST, fexecve_failure) {
diff --git a/tests/utils.h b/tests/utils.h
index 592ac0e..72214c2 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -69,14 +69,6 @@
   return (dlopen("libc.so", 0) != nullptr);
 }
 
-extern "C" void __hwasan_init() __attribute__((weak));
-
-static inline bool running_with_hwasan() {
-  return &__hwasan_init != 0;
-}
-
-#define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
-
 static inline bool running_with_native_bridge() {
 #if defined(__BIONIC__)
   static const prop_info* pi = __system_property_find("ro.dalvik.vm.isa." ABI_STRING);
@@ -229,7 +221,7 @@
   }
 
   void Run(const std::function<void()>& child_fn, int expected_exit_status,
-           const char* expected_output) {
+           const char* expected_output_regex) {
     int fds[2];
     ASSERT_NE(pipe(fds), -1);
 
@@ -258,8 +250,10 @@
 
     std::string error_msg("Test output:\n" + output_);
     AssertChildExited(pid, expected_exit_status, &error_msg);
-    if (expected_output != nullptr) {
-      ASSERT_EQ(expected_output, output_);
+    if (expected_output_regex != nullptr) {
+      if (!std::regex_search(output_, std::regex(expected_output_regex))) {
+        FAIL() << "regex " << expected_output_regex << " didn't match " << output_;
+      }
     }
   }
 
@@ -268,6 +262,8 @@
   std::vector<const char*> env_;
   std::string output_;
 };
+
+void RunGwpAsanTest(const char* test_name);
 #endif
 
 class FdLeakChecker {
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index d0b5a4a..85a75ec 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -22,6 +22,7 @@
 #include <locale.h>
 #include <math.h>
 #include <stdint.h>
+#include <sys/cdefs.h>
 #include <wchar.h>
 
 #include "utils.h"
@@ -800,8 +801,12 @@
 }
 
 TEST(wchar, wmempcpy) {
+#if !defined(ANDROID_HOST_MUSL)
   wchar_t dst[6];
   ASSERT_EQ(&dst[4], wmempcpy(dst, L"hello", 4));
+#else
+  GTEST_SKIP() << "musl doesn't have wmempcpy";
+#endif
 }
 
 template <typename T>
@@ -913,15 +918,27 @@
 }
 
 TEST(wchar, wcstod_l) {
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(1.23, wcstod_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstod_l";
+#endif
 }
 
 TEST(wchar, wcstof_l) {
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(1.23f, wcstof_l(L"1.23", nullptr, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstof_l";
+#endif
 }
 
 TEST(wchar, wcstol_l) {
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(123L, wcstol_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstol_l";
+#endif
 }
 
 TEST(wchar, wcstold_l) {
@@ -933,11 +950,15 @@
 }
 
 TEST(wchar, wcstoul_l) {
+#if !defined(ANDROID_HOST_MUSL)
   EXPECT_EQ(123UL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+#else
+  GTEST_SKIP() << "musl doesn't have wcstoul_l";
+#endif
 }
 
 TEST(wchar, wcstoull_l) {
-  EXPECT_EQ(123ULL, wcstoul_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
+  EXPECT_EQ(123ULL, wcstoull_l(L"123", nullptr, 10, LC_GLOBAL_LOCALE));
 }
 
 static void AssertWcwidthRange(wchar_t begin, wchar_t end, int expected) {
diff --git a/tools/versioner/src/Android.bp b/tools/versioner/src/Android.bp
index 0173c41..abcaaa3 100644
--- a/tools/versioner/src/Android.bp
+++ b/tools/versioner/src/Android.bp
@@ -21,8 +21,7 @@
     ],
 
     shared_libs: [
-        "libclang_cxx_host",
-        "libLLVM_host",
+        "libclang-cpp_host",
         "libbase",
     ],