Merge mainline-release 6664920 to master - DO NOT MERGE

Merged-In: I91b84c489668ae1cac5a8143a9350e3ab625afdb
Change-Id: Id39b07cab134b03e42729cd0a7ca91990468d63e
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: NOTICE
+}
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 11d9fe6..b4223ea 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,8 +1,9 @@
-[Hook Scripts]
-notice = tools/update_notice.sh
-
 [Builtin Hooks]
 clang_format = true
 
 [Builtin Hooks Options]
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+
+[Hook Scripts]
+aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."
+notice = tools/update_notice.sh
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index a0f3c3c..da07c79 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -175,11 +175,9 @@
 temporarily support these libraries; so if you see a warning that means
 your code will not work in a future release -- please fix it now!
 
-In O and later, the system property `debug.ld.greylist_disabled` can be
-used to deny access to the greylist even to an app that would normally
-be allowed it. This allows you to test compatibility without bumping the
-app's `targetSdkVersion`. Use `setprop debug.ld.greylist_disabled true`
-to turn this on (any other value leaves the greylist enabled).
+Between O and R, this compatibility mode could be disabled by setting a
+system property (`debug.ld.greylist_disabled`). This property is ignored
+in S and later.
 
 ```
 $ readelf --dynamic libBroken.so | grep NEEDED
@@ -218,7 +216,7 @@
 
 Each ELF file has additional information contained in the section
 headers. These headers must be present now, because the dynamic linker
-uses them for sanity checking. Some developers strip them in an
+uses them for validity checking. Some developers strip them in an
 attempt to obfuscate the binary and prevent reverse engineering. (This
 doesn't really help because it is possible to reconstruct the stripped
 information using widely-available tools.)
diff --git a/apex/Android.bp b/apex/Android.bp
index f62f930..c6c4cbf 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -28,9 +28,61 @@
     ],
     multilib: {
         both: {
-            binaries: ["linker"],
+            binaries: [
+                "crash_dump",
+                "linker",
+            ],
         },
     },
     key: "com.android.runtime.key",
     certificate: ":com.android.runtime.certificate",
+    prebuilts: [
+        "bionic-linker-config",
+    ],
+}
+
+sdk {
+    name: "runtime-module-sdk",
+    defaults: ["linux_bionic_supported"],
+
+    native_header_libs: [
+        "bionic_libc_platform_headers",
+        "libc_headers",
+    ],
+    native_shared_libs: [
+        "libc",
+        "libdl",
+        "libdl_android",
+        "libm",
+    ],
+    native_static_libs: [
+        "libasync_safe",
+    ],
+    native_objects: [
+        "crtbegin_dynamic",
+        "crtbegin_so",
+        "crtend_android",
+        "crtend_so",
+    ],
+}
+
+module_exports {
+    name: "runtime-module-host-exports",
+    host_supported: true,
+    device_supported: false,
+    compile_multilib: "64",
+
+    native_binaries: ["linkerconfig"],
+    target: {
+        linux_bionic: {
+            native_binaries: ["linker"],
+        },
+    },
+}
+
+prebuilt_etc {
+    name: "bionic-linker-config",
+    src: "linker.config.txt",
+    filename: "linker.config.txt",
+    installable: false,
 }
diff --git a/apex/linker.config.txt b/apex/linker.config.txt
new file mode 100644
index 0000000..7bac3d6
--- /dev/null
+++ b/apex/linker.config.txt
@@ -0,0 +1,6 @@
+# Extra linker configurations for bionic APEX
+# See https://android.googlesource.com/platform/system/linkerconfig/+/master/README.md#apex_etc_linker_config_txt
+
+[properties]
+# Set bionic APEX as force visible so bionic APEX namespace is accessible via android_get_exported_namespace
+visible = true
diff --git a/benchmarks/linker_relocation/regen/gen_bench.py b/benchmarks/linker_relocation/regen/gen_bench.py
index 61156ce..09efa75 100755
--- a/benchmarks/linker_relocation/regen/gen_bench.py
+++ b/benchmarks/linker_relocation/regen/gen_bench.py
@@ -62,7 +62,7 @@
 ])
 
 # Skip these symbols so the benchmark runs on multiple C libraries (glibc, Bionic, musl).
-kBionicSymbolBlacklist: Set[str] = set([
+kBionicIgnoredSymbols: Set[str] = set([
     '__FD_ISSET_chk',
     '__FD_SET_chk',
     '__assert',
@@ -137,7 +137,7 @@
     return defs
 
 
-def sanity_check_rels(root: LoadedLibrary, defs: Definitions) -> None:
+def check_rels(root: LoadedLibrary, defs: Definitions) -> None:
     # Find every symbol for every relocation in the load group.
     has_missing = False
     for lib in bfs_walk(root):
@@ -169,7 +169,7 @@
         nonlocal defs
         d = defs.get(name)
         if d is not None and d.soname in kBionicSonames:
-            if name in kBionicSymbolBlacklist: return None
+            if name in kBionicIgnoredSymbols: return None
             # Discard relocations to newer Bionic symbols, because there aren't many of them, and
             # they would limit where the benchmark can run.
             if ver == 'LIBC': return name
@@ -389,7 +389,7 @@
     with open(Path(args.input)) as f:
         root = json_to_elf_tree(json.load(f))
     defs = build_symbol_index(root)
-    sanity_check_rels(root, defs)
+    check_rels(root, defs)
 
     if out.exists(): shutil.rmtree(out)
     os.makedirs(str(out))
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 9a68a12..856f150 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -53,15 +53,14 @@
 }
 BIONIC_BENCHMARK(BM_pthread_setspecific);
 
-static void DummyPthreadOnceInitFunction() {
-}
+static void NoOpPthreadOnceInitFunction() {}
 
 static void BM_pthread_once(benchmark::State& state) {
   static pthread_once_t once = PTHREAD_ONCE_INIT;
-  pthread_once(&once, DummyPthreadOnceInitFunction);
+  pthread_once(&once, NoOpPthreadOnceInitFunction);
 
   while (state.KeepRunning()) {
-    pthread_once(&once, DummyPthreadOnceInitFunction);
+    pthread_once(&once, NoOpPthreadOnceInitFunction);
   }
 }
 BIONIC_BENCHMARK(BM_pthread_once);
diff --git a/benchmarks/semaphore_benchmark.cpp b/benchmarks/semaphore_benchmark.cpp
index cf51489..ffccc82 100644
--- a/benchmarks/semaphore_benchmark.cpp
+++ b/benchmarks/semaphore_benchmark.cpp
@@ -28,8 +28,8 @@
   sem_init(&semaphore, 1, 1);
 
   while (state.KeepRunning()) {
-    int dummy;
-    sem_getvalue(&semaphore, &dummy);
+    int unused;
+    sem_getvalue(&semaphore, &unused);
   }
 }
 BIONIC_BENCHMARK(BM_semaphore_sem_getvalue);
@@ -44,112 +44,3 @@
   }
 }
 BIONIC_BENCHMARK(BM_semaphore_sem_wait_sem_post);
-
-// This test reports the overhead of the underlying futex wake syscall on
-// the producer. It does not report the overhead from issuing the wake to the
-// point where the posted consumer thread wakes up. It suffers from
-// clock_gettime syscall overhead. Lock the CPU speed for consistent results
-// as we may not reach >50% cpu utilization.
-//
-// We will run a background thread that catches the sem_post wakeup and
-// loops immediately returning back to sleep in sem_wait for the next one. This
-// thread is run with policy SCHED_OTHER (normal policy), a middle policy.
-//
-// The primary thread will run at SCHED_IDLE (lowest priority policy) when
-// monitoring the background thread to detect when it hits sem_wait sleep. It
-// will do so with no clock running. Once we are ready, we will switch to
-// SCHED_FIFO (highest priority policy) to time the act of running sem_post
-// with the benchmark clock running. This ensures nothing else in the system
-// can preempt our timed activity, including the background thread. We are
-// also protected with the scheduling policy of letting a process hit a
-// resource limit rather than get hit with a context switch.
-//
-// The background thread will start executing either on another CPU, or
-// after we back down from SCHED_FIFO, but certainly not in the context of
-// the timing of the sem_post.
-
-static atomic_int BM_semaphore_sem_post_running;
-
-static void* BM_semaphore_sem_post_start_thread(void* arg) {
-  sem_t* semaphore = reinterpret_cast<sem_t*>(arg);
-  while ((BM_semaphore_sem_post_running > 0) && !sem_wait(semaphore)) {
-  }
-  BM_semaphore_sem_post_running = -1;
-  return nullptr;
-}
-
-class SemaphoreFixture : public benchmark::Fixture {
- public:
-  void SetUp(const benchmark::State&) override {
-    sem_init(&semaphore, 0, 0);
-
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-
-    memset(&param, 0, sizeof(param));
-    pthread_attr_setschedparam(&attr, &param);
-    pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-    pthread_t pthread;
-    pthread_create(&pthread, &attr, BM_semaphore_sem_post_start_thread, &semaphore);
-    pthread_attr_destroy(&attr);
-
-    sched_setscheduler(0, SCHED_IDLE, &param);
-
-    BM_semaphore_sem_post_running = 1;
-    setup = true;
-  }
-
-  ~SemaphoreFixture() override {
-    if (setup) {
-      // Only do this if the test was actually run.
-      sched_setscheduler(0, SCHED_OTHER, &param);
-
-      if (BM_semaphore_sem_post_running > 0) {
-        BM_semaphore_sem_post_running = 0;
-      }
-      do {
-        sem_post(&semaphore);
-        sched_yield();
-      } while (BM_semaphore_sem_post_running != -1);
-    }
-  }
-
-  sem_t semaphore;
-  sched_param param;
-  bool setup = false;
-};
-
-// This is commented out because dynamic benchmark registering doesn't currently support fixtures.
-// Uncomment it and recompile to run this benchmark on every run.
-/* BENCHMARK_F(SemaphoreFixture, semaphore_sem_post)(benchmark::State& state) {
-  while (state.KeepRunning()) {
-    state.PauseTiming();
-
-    int trys = 3, dummy = 0;
-    do {
-      if (BM_semaphore_sem_post_running < 0) {
-        sched_setscheduler(0, SCHED_OTHER, &param);
-        fprintf(stderr, "BM_semaphore_sem_post: start_thread died unexpectedly\n");
-        abort();
-      }
-      sched_yield();
-      sem_getvalue(&semaphore, &dummy);
-      if (dummy < 0) {  // POSIX.1-2001 possibility 1
-        break;
-      }
-      if (dummy == 0) { // POSIX.1-2001 possibility 2
-        --trys;
-      }
-    } while (trys);
-
-    param.sched_priority = 1;
-    sched_setscheduler(0, SCHED_FIFO, &param);
-
-    state.ResumeTiming();
-    sem_post(&semaphore);
-
-    param.sched_priority = 0;
-    sched_setscheduler(0, SCHED_IDLE, &param);
-  }
-}*/
diff --git a/build/coverage.sh b/build/coverage.sh
new file mode 100755
index 0000000..13fabc5
--- /dev/null
+++ b/build/coverage.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# This script generates coverage for bionic.
+#
+# Prereqs: Coverage-enabled build.
+#
+#   $ lunch <target>
+#   $ m NATIVE_COVERAGE_PATHS="bionic" CLANG_COVERAGE=true
+#   $ m NATIVE_COVERAGE_PATHS="bionic" CLANG_COVERAGE=true bionic-unit-tests
+#
+# Do *NOT* then rebuild at the top level, or you'll clobber the
+# coverage-enabled libc!
+#
+# Flash image and set $ANDROID_SERIAL.
+#
+# Usage: $ bionic/build/coverage.sh
+# Output: HTML report is generated to /tmp/bionic-coverage/html/index.html
+#
+
+eval "$(cd ${ANDROID_BUILD_TOP}; build/soong/soong_ui.bash --dumpvars-mode --vars="TARGET_ARCH TARGET_ARCH_VARIANT")"
+
+LLVM_PROFDATA=${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/llvm-binutils-stable/llvm-profdata
+LLVM_COV=${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/llvm-binutils-stable/llvm-cov
+
+DEVICE_TEST_DIR32=/data/local/tmp/bionic-coverage32
+DEVICE_TEST_DIR64=/data/local/tmp/bionic-coverage64
+DEVICE_PROF_DIR=/data/local/tmp/bionic-profraw
+HOST_PROFDATA_DIR=/tmp/bionic-coverage
+
+# Run bionic-unit-tests
+adb shell rm -rf ${DEVICE_TEST_DIR32} ${DEVICE_TEST_DIR64} ${DEVICE_PROF_DIR}
+adb shell mkdir ${DEVICE_TEST_DIR32} ${DEVICE_TEST_DIR64} ${DEVICE_PROF_DIR}
+adb push $OUT/data/nativetest/bionic-loader-test-libs ${DEVICE_TEST_DIR32}
+adb push $OUT/data/nativetest/bionic-unit-tests ${DEVICE_TEST_DIR32}
+adb push $OUT/data/nativetest64/bionic-loader-test-libs ${DEVICE_TEST_DIR64}
+adb push $OUT/data/nativetest64/bionic-unit-tests ${DEVICE_TEST_DIR64}
+adb shell LLVM_PROFILE_FILE=${DEVICE_PROF_DIR}/bionic-%p-%m.profraw \
+  LD_LIBRARY_PATH=${DEVICE_TEST_DIR32}/bionic-loader-test-libs \
+  ${DEVICE_TEST_DIR32}/bionic-unit-tests/bionic-unit-tests
+adb shell LLVM_PROFILE_FILE=${DEVICE_PROF_DIR}/bionic-%p-%m.profraw \
+  LD_LIBRARY_PATH=${DEVICE_TEST_DIR64}/bionic-loader-test-libs \
+  ${DEVICE_TEST_DIR64}/bionic-unit-tests/bionic-unit-tests
+
+# Pull coverage files and post-process
+rm -rf ${HOST_PROFDATA_DIR}
+mkdir ${HOST_PROFDATA_DIR}
+adb pull ${DEVICE_PROF_DIR} ${HOST_PROFDATA_DIR}/profraws
+
+${LLVM_PROFDATA} merge \
+  --output=${HOST_PROFDATA_DIR}/bionic.profdata \
+  ${HOST_PROFDATA_DIR}/profraws/*.profraw
+
+${LLVM_COV} show \
+  --instr-profile=${HOST_PROFDATA_DIR}/bionic.profdata \
+  --format=html \
+  $OUT/symbols/apex/com.android.runtime/lib64/bionic/libc.so \
+  --object=$OUT/symbols/apex/com.android.runtime/lib64/bionic/libm.so \
+  --object=$OUT/symbols/data/nativetest64/bionic-unit-tests/bionic-unit-tests \
+  --object=$OUT/symbols/apex/com.android.runtime/lib/bionic/libc.so \
+  --object=$OUT/symbols/apex/com.android.runtime/lib/bionic/libm.so \
+  --object=$OUT/symbols/data/nativetest/bionic-unit-tests/bionic-unit-tests \
+  /proc/self/cwd/bionic/libc \
+  /proc/self/cwd/bionic/libm \
+  --output-dir=${HOST_PROFDATA_DIR}/html \
+  --show-region-summary=false
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 81afd14..3be6b1a 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -81,13 +81,23 @@
 in the 64-bit ABI even though they're identical to the non-`64` names.
 
 
-## `time_t` is 32-bit
+## `time_t` is 32-bit on LP32 (y2038)
 
-On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type
-`time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit
-Android all use the 32-bit `time_t`.
+On 32-bit Android, `time_t` is 32-bit, which will overflow in 2038.
 
-In the 64-bit ABI, `time_t` is 64-bit.
+In the 64-bit ABI, `time_t` is 64-bit, which will not overflow until
+long after the death of the star around which we currently circle.
+
+The header `<time64.h>` and type `time64_t` exist as a workaround,
+but the kernel interfaces exposed on 32-bit Android all use the 32-bit
+`time_t` and `struct timespec`/`struct timeval`. Linux 5.x kernels
+do offer extra interfaces so that 32-bit processes can pass 64-bit
+times to/from the kernel, but we do not plan on adding support for
+these to the C library. Convenient use of the new calls would require
+an equivalent to `_FILE_OFFSET_BITS=64`, which we wouldn't be able
+to globally flip for reasons similar to `_FILE_OFFSET_BITS`, mentioned
+above. All apps are already required to offer 64-bit variants, and we
+expect 64-bit-only devices within the next few years.
 
 
 ## `pthread_mutex_t` is too small for large pids
diff --git a/docs/fdtrack.md b/docs/fdtrack.md
new file mode 100644
index 0000000..5bc9860
--- /dev/null
+++ b/docs/fdtrack.md
@@ -0,0 +1,66 @@
+## fdtrack
+
+fdtrack consists of two parts: a set of hooks in bionic to register a callback
+that's invoked on file descriptor operations, and a library that implements a
+hook to perform and store backtraces for file descriptor creation.
+
+### bionic hooks
+bionic provides a header in the `bionic_libc_platform_headers` header_lib at <[bionic/fdtrack.h](https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/platform/bionic/fdtrack.h)>.
+Register a callback with `android_fdtrack_compare_exchange_hook` to receive
+callbacks upon file descriptor creation and destruction. This function can be
+called at any point in order to start capturing events, but be sure to properly
+handle unbalanced closes. This callback may be called from an async signal safe
+context, but not vfork (bionic tracks whether a thread is vforked, and chooses
+not to call callbacks when this is the case).
+
+### libfdtrack
+[libfdtrack](https://android.googlesource.com/platform/bionic/+/refs/heads/master/libfdtrack)
+implements a library that uses libunwindstack to unwind and store fd creation backtraces.
+
+
+#### Using libfdtrack
+libfdtrack registers its hook upon being loaded, so to start capturing
+backtraces, `dlopen("libfdtrack.so", RTLD_GLOBAL)` is all that's needed. To dump
+its output to logcat, either use `fdtrack_dump`, or send the signal
+`BIONIC_SIGNAL_FDTRACK` (available from `<bionic/reserved_signals.h>`) to the
+process. If you wish to iterate through the results programmatically,
+`fdtrack_iterate` can be used (warning: this interface is currently unstable,
+don't use it in code that can be used on multiple platform versions.)
+
+libfdtrack adds a significant amount of overhead, so for processes that are
+latency-critical like system_server, it's not feasible to always capture
+backtraces. Instead, if you can detect that an fd leak is ongoing, turning on
+backtraces for a while and then triggering a dump can be sufficient.
+system_server [implements this approach](https://android.googlesource.com/platform/frameworks/base/+/679f3e4242b8e018eb7df90ef433f81088a64fff%5E%21/),
+spawning a thread that regularly checks the count of fds in the process, turns
+on fdtrack when it hits a threshold, and then aborts after another threshold.
+This dumps the output to logcat, which will be available in both the tombstone
+and logcat from bugreports.
+
+#### Implementation details
+There are multiple methods to unwind in Android:
+
+ * libunwindstack
+   * Pros
+     * Primary method on the platform
+     * Able to unwind through ART
+   * Cons
+     * Uses malloc internally: unsafe unless a separate allocator is
+       statically-linked and steps are taken to prevent the unwind from being
+       interrupted by a signal
+     * Slow - infeasible to be used always in latency-sensitive processes
+ * `android_unsafe_frame_pointer_chase`
+   * Pros
+     * Definitely async signal safe
+     * Fast
+   * Cons
+     * Unable to unwind through ART because it doesn't maintain the frame pointer
+     * Requires -fno-omit-frame-pointer to be used on all code being unwound
+       through, which currently isn't the case on Android
+     * Frame layout is a mess on 32-bit ARM: the ARM standard, clang, and GCC
+       [all disagree](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92172)
+     * Chasing the frame pointer will often result in multiple frames inside the
+       same function
+
+libfdtrack chooses to use libunwindstack for now, since unwinding through ART
+is critical to being useful for the initial user, system_server.
diff --git a/docs/libc_assembler.md b/docs/libc_assembler.md
index 44c0036..43bcfc7 100644
--- a/docs/libc_assembler.md
+++ b/docs/libc_assembler.md
@@ -10,7 +10,8 @@
 * Rerun the benchmarks using the updated image that uses the code for
 the new routine. See the [Performance](#Performance) section for details about
 benchmarking.
-* Verify that unwind information for new routine looks sane. See the [Unwind Info](#unwind-info) section for details about how to verify this.
+* Verify that unwind information for new routine looks correct. See
+the [Unwind Info](#unwind-info) section for details about how to verify this.
 
 When benchmarking, it's best to verify on the latest Pixel device supported.
 Make sure that you benchmark both the big and little cores to verify that
diff --git a/libc/Android.bp b/libc/Android.bp
index d3271ae..49b75c1 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -4,10 +4,10 @@
     "async_safe/async_safe_log.cpp",
     "bionic/ether_aton.c",
     "bionic/ether_ntoa.c",
+    "bionic/exit.cpp",
     "bionic/fts.c",
     "bionic/initgroups.c",
     "bionic/isatty.c",
-    "bionic/pututline.c",
     "bionic/sched_cpualloc.c",
     "bionic/sched_cpucount.c",
     "stdio/fmemopen.cpp",
@@ -17,7 +17,6 @@
     "stdio/stdio_ext.cpp",
     "stdio/vfscanf.cpp",
     "stdio/vfwscanf.c",
-    "stdlib/exit.c",
 ]
 
 // off64_t/time64_t support on LP32.
@@ -65,7 +64,13 @@
         "bionic/libc/async_safe/include",
     ],
 
-    header_libs: ["gwp_asan_headers"],
+    header_libs: [
+        "libc_headers",
+        "gwp_asan_headers",
+    ],
+    export_header_lib_headers: [
+        "libc_headers",
+    ],
 
     stl: "none",
     system_shared_libs: [],
@@ -75,7 +80,6 @@
         // TODO(b/132640749): Fix broken fuzzer support.
         fuzzer: false,
     },
-    native_coverage: false,
     ramdisk_available: true,
     recovery_available: true,
     native_bridge_supported: true,
@@ -88,6 +92,15 @@
         experimental_mte: {
             cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
         },
+        malloc_zero_contents: {
+            cflags: ["-DSCUDO_ZERO_CONTENTS"],
+        },
+        malloc_pattern_fill_contents: {
+            cflags: ["-DSCUDO_PATTERN_FILL_CONTENTS"],
+        },
+        malloc_not_svelte: {
+            cflags: ["-DUSE_SCUDO"],
+        },
     },
 }
 
@@ -377,7 +390,6 @@
         "upstream-netbsd/lib/libc/gen/nice.c",
         "upstream-netbsd/lib/libc/gen/psignal.c",
         "upstream-netbsd/lib/libc/gen/utime.c",
-        "upstream-netbsd/lib/libc/gen/utmp.c",
         "upstream-netbsd/lib/libc/inet/nsap_addr.c",
         "upstream-netbsd/lib/libc/regex/regcomp.c",
         "upstream-netbsd/lib/libc/regex/regerror.c",
@@ -513,6 +525,7 @@
         "upstream-openbsd/lib/libc/stdlib/llabs.c",
         "upstream-openbsd/lib/libc/stdlib/lldiv.c",
         "upstream-openbsd/lib/libc/stdlib/lsearch.c",
+        "upstream-openbsd/lib/libc/stdlib/recallocarray.c",
         "upstream-openbsd/lib/libc/stdlib/remque.c",
         "upstream-openbsd/lib/libc/stdlib/setenv.c",
         "upstream-openbsd/lib/libc/stdlib/tfind.c",
@@ -554,6 +567,7 @@
     srcs: [
         "stdio/vfprintf.cpp",
         "stdio/vfwprintf.cpp",
+        "upstream-openbsd/lib/libc/string/memmem.c",
         "upstream-openbsd/lib/libc/string/strstr.c",
     ],
     cflags: [
@@ -608,6 +622,7 @@
         arm64: {
             exclude_srcs: [
                 "upstream-openbsd/lib/libc/string/memchr.c",
+                "upstream-openbsd/lib/libc/string/memrchr.c",
                 "upstream-openbsd/lib/libc/string/stpcpy.c",
                 "upstream-openbsd/lib/libc/string/strcpy.c",
                 "upstream-openbsd/lib/libc/string/strncmp.c",
@@ -777,6 +792,7 @@
         "bionic/android_set_abort_message.cpp",
 
         "bionic/strchr.cpp",
+        "bionic/strchrnul.cpp",
         "bionic/strnlen.c",
         "bionic/strrchr.cpp",
     ],
@@ -837,28 +853,11 @@
         },
         arm64: {
             srcs: [
-                "arch-arm64/generic/bionic/memcmp.S",
                 "arch-arm64/generic/bionic/memcpy.S",
                 "arch-arm64/generic/bionic/memmove.S",
                 "arch-arm64/generic/bionic/memset.S",
-                "arch-arm64/generic/bionic/stpcpy.S",
-                "arch-arm64/generic/bionic/strcpy.S",
                 "arch-arm64/generic/bionic/wmemmove.S",
 
-                "arch-arm64/default/bionic/memchr.S",
-                "arch-arm64/default/bionic/strchr.S",
-                "arch-arm64/default/bionic/strcmp.S",
-                "arch-arm64/default/bionic/strlen.S",
-                "arch-arm64/default/bionic/strncmp.S",
-                "arch-arm64/default/bionic/strnlen.S",
-
-                "arch-arm64/mte/bionic/memchr.c",
-                "arch-arm64/mte/bionic/strchr.cpp",
-                "arch-arm64/mte/bionic/strcmp.c",
-                "arch-arm64/mte/bionic/strlen.c",
-                "arch-arm64/mte/bionic/strncmp.c",
-                "arch-arm64/mte/bionic/strnlen.c",
-
                 "arch-arm64/bionic/__bionic_clone.S",
                 "arch-arm64/bionic/_exit_with_stack_teardown.S",
                 "arch-arm64/bionic/setjmp.S",
@@ -868,7 +867,9 @@
             exclude_srcs: [
                 "bionic/__memcpy_chk.cpp",
                 "bionic/strchr.cpp",
+                "bionic/strchrnul.cpp",
                 "bionic/strnlen.c",
+                "bionic/strrchr.cpp",
             ],
         },
 
@@ -911,6 +912,7 @@
                 "arch-x86/bionic/setjmp.S",
                 "arch-x86/bionic/syscall.S",
                 "arch-x86/bionic/vfork.S",
+                "arch-x86/bionic/__x86.get_pc_thunk.S",
 
                 // ssse3 functions
                 "arch-x86/atom/string/ssse3-strcat-atom.S",
@@ -1009,7 +1011,6 @@
         "bionic/bionic_arc4random.cpp",
         "bionic/bionic_futex.cpp",
         "bionic/bionic_netlink.cpp",
-        "bionic/bionic_systrace.cpp",
         "bionic/bionic_time_conversions.cpp",
         "bionic/brk.cpp",
         "bionic/c16rtomb.cpp",
@@ -1074,7 +1075,6 @@
         "bionic/mblen.cpp",
         "bionic/mbrtoc16.cpp",
         "bionic/mbrtoc32.cpp",
-        "bionic/memmem.cpp",
         "bionic/mempcpy.cpp",
         "bionic/mkdir.cpp",
         "bionic/mkfifo.cpp",
@@ -1121,7 +1121,6 @@
         "bionic/spawn.cpp",
         "bionic/stat.cpp",
         "bionic/stdlib_l.cpp",
-        "bionic/strchrnul.cpp",
         "bionic/strerror.cpp",
         "bionic/string_l.cpp",
         "bionic/strings_l.cpp",
@@ -1153,6 +1152,7 @@
         "bionic/umount.cpp",
         "bionic/unlink.cpp",
         "bionic/usleep.cpp",
+        "bionic/utmp.cpp",
         "bionic/wait.cpp",
         "bionic/wchar.cpp",
         "bionic/wchar_l.cpp",
@@ -1177,7 +1177,9 @@
             cflags: ["-DTREBLE_LINKER_NAMESPACES"],
         },
     },
-    whole_static_libs: ["libsystemproperties"],
+    whole_static_libs: [
+        "libsystemproperties",
+    ],
     cppflags: ["-Wold-style-cast"],
     local_include_dirs: ["stdio"],
     include_dirs: ["bionic/libstdc++/include"],
@@ -1186,6 +1188,21 @@
 }
 
 // ========================================================
+// libc_bionic_systrace.a
+// ========================================================
+
+cc_library_static {
+    name: "libc_bionic_systrace",
+    defaults: ["libc_defaults"],
+    srcs: [
+        "bionic/bionic_systrace.cpp",
+    ],
+    apex_available: [
+        "com.android.runtime",
+    ],
+}
+
+// ========================================================
 // libc_pthread.a - pthreads parts that previously lived in
 // libc_bionic.a. Relocated to their own library because
 // they can't be included in libc_ndk.a (as the layout of
@@ -1220,6 +1237,7 @@
         "bionic/pthread_setname_np.cpp",
         "bionic/pthread_setschedparam.cpp",
         "bionic/pthread_spinlock.cpp",
+        "bionic/sys_thread_properties.cpp",
 
         // The following implementations depend on pthread data or implementation,
         // so we can't include them in libc_ndk.a.
@@ -1358,6 +1376,7 @@
 
     whole_static_libs: [
         "gwp_asan",
+        "libarm-optimized-routines-string",
         "libc_bionic_ndk",
         "libc_bootstrap",
         "libc_fortify",
@@ -1388,6 +1407,7 @@
     name: "libc_nopthread",
 
     whole_static_libs: [
+        "libarm-optimized-routines-string",
         "libc_bionic",
         "libc_bionic_ndk",
         "libc_bootstrap",
@@ -1580,7 +1600,6 @@
     ],
     name: "libc",
     static_ndk_lib: true,
-    export_include_dirs: ["include"],
     product_variables: {
         platform_sdk_version: {
             asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1643,6 +1662,8 @@
                 srcs: [":libc_sources_shared_arm"],
                 // special for arm
                 cflags: ["-DCRT_LEGACY_WORKAROUND"],
+
+                whole_static_libs: [ "libunwind_llvm" ],
             },
 
             // Arm 32 bit does not produce complete exidx unwind information
@@ -1652,8 +1673,6 @@
             strip: {
                 keep_symbols_and_debug_frame: true,
             },
-
-            whole_static_libs: [ "libunwind_llvm" ],
         },
         arm64: {
             version_script: ":libc.arm64.map",
@@ -1664,7 +1683,9 @@
                 keep_symbols: true,
             },
 
-            whole_static_libs: [ "libgcc_stripped" ],
+            shared: {
+                whole_static_libs: [ "libgcc_stripped" ],
+            },
         },
         x86: {
             // TODO: This is to work around b/24465209. Remove after root cause is fixed.
@@ -1679,7 +1700,9 @@
                 keep_symbols: true,
             },
 
-            whole_static_libs: [ "libgcc_stripped" ],
+            shared: {
+                whole_static_libs: [ "libgcc_stripped" ],
+            },
         },
         x86_64: {
             version_script: ":libc.x86_64.map",
@@ -1690,7 +1713,9 @@
                 keep_symbols: true,
             },
 
-            whole_static_libs: [ "libgcc_stripped" ],
+            shared: {
+                whole_static_libs: [ "libgcc_stripped" ],
+            },
         },
     },
 
@@ -1748,6 +1773,7 @@
 // Headers that only other parts of the platform can include.
 cc_library_headers {
     name: "bionic_libc_platform_headers",
+    defaults: ["linux_bionic_supported"],
     visibility: [
         "//art:__subpackages__",
         "//bionic:__subpackages__",
@@ -1757,9 +1783,10 @@
         "//external/perfetto:__subpackages__",
         "//external/scudo:__subpackages__",
         "//system/core/debuggerd:__subpackages__",
+        "//system/core/libunwindstack:__subpackages__",
         "//system/memory/libmemunreachable:__subpackages__",
+        "//tools/security/sanitizer-status:__subpackages__",
     ],
-    host_supported: true,
     vendor_available: true,
     ramdisk_available: true,
     recovery_available: true,
@@ -1779,9 +1806,13 @@
     ],
 }
 
-// libc_headers for libasync_safe and libpropertyinfoparser
 cc_library_headers {
-    name: "libc_headers",
+    // Internal lib for use in libc_headers. Since we cannot intersect arch{}
+    // and target{} in the same module, this one specifies the arch-dependent
+    // include paths, and then libc_headers filters by target so that the
+    // headers only are included for Bionic targets.
+    name: "libc_headers_arch",
+    visibility: ["//visibility:private"],
 
     host_supported: true,
     vendor_available: true,
@@ -1794,14 +1825,6 @@
     ],
     // used by most APEXes indirectly via libunwind_llvm
     min_sdk_version: "apex_inherit",
-    visibility: [
-        ":__subpackages__", // visible to bionic
-        // ... and only to these places (b/152668052)
-        "//external/gwp_asan",
-        "//external/libunwind_llvm",
-        "//system/core/property_service/libpropertyinfoparser",
-        "//system/extras/toolchain-extras",
-    ],
 
     no_libcrt: true,
     stl: "none",
@@ -1815,36 +1838,77 @@
     // is correct because the headers can support any sdk_version.
     sdk_version: "1",
 
-    export_include_dirs: [
+    export_system_include_dirs: [
         "include",
         "kernel/uapi",
+        "kernel/android/scsi",
         "kernel/android/uapi",
     ],
 
     arch: {
         arm: {
-            export_include_dirs: [
-                "kernel/uapi/asm-arm",
-            ],
+            export_system_include_dirs: ["kernel/uapi/asm-arm"],
         },
         arm64: {
-            export_include_dirs: [
-                "kernel/uapi/asm-arm64",
-            ],
+            export_system_include_dirs: ["kernel/uapi/asm-arm64"],
         },
         x86: {
-            export_include_dirs: [
-                "kernel/uapi/asm-x86",
-            ],
+            export_system_include_dirs: ["kernel/uapi/asm-x86"],
         },
         x86_64: {
-            export_include_dirs: [
-                "kernel/uapi/asm-x86",
-            ],
+            export_system_include_dirs: ["kernel/uapi/asm-x86"],
         },
     },
 }
 
+cc_library_headers {
+    name: "libc_headers",
+    host_supported: true,
+    native_bridge_supported: true,
+    vendor_available: true,
+    ramdisk_available: true,
+    recovery_available: true,
+    sdk_version: "1",
+
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
+    // used by most APEXes indirectly via libunwind_llvm
+    min_sdk_version: "apex_inherit",
+    visibility: [
+        "//bionic:__subpackages__", // visible to bionic
+        // ... and only to these places (b/152668052)
+        "//external/arm-optimized-routines",
+        "//external/gwp_asan",
+        "//external/jemalloc_new",
+        "//external/libunwind_llvm",
+        "//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",
+    no_libcrt: true,
+    system_shared_libs: [],
+
+    target: {
+        android: {
+            header_libs: ["libc_headers_arch"],
+            export_header_lib_headers: ["libc_headers_arch"],
+        },
+        linux_bionic: {
+            header_libs: ["libc_headers_arch"],
+            export_header_lib_headers: ["libc_headers_arch"],
+        },
+    }
+}
+
 // ========================================================
 // libstdc++.so and libstdc++.a.
 // ========================================================
@@ -1937,8 +2001,10 @@
         "//apex_available:platform",
         "//apex_available:anyapex",
     ],
-    // crt* objects are used by most cc_binary/cc_library in "anyapex"
-    min_sdk_version: "apex_inherit",
+    // Generate NDK variants of the CRT objects for every supported API level.
+    min_sdk_version: "16",
+    stl: "none",
+    crt: true,
     cflags: [
         "-Wno-gcc-compat",
         "-Wall",
@@ -2315,11 +2381,11 @@
     ],
 }
 
-// SECCOMP_BLACKLIST_APP_ZYGOTE.TXT = SECCOMP_BLACKLIST_APP.txt - setresgid*
+// SECCOMP_BLOCKLIST_APP_ZYGOTE.TXT = SECCOMP_BLOCKLIST_APP.txt - setresgid*
 genrule {
-    name: "generate_app_zygote_blacklist",
-    out: ["SECCOMP_BLACKLIST_APP_ZYGOTE.TXT"],
-    srcs: ["SECCOMP_BLACKLIST_APP.TXT"],
+    name: "generate_app_zygote_blocklist",
+    out: ["SECCOMP_BLOCKLIST_APP_ZYGOTE.TXT"],
+    srcs: ["SECCOMP_BLOCKLIST_APP.TXT"],
     cmd: "grep -v '^int[ \t]*setresgid' $(in) > $(out)",
 }
 
@@ -2332,11 +2398,11 @@
 
     srcs: [
         "SYSCALLS.TXT",
-        "SECCOMP_WHITELIST_COMMON.TXT",
-        "SECCOMP_WHITELIST_APP.TXT",
-        "SECCOMP_BLACKLIST_COMMON.TXT",
+        "SECCOMP_ALLOWLIST_COMMON.TXT",
+        "SECCOMP_ALLOWLIST_APP.TXT",
+        "SECCOMP_BLOCKLIST_COMMON.TXT",
         "SECCOMP_PRIORITY.TXT",
-        ":generate_app_zygote_blacklist",
+        ":generate_app_zygote_blocklist",
         ":libseccomp_gen_syscall_nrs_arm",
         ":libseccomp_gen_syscall_nrs_arm64",
         ":libseccomp_gen_syscall_nrs_x86",
@@ -2360,10 +2426,10 @@
 
     srcs: [
         "SYSCALLS.TXT",
-        "SECCOMP_WHITELIST_COMMON.TXT",
-        "SECCOMP_WHITELIST_APP.TXT",
-        "SECCOMP_BLACKLIST_COMMON.TXT",
-        "SECCOMP_BLACKLIST_APP.TXT",
+        "SECCOMP_ALLOWLIST_COMMON.TXT",
+        "SECCOMP_ALLOWLIST_APP.TXT",
+        "SECCOMP_BLOCKLIST_COMMON.TXT",
+        "SECCOMP_BLOCKLIST_APP.TXT",
         "SECCOMP_PRIORITY.TXT",
         ":libseccomp_gen_syscall_nrs_arm",
         ":libseccomp_gen_syscall_nrs_arm64",
@@ -2388,9 +2454,9 @@
 
     srcs: [
         "SYSCALLS.TXT",
-        "SECCOMP_WHITELIST_COMMON.TXT",
-        "SECCOMP_WHITELIST_SYSTEM.TXT",
-        "SECCOMP_BLACKLIST_COMMON.TXT",
+        "SECCOMP_ALLOWLIST_COMMON.TXT",
+        "SECCOMP_ALLOWLIST_SYSTEM.TXT",
+        "SECCOMP_BLOCKLIST_COMMON.TXT",
         "SECCOMP_PRIORITY.TXT",
         ":libseccomp_gen_syscall_nrs_arm",
         ":libseccomp_gen_syscall_nrs_arm64",
@@ -2433,75 +2499,6 @@
     },
 }
 
-// This is a temporary library that will use scudo as the native memory
-// allocator. To use it, add it as the first shared library.
-cc_defaults {
-    name: "libc_scudo_wrapper_defaults",
-    srcs: [
-        "bionic/gwp_asan_wrappers.cpp",
-        "bionic/heap_tagging.cpp",
-        "bionic/malloc_common.cpp",
-        "bionic/malloc_common_dynamic.cpp",
-        "bionic/malloc_heapprofd.cpp",
-        "bionic/malloc_limit.cpp",
-        "bionic/scudo_wrapper.cpp",
-        "bionic/__set_errno.cpp",
-    ],
-    cflags: [
-        "-DUSE_SCUDO",
-        "-fno-emulated-tls", // Required for GWP-ASan.
-    ],
-    shared_libs: ["libscudo_wrapper"],
-
-    header_libs: [
-        "libc_headers",
-        "gwp_asan_headers",
-    ],
-
-    static_libs: [
-        "libasync_safe",
-        "gwp_asan",
-    ],
-
-    arch: {
-        arm: {
-            srcs: [":syscalls-arm.S"],
-        },
-        arm64: {
-            srcs: [":syscalls-arm64.S"],
-        },
-        x86: {
-            srcs: [
-                "arch-x86/bionic/__libc_init_sysinfo.cpp",
-                ":syscalls-x86.S",
-            ],
-        },
-        x86_64: {
-            srcs: [":syscalls-x86_64.S"],
-        },
-    },
-
-    // Mark this library as global so it overrides all the allocation
-    // definitions properly.
-    ldflags: ["-Wl,-z,global"],
-}
-
-cc_library_shared {
-    name: "libc_scudo",
-    vendor_available: true,
-    stl: "none",
-    system_shared_libs: [],
-
-    allow_undefined_symbols: true,
-    // Like libc, disable native coverage for libc_scudo.
-    native_coverage: false,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media.swcodec",
-    ],
-    min_sdk_version: "apex_inherit",
-}
-
 subdirs = [
     "bionic/scudo",
 ]
diff --git a/libc/NOTICE b/libc/NOTICE
index 8245ff8..58d6679 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -1,60 +1,3 @@
-   Copyright (c) 2014, ARM Limited
-   All rights Reserved.
-   Copyright (c) 2014, Linaro Ltd.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the company nor the names of its contributors
-         may be used to endorse or promote products derived from this
-         software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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) 2014, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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) 1993 John Brezak
  All rights reserved.
 
@@ -1097,6 +1040,22 @@
 -------------------------------------------------------------------
 
 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
@@ -3061,7 +3020,7 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+Copyright (c) 1997 Todd C. Miller <millert@openbsd.org>
 
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
@@ -3513,35 +3472,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2002 The NetBSD Foundation, Inc.
-All rights reserved.
-
-This code is derived from software contributed to The NetBSD Foundation
-by Christos Zoulas.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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) 2002 Tim J. Robbins
 All rights reserved.
 
@@ -4301,7 +4231,30 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2005-2014 Rich Felker
+Copyright (c) 2005-2018 Rich Felker
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2005-2020 Rich Felker, et al.
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -4659,7 +4612,23 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2008 Todd C. Miller <millert@openbsd.org>
+Copyright (c) 2008, 2016 Todd C. Miller <millert@openbsd.org>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
 
 Permission to use, copy, modify, and distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
@@ -5225,34 +5194,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2012, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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) 2012-2013, Linaro Limited
    All rights reserved.
 
@@ -5465,33 +5406,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2013-2015, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-     notice, this list of conditions and the following disclaimer in the
-     documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-     names of its contributors may be used to endorse or promote products
-     derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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
-
--------------------------------------------------------------------
-
 Copyright (c) 2014, Intel Corporation
 All rights reserved.
 
@@ -5632,34 +5546,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2017 ARM Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. The name of the company may not be used to endorse or promote
-   products derived from this software without specific prior written
-   permission.
-
-THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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)1999 Citrus Project,
 All rights reserved.
 
diff --git a/libc/SECCOMP_WHITELIST_APP.TXT b/libc/SECCOMP_ALLOWLIST_APP.TXT
similarity index 96%
rename from libc/SECCOMP_WHITELIST_APP.TXT
rename to libc/SECCOMP_ALLOWLIST_APP.TXT
index dc48715..ba40b60 100644
--- a/libc/SECCOMP_WHITELIST_APP.TXT
+++ b/libc/SECCOMP_ALLOWLIST_APP.TXT
@@ -1,4 +1,4 @@
-# This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
+# This file is used to populate seccomp's allowlist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
 # This file is processed by a python script named genseccomp.py.
diff --git a/libc/SECCOMP_WHITELIST_COMMON.TXT b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
similarity index 98%
rename from libc/SECCOMP_WHITELIST_COMMON.TXT
rename to libc/SECCOMP_ALLOWLIST_COMMON.TXT
index 56f9d1d..804676e 100644
--- a/libc/SECCOMP_WHITELIST_COMMON.TXT
+++ b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
@@ -1,4 +1,4 @@
-# This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
+# This file is used to populate seccomp's allowlist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
 # This file is processed by a python script named genseccomp.py.
diff --git a/libc/SECCOMP_WHITELIST_SYSTEM.TXT b/libc/SECCOMP_ALLOWLIST_SYSTEM.TXT
similarity index 78%
rename from libc/SECCOMP_WHITELIST_SYSTEM.TXT
rename to libc/SECCOMP_ALLOWLIST_SYSTEM.TXT
index 266fe30..756affe 100644
--- a/libc/SECCOMP_WHITELIST_SYSTEM.TXT
+++ b/libc/SECCOMP_ALLOWLIST_SYSTEM.TXT
@@ -1,4 +1,4 @@
-# This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
+# This file is used to populate seccomp's allowlist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
 # This file is processed by a python script named genseccomp.py.
diff --git a/libc/SECCOMP_BLACKLIST_COMMON.TXT b/libc/SECCOMP_BLACKLIST_COMMON.TXT
deleted file mode 100644
index 8ae21c1..0000000
--- a/libc/SECCOMP_BLACKLIST_COMMON.TXT
+++ /dev/null
@@ -1,10 +0,0 @@
-# This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
-# Note that the resultant policy is applied only to zygote spawned processes.
-#
-# The final seccomp whitelist is SYSCALLS.TXT - SECCOMP_BLACKLIST.TXT + SECCOMP_WHITELIST.TXT
-# Any entry in the blacklist must be in the syscalls file and not be in the whitelist file
-#
-# This file is processed by a python script named genseccomp.py.
-
-int     swapon(const char*, int) all
-int     swapoff(const char*) all
diff --git a/libc/SECCOMP_BLACKLIST_APP.TXT b/libc/SECCOMP_BLOCKLIST_APP.TXT
similarity index 89%
rename from libc/SECCOMP_BLACKLIST_APP.TXT
rename to libc/SECCOMP_BLOCKLIST_APP.TXT
index 40ca222..f14e11c 100644
--- a/libc/SECCOMP_BLACKLIST_APP.TXT
+++ b/libc/SECCOMP_BLOCKLIST_APP.TXT
@@ -1,8 +1,8 @@
-# This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
+# This file is used to populate seccomp's allowlist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
-# The final seccomp whitelist is SYSCALLS.TXT - SECCOMP_BLACKLIST.TXT + SECCOMP_WHITELIST.TXT
-# Any entry in the blacklist must be in the syscalls file and not be in the whitelist file
+# The final seccomp allowlist is SYSCALLS.TXT - SECCOMP_BLOCKLIST.TXT + SECCOMP_ALLOWLIST.TXT
+# Any entry in the blocklist must be in the syscalls file and not be in the allowlist file
 #
 # This file is processed by a python script named genseccomp.py.
 
diff --git a/libc/SECCOMP_BLOCKLIST_COMMON.TXT b/libc/SECCOMP_BLOCKLIST_COMMON.TXT
new file mode 100644
index 0000000..22c9844
--- /dev/null
+++ b/libc/SECCOMP_BLOCKLIST_COMMON.TXT
@@ -0,0 +1,10 @@
+# This file is used to populate seccomp's allowlist policy in combination with SYSCALLS.TXT.
+# Note that the resultant policy is applied only to zygote spawned processes.
+#
+# The final seccomp allowlist is SYSCALLS.TXT - SECCOMP_BLOCKLIST.TXT + SECCOMP_ALLOWLIST.TXT
+# Any entry in the blocklist must be in the syscalls file and not be in the allowlist file
+#
+# This file is processed by a python script named genseccomp.py.
+
+int     swapon(const char*, int) all
+int     swapoff(const char*) all
diff --git a/libc/SECCOMP_PRIORITY.TXT b/libc/SECCOMP_PRIORITY.TXT
index fb5ad4a..bccc426 100644
--- a/libc/SECCOMP_PRIORITY.TXT
+++ b/libc/SECCOMP_PRIORITY.TXT
@@ -1,4 +1,4 @@
-# This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
+# This file is used to populate seccomp's allowlist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
 # This file is processed by a python script named genseccomp.py.
diff --git a/libc/arch-arm/bionic/__restore.S b/libc/arch-arm/bionic/__restore.S
index 8c1e41d..5291743 100644
--- a/libc/arch-arm/bionic/__restore.S
+++ b/libc/arch-arm/bionic/__restore.S
@@ -28,13 +28,14 @@
 
 #include <private/bionic_asm.h>
 
-// gdb is smart enough to unwind through signal frames with just the regular
+// gdb is able to unwind through signal frames with just the regular
 // CFI information but libgcc and libunwind both need extra help. We do this
 // by using .fnstart/.fnend and inserting a nop before both __restore and
 // __restore_rt (but covered by the .fnstart/.fnend) so that although they're
 // not inside the functions from objdump's point of view, an unwinder that
-// blindly looks at the previous instruction (but is then smart enough to check
-// the unwind information to find out where it landed) gets the right answer.
+// just assumes it should look at the previous instruction (but is then smart
+// enough to check the unwind information to find out where it landed) gets
+// the right answer.
 // Make sure not to have both DWARF and ARM unwind information, so only
 // use the ARM unwind information.
 
diff --git a/libc/arch-arm64/default/bionic/memchr.S b/libc/arch-arm64/default/bionic/memchr.S
deleted file mode 100644
index 7fbcc8f..0000000
--- a/libc/arch-arm64/default/bionic/memchr.S
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *
-   Copyright (c) 2014, ARM Limited
-   All rights Reserved.
-   Copyright (c) 2014, Linaro Ltd.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the company nor the names of its contributors
-         may be used to endorse or promote products derived from this
-         software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Neon Available.
- */
-
-#include <private/bionic_asm.h>
-
-/* Arguments and results.  */
-#define srcin		x0
-#define chrin		w1
-#define cntin		x2
-
-#define result		x0
-
-#define src		x3
-#define	tmp		x4
-#define wtmp2		w5
-#define synd		x6
-#define soff		x9
-#define cntrem		x10
-
-#define vrepchr		v0
-#define vdata1		v1
-#define vdata2		v2
-#define vhas_chr1	v3
-#define vhas_chr2	v4
-#define vrepmask	v5
-#define vend		v6
-
-/*
- * Core algorithm:
- *
- * For each 32-byte chunk we calculate a 64-bit syndrome value, with two bits
- * per byte. For each tuple, bit 0 is set if the relevant byte matched the
- * requested character and bit 1 is not used (faster than using a 32bit
- * syndrome). Since the bits in the syndrome reflect exactly the order in which
- * things occur in the original string, counting trailing zeros allows to
- * identify exactly which byte has matched.
- */
-
-ENTRY(memchr_default)
-	/*
-	 * Magic constant 0x40100401 allows us to identify which lane matches
-	 * the requested byte.
-	 */
-	cbz	cntin, .Lzero_length
-	mov	wtmp2, #0x0401
-	movk	wtmp2, #0x4010, lsl #16
-	dup	vrepchr.16b, chrin
-	/* Work with aligned 32-byte chunks */
-	bic	src, srcin, #31
-	dup	vrepmask.4s, wtmp2
-	ands	soff, srcin, #31
-	and	cntrem, cntin, #31
-	b.eq	.Lloop
-
-	/*
-	 * Input string is not 32-byte aligned. We calculate the syndrome
-	 * value for the aligned 32 bytes block containing the first bytes
-	 * and mask the irrelevant part.
-	 */
-
-	ld1	{vdata1.16b, vdata2.16b}, [src], #32
-	sub	tmp, soff, #32
-	adds	cntin, cntin, tmp
-	cmeq	vhas_chr1.16b, vdata1.16b, vrepchr.16b
-	cmeq	vhas_chr2.16b, vdata2.16b, vrepchr.16b
-	and	vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
-	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
-	addp	vend.16b, vhas_chr1.16b, vhas_chr2.16b		/* 256->128 */
-	addp	vend.16b, vend.16b, vend.16b			/* 128->64 */
-	mov	synd, vend.d[0]
-	/* Clear the soff*2 lower bits */
-	lsl	tmp, soff, #1
-	lsr	synd, synd, tmp
-	lsl	synd, synd, tmp
-	/* The first block can also be the last */
-	b.ls	.Lmasklast
-	/* Have we found something already? */
-	cbnz	synd, .Ltail
-
-.Lloop:
-	ld1	{vdata1.16b, vdata2.16b}, [src], #32
-	subs	cntin, cntin, #32
-	cmeq	vhas_chr1.16b, vdata1.16b, vrepchr.16b
-	cmeq	vhas_chr2.16b, vdata2.16b, vrepchr.16b
-	/* If we're out of data we finish regardless of the result */
-	b.ls	.Lend
-	/* Use a fast check for the termination condition */
-	orr	vend.16b, vhas_chr1.16b, vhas_chr2.16b
-	addp	vend.2d, vend.2d, vend.2d
-	mov	synd, vend.d[0]
-	/* We're not out of data, loop if we haven't found the character */
-	cbz	synd, .Lloop
-
-.Lend:
-	/* Termination condition found, let's calculate the syndrome value */
-	and	vhas_chr1.16b, vhas_chr1.16b, vrepmask.16b
-	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask.16b
-	addp	vend.16b, vhas_chr1.16b, vhas_chr2.16b		/* 256->128 */
-	addp	vend.16b, vend.16b, vend.16b			/* 128->64 */
-	mov	synd, vend.d[0]
-	/* Only do the clear for the last possible block */
-	b.hi	.Ltail
-
-.Lmasklast:
-	/* Clear the (32 - ((cntrem + soff) % 32)) * 2 upper bits */
-	add	tmp, cntrem, soff
-	and	tmp, tmp, #31
-	sub	tmp, tmp, #32
-	neg	tmp, tmp, lsl #1
-	lsl	synd, synd, tmp
-	lsr	synd, synd, tmp
-
-.Ltail:
-	/* Count the trailing zeros using bit reversing */
-	rbit	synd, synd
-	/* Compensate the last post-increment */
-	sub	src, src, #32
-	/* Check that we have found a character */
-	cmp	synd, #0
-	/* And count the leading zeros */
-	clz	synd, synd
-	/* Compute the potential result */
-	add	result, src, synd, lsr #1
-	/* Select result or NULL */
-	csel	result, xzr, result, eq
-	ret
-
-.Lzero_length:
-	mov	result, xzr
-	ret
-END(memchr_default)
diff --git a/libc/arch-arm64/default/bionic/strchr.S b/libc/arch-arm64/default/bionic/strchr.S
deleted file mode 100644
index f8cb724..0000000
--- a/libc/arch-arm64/default/bionic/strchr.S
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *
-   Copyright (c) 2014, ARM Limited
-   All rights Reserved.
-   Copyright (c) 2014, Linaro Ltd.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the company nor the names of its contributors
-         may be used to endorse or promote products derived from this
-         software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- * Neon Available.
- */
-
-#include <private/bionic_asm.h>
-
-/* Arguments and results.  */
-#define srcin		x0
-#define chrin		w1
-
-#define result		x0
-
-#define src		x2
-#define	tmp1		x3
-#define wtmp2		w4
-#define tmp3		x5
-
-#define vrepchr		v0
-#define vdata1		v1
-#define vdata2		v2
-#define vhas_nul1	v3
-#define vhas_nul2	v4
-#define vhas_chr1	v5
-#define vhas_chr2	v6
-#define vrepmask_0	v7
-#define vrepmask_c	v16
-#define vend1		v17
-#define vend2		v18
-
-/* Core algorithm.
-
-   For each 32-byte hunk we calculate a 64-bit syndrome value, with
-   two bits per byte (LSB is always in bits 0 and 1, for both big
-   and little-endian systems).  For each tuple, bit 0 is set iff
-   the relevant byte matched the requested character; bit 1 is set
-   iff the relevant byte matched the NUL end of string (we trigger
-   off bit0 for the special case of looking for NUL).  Since the bits
-   in the syndrome reflect exactly the order in which things occur
-   in the original string a count_trailing_zeros() operation will
-   identify exactly which byte is causing the termination, and why.  */
-
-/* Locals and temporaries.  */
-
-ENTRY(strchr_default)
-	/* Magic constant 0x40100401 to allow us to identify which lane
-	   matches the requested byte.  Magic constant 0x80200802 used
-	   similarly for NUL termination.  */
-	mov	wtmp2, #0x0401
-	movk	wtmp2, #0x4010, lsl #16
-	dup	vrepchr.16b, chrin
-	bic	src, srcin, #31		/* Work with aligned 32-byte hunks.  */
-	dup	vrepmask_c.4s, wtmp2
-	ands	tmp1, srcin, #31
-	add	vrepmask_0.4s, vrepmask_c.4s, vrepmask_c.4s /* equiv: lsl #1 */
-	b.eq	.Lloop
-
-	/* Input string is not 32-byte aligned.  Rather than forcing
-	   the padding bytes to a safe value, we calculate the syndrome
-	   for all the bytes, but then mask off those bits of the
-	   syndrome that are related to the padding.  */
-	ld1	{vdata1.16b, vdata2.16b}, [src], #32
-	neg	tmp1, tmp1
-	cmeq	vhas_nul1.16b, vdata1.16b, #0
-	cmeq	vhas_chr1.16b, vdata1.16b, vrepchr.16b
-	cmeq	vhas_nul2.16b, vdata2.16b, #0
-	cmeq	vhas_chr2.16b, vdata2.16b, vrepchr.16b
-	and	vhas_nul1.16b, vhas_nul1.16b, vrepmask_0.16b
-	and	vhas_nul2.16b, vhas_nul2.16b, vrepmask_0.16b
-	and	vhas_chr1.16b, vhas_chr1.16b, vrepmask_c.16b
-	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask_c.16b
-	orr	vend1.16b, vhas_nul1.16b, vhas_chr1.16b
-	orr	vend2.16b, vhas_nul2.16b, vhas_chr2.16b
-	lsl	tmp1, tmp1, #1
-	addp	vend1.16b, vend1.16b, vend2.16b		// 256->128
-	mov	tmp3, #~0
-	addp	vend1.16b, vend1.16b, vend2.16b		// 128->64
-	lsr	tmp1, tmp3, tmp1
-
-	mov	tmp3, vend1.d[0]
-	bic	tmp1, tmp3, tmp1	// Mask padding bits.
-	cbnz	tmp1, .Ltail
-
-.Lloop:
-	ld1	{vdata1.16b, vdata2.16b}, [src], #32
-	cmeq	vhas_nul1.16b, vdata1.16b, #0
-	cmeq	vhas_chr1.16b, vdata1.16b, vrepchr.16b
-	cmeq	vhas_nul2.16b, vdata2.16b, #0
-	cmeq	vhas_chr2.16b, vdata2.16b, vrepchr.16b
-	/* Use a fast check for the termination condition.  */
-	orr	vend1.16b, vhas_nul1.16b, vhas_chr1.16b
-	orr	vend2.16b, vhas_nul2.16b, vhas_chr2.16b
-	orr	vend1.16b, vend1.16b, vend2.16b
-	addp	vend1.2d, vend1.2d, vend1.2d
-	mov	tmp1, vend1.d[0]
-	cbz	tmp1, .Lloop
-
-	/* Termination condition found.  Now need to establish exactly why
-	   we terminated.  */
-	and	vhas_nul1.16b, vhas_nul1.16b, vrepmask_0.16b
-	and	vhas_nul2.16b, vhas_nul2.16b, vrepmask_0.16b
-	and	vhas_chr1.16b, vhas_chr1.16b, vrepmask_c.16b
-	and	vhas_chr2.16b, vhas_chr2.16b, vrepmask_c.16b
-	orr	vend1.16b, vhas_nul1.16b, vhas_chr1.16b
-	orr	vend2.16b, vhas_nul2.16b, vhas_chr2.16b
-	addp	vend1.16b, vend1.16b, vend2.16b		// 256->128
-	addp	vend1.16b, vend1.16b, vend2.16b		// 128->64
-
-	mov	tmp1, vend1.d[0]
-.Ltail:
-	/* Count the trailing zeros, by bit reversing...  */
-	rbit	tmp1, tmp1
-	/* Re-bias source.  */
-	sub	src, src, #32
-	clz	tmp1, tmp1	/* And counting the leading zeros.  */
-	/* Tmp1 is even if the target charager was found first.  Otherwise
-	   we've found the end of string and we weren't looking for NUL.  */
-	tst	tmp1, #1
-	add	result, src, tmp1, lsr #1
-	csel	result, result, xzr, eq
-	ret
-END(strchr_default)
diff --git a/libc/arch-arm64/default/bionic/strcmp.S b/libc/arch-arm64/default/bionic/strcmp.S
deleted file mode 100644
index dfac7c4..0000000
--- a/libc/arch-arm64/default/bionic/strcmp.S
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright (c) 2012, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
-#include <private/bionic_asm.h>
-
-#define L(label) .L ## label
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-/* Parameters and result.  */
-#define src1		x0
-#define src2		x1
-#define result		x0
-
-/* Internal variables.  */
-#define data1		x2
-#define data1w		w2
-#define data2		x3
-#define data2w		w3
-#define has_nul		x4
-#define diff		x5
-#define syndrome	x6
-#define tmp1		x7
-#define tmp2		x8
-#define tmp3		x9
-#define zeroones	x10
-#define pos		x11
-
-	/* Start of performance-critical section  -- one 64B cache line.  */
-ENTRY(strcmp_default)
-.p2align  6
-	eor	tmp1, src1, src2
-	mov	zeroones, #REP8_01
-	tst	tmp1, #7
-	b.ne	L(misaligned8)
-	ands	tmp1, src1, #7
-	b.ne	L(mutual_align)
-	/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
-	   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
-	   can be done in parallel across the entire word.  */
-L(loop_aligned):
-	ldr	data1, [src1], #8
-	ldr	data2, [src2], #8
-L(start_realigned):
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, #REP8_7f
-	eor	diff, data1, data2	/* Non-zero if differences found.  */
-	bic	has_nul, tmp1, tmp2	/* Non-zero if NUL terminator.  */
-	orr	syndrome, diff, has_nul
-	cbz	syndrome, L(loop_aligned)
-	/* End of performance-critical section  -- one 64B cache line.  */
-
-L(end):
-#ifndef	__AARCH64EB__
-	rev	syndrome, syndrome
-	rev	data1, data1
-	/* The MS-non-zero bit of the syndrome marks either the first bit
-	   that is different, or the top bit of the first zero byte.
-	   Shifting left now will bring the critical information into the
-	   top bits.  */
-	clz	pos, syndrome
-	rev	data2, data2
-	lsl	data1, data1, pos
-	lsl	data2, data2, pos
-	/* But we need to zero-extend (char is unsigned) the value and then
-	   perform a signed 32-bit subtraction.  */
-	lsr	data1, data1, #56
-	sub	result, data1, data2, lsr #56
-	ret
-#else
-	/* For big-endian we cannot use the trick with the syndrome value
-	   as carry-propagation can corrupt the upper bits if the trailing
-	   bytes in the string contain 0x01.  */
-	/* However, if there is no NUL byte in the dword, we can generate
-	   the result directly.  We can't just subtract the bytes as the
-	   MSB might be significant.  */
-	cbnz	has_nul, 1f
-	cmp	data1, data2
-	cset	result, ne
-	cneg	result, result, lo
-	ret
-1:
-	/* Re-compute the NUL-byte detection, using a byte-reversed value.  */
-	rev	tmp3, data1
-	sub	tmp1, tmp3, zeroones
-	orr	tmp2, tmp3, #REP8_7f
-	bic	has_nul, tmp1, tmp2
-	rev	has_nul, has_nul
-	orr	syndrome, diff, has_nul
-	clz	pos, syndrome
-	/* The MS-non-zero bit of the syndrome marks either the first bit
-	   that is different, or the top bit of the first zero byte.
-	   Shifting left now will bring the critical information into the
-	   top bits.  */
-	lsl	data1, data1, pos
-	lsl	data2, data2, pos
-	/* But we need to zero-extend (char is unsigned) the value and then
-	   perform a signed 32-bit subtraction.  */
-	lsr	data1, data1, #56
-	sub	result, data1, data2, lsr #56
-	ret
-#endif
-
-L(mutual_align):
-	/* Sources are mutually aligned, but are not currently at an
-	   alignment boundary.  Round down the addresses and then mask off
-	   the bytes that preceed the start point.  */
-	bic	src1, src1, #7
-	bic	src2, src2, #7
-	lsl	tmp1, tmp1, #3		/* Bytes beyond alignment -> bits.  */
-	ldr	data1, [src1], #8
-	neg	tmp1, tmp1		/* Bits to alignment -64.  */
-	ldr	data2, [src2], #8
-	mov	tmp2, #~0
-#ifdef __AARCH64EB__
-	/* Big-endian.  Early bytes are at MSB.  */
-	lsl	tmp2, tmp2, tmp1	/* Shift (tmp1 & 63).  */
-#else
-	/* Little-endian.  Early bytes are at LSB.  */
-	lsr	tmp2, tmp2, tmp1	/* Shift (tmp1 & 63).  */
-#endif
-	orr	data1, data1, tmp2
-	orr	data2, data2, tmp2
-	b	L(start_realigned)
-
-L(misaligned8):
-	/* Align SRC1 to 8 bytes and then compare 8 bytes at a time, always
-	   checking to make sure that we don't access beyond page boundary in
-	   SRC2.  */
-	tst	src1, #7
-	b.eq	L(loop_misaligned)
-L(do_misaligned):
-	ldrb	data1w, [src1], #1
-	ldrb	data2w, [src2], #1
-	cmp	data1w, #1
-	ccmp	data1w, data2w, #0, cs	/* NZCV = 0b0000.  */
-	b.ne	L(done)
-	tst	src1, #7
-	b.ne	L(do_misaligned)
-
-L(loop_misaligned):
-	/* Test if we are within the last dword of the end of a 4K page.  If
-	   yes then jump back to the misaligned loop to copy a byte at a time.  */
-	and	tmp1, src2, #0xff8
-	eor	tmp1, tmp1, #0xff8
-	cbz	tmp1, L(do_misaligned)
-	ldr	data1, [src1], #8
-	ldr	data2, [src2], #8
-
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, #REP8_7f
-	eor	diff, data1, data2	/* Non-zero if differences found.  */
-	bic	has_nul, tmp1, tmp2	/* Non-zero if NUL terminator.  */
-	orr	syndrome, diff, has_nul
-	cbz	syndrome, L(loop_misaligned)
-	b	L(end)
-
-L(done):
-	sub	result, data1, data2
-	ret
-END(strcmp_default)
diff --git a/libc/arch-arm64/default/bionic/strlen.S b/libc/arch-arm64/default/bionic/strlen.S
deleted file mode 100644
index 07c5294..0000000
--- a/libc/arch-arm64/default/bionic/strlen.S
+++ /dev/null
@@ -1,227 +0,0 @@
-/* Copyright (c) 2013-2015, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-	 notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-	 notice, this list of conditions and the following disclaimer in the
-	 documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-	 names of its contributors may be used to endorse or promote products
-	 derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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. */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses, min page size 4k.
- */
-
-#include <private/bionic_asm.h>
-
-/* To test the page crossing code path more thoroughly, compile with
-   -DTEST_PAGE_CROSS - this will force all calls through the slower
-   entry path.  This option is not intended for production use.	 */
-
-/* Arguments and results.  */
-#define srcin		x0
-#define len		x0
-
-/* Locals and temporaries.  */
-#define src		x1
-#define data1		x2
-#define data2		x3
-#define has_nul1	x4
-#define has_nul2	x5
-#define tmp1		x4
-#define tmp2		x5
-#define tmp3		x6
-#define tmp4		x7
-#define zeroones	x8
-
-#define L(l) .L ## l
-
-	/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
-	   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
-	   can be done in parallel across the entire word. A faster check
-	   (X - 1) & 0x80 is zero for non-NUL ASCII characters, but gives
-	   false hits for characters 129..255.	*/
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-#ifdef TEST_PAGE_CROSS
-# define MIN_PAGE_SIZE 15
-#else
-# define MIN_PAGE_SIZE 4096
-#endif
-
-	/* Since strings are short on average, we check the first 16 bytes
-	   of the string for a NUL character.  In order to do an unaligned ldp
-	   safely we have to do a page cross check first.  If there is a NUL
-	   byte we calculate the length from the 2 8-byte words using
-	   conditional select to reduce branch mispredictions (it is unlikely
-	   strlen will be repeatedly called on strings with the same length).
-
-	   If the string is longer than 16 bytes, we align src so don't need
-	   further page cross checks, and process 32 bytes per iteration
-	   using the fast NUL check.  If we encounter non-ASCII characters,
-	   fallback to a second loop using the full NUL check.
-
-	   If the page cross check fails, we read 16 bytes from an aligned
-	   address, remove any characters before the string, and continue
-	   in the main loop using aligned loads.  Since strings crossing a
-	   page in the first 16 bytes are rare (probability of
-	   16/MIN_PAGE_SIZE ~= 0.4%), this case does not need to be optimized.
-
-	   AArch64 systems have a minimum page size of 4k.  We don't bother
-	   checking for larger page sizes - the cost of setting up the correct
-	   page size is just not worth the extra gain from a small reduction in
-	   the cases taking the slow path.  Note that we only care about
-	   whether the first fetch, which may be misaligned, crosses a page
-	   boundary.  */
-
-ENTRY(strlen_default)
-	and	tmp1, srcin, MIN_PAGE_SIZE - 1
-	mov	zeroones, REP8_01
-	cmp	tmp1, MIN_PAGE_SIZE - 16
-	b.gt	L(page_cross)
-	ldp	data1, data2, [srcin]
-#ifdef __AARCH64EB__
-	/* For big-endian, carry propagation (if the final byte in the
-	   string is 0x01) means we cannot use has_nul1/2 directly.
-	   Since we expect strings to be small and early-exit,
-	   byte-swap the data now so has_null1/2 will be correct.  */
-	rev	data1, data1
-	rev	data2, data2
-#endif
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, REP8_7f
-	sub	tmp3, data2, zeroones
-	orr	tmp4, data2, REP8_7f
-	bics	has_nul1, tmp1, tmp2
-	bic	has_nul2, tmp3, tmp4
-	ccmp	has_nul2, 0, 0, eq
-	beq	L(main_loop_entry)
-
-	/* Enter with C = has_nul1 == 0.  */
-	csel	has_nul1, has_nul1, has_nul2, cc
-	mov	len, 8
-	rev	has_nul1, has_nul1
-	clz	tmp1, has_nul1
-	csel	len, xzr, len, cc
-	add	len, len, tmp1, lsr 3
-	ret
-
-	/* The inner loop processes 32 bytes per iteration and uses the fast
-	   NUL check.  If we encounter non-ASCII characters, use a second
-	   loop with the accurate NUL check.  */
-	.p2align 4
-L(main_loop_entry):
-	bic	src, srcin, 15
-	sub	src, src, 16
-L(main_loop):
-	ldp	data1, data2, [src, 32]!
-.Lpage_cross_entry:
-	sub	tmp1, data1, zeroones
-	sub	tmp3, data2, zeroones
-	orr	tmp2, tmp1, tmp3
-	tst	tmp2, zeroones, lsl 7
-	bne	1f
-	ldp	data1, data2, [src, 16]
-	sub	tmp1, data1, zeroones
-	sub	tmp3, data2, zeroones
-	orr	tmp2, tmp1, tmp3
-	tst	tmp2, zeroones, lsl 7
-	beq	L(main_loop)
-	add	src, src, 16
-1:
-	/* The fast check failed, so do the slower, accurate NUL check.	 */
-	orr	tmp2, data1, REP8_7f
-	orr	tmp4, data2, REP8_7f
-	bics	has_nul1, tmp1, tmp2
-	bic	has_nul2, tmp3, tmp4
-	ccmp	has_nul2, 0, 0, eq
-	beq	L(nonascii_loop)
-
-	/* Enter with C = has_nul1 == 0.  */
-L(tail):
-#ifdef __AARCH64EB__
-	/* For big-endian, carry propagation (if the final byte in the
-	   string is 0x01) means we cannot use has_nul1/2 directly.  The
-	   easiest way to get the correct byte is to byte-swap the data
-	   and calculate the syndrome a second time.  */
-	csel	data1, data1, data2, cc
-	rev	data1, data1
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, REP8_7f
-	bic	has_nul1, tmp1, tmp2
-#else
-	csel	has_nul1, has_nul1, has_nul2, cc
-#endif
-	sub	len, src, srcin
-	rev	has_nul1, has_nul1
-	add	tmp2, len, 8
-	clz	tmp1, has_nul1
-	csel	len, len, tmp2, cc
-	add	len, len, tmp1, lsr 3
-	ret
-
-L(nonascii_loop):
-	ldp	data1, data2, [src, 16]!
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, REP8_7f
-	sub	tmp3, data2, zeroones
-	orr	tmp4, data2, REP8_7f
-	bics	has_nul1, tmp1, tmp2
-	bic	has_nul2, tmp3, tmp4
-	ccmp	has_nul2, 0, 0, eq
-	bne	L(tail)
-	ldp	data1, data2, [src, 16]!
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, REP8_7f
-	sub	tmp3, data2, zeroones
-	orr	tmp4, data2, REP8_7f
-	bics	has_nul1, tmp1, tmp2
-	bic	has_nul2, tmp3, tmp4
-	ccmp	has_nul2, 0, 0, eq
-	beq	L(nonascii_loop)
-	b	L(tail)
-
-	/* Load 16 bytes from [srcin & ~15] and force the bytes that precede
-	   srcin to 0x7f, so we ignore any NUL bytes before the string.
-	   Then continue in the aligned loop.  */
-L(page_cross):
-	bic	src, srcin, 15
-	ldp	data1, data2, [src]
-	lsl	tmp1, srcin, 3
-	mov	tmp4, -1
-#ifdef __AARCH64EB__
-	/* Big-endian.	Early bytes are at MSB.	 */
-	lsr	tmp1, tmp4, tmp1	/* Shift (tmp1 & 63).  */
-#else
-	/* Little-endian.  Early bytes are at LSB.  */
-	lsl	tmp1, tmp4, tmp1	/* Shift (tmp1 & 63).  */
-#endif
-	orr	tmp1, tmp1, REP8_80
-	orn	data1, data1, tmp1
-	orn	tmp2, data2, tmp1
-	tst	srcin, 8
-	csel	data1, data1, tmp4, eq
-	csel	data2, data2, tmp2, eq
-	b	L(page_cross_entry)
-
-END(strlen_default)
diff --git a/libc/arch-arm64/default/bionic/strncmp.S b/libc/arch-arm64/default/bionic/strncmp.S
deleted file mode 100644
index 5432b73..0000000
--- a/libc/arch-arm64/default/bionic/strncmp.S
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Copyright (c) 2014, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
-#include <private/bionic_asm.h>
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-/* Parameters and result.  */
-#define src1		x0
-#define src2		x1
-#define limit		x2
-#define result		x0
-
-/* Internal variables.  */
-#define data1		x3
-#define data1w		w3
-#define data2		x4
-#define data2w		w4
-#define has_nul		x5
-#define diff		x6
-#define syndrome	x7
-#define tmp1		x8
-#define tmp2		x9
-#define tmp3		x10
-#define zeroones	x11
-#define pos		x12
-#define limit_wd	x13
-#define mask		x14
-#define endloop		x15
-#define count		mask
-
-	.text
-	.p2align 6
-	.rep 7
-	nop	/* Pad so that the loop below fits a cache line.  */
-	.endr
-ENTRY(strncmp_default)
-	cbz	limit, .Lret0
-	eor	tmp1, src1, src2
-	mov	zeroones, #REP8_01
-	tst	tmp1, #7
-	and	count, src1, #7
-	b.ne	.Lmisaligned8
-	cbnz	count, .Lmutual_align
-	/* Calculate the number of full and partial words -1.  */
-	sub	limit_wd, limit, #1	/* limit != 0, so no underflow.  */
-	lsr	limit_wd, limit_wd, #3	/* Convert to Dwords.  */
-
-	/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
-	   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
-	   can be done in parallel across the entire word.  */
-	/* Start of performance-critical section  -- one 64B cache line.  */
-.Lloop_aligned:
-	ldr	data1, [src1], #8
-	ldr	data2, [src2], #8
-.Lstart_realigned:
-	subs	limit_wd, limit_wd, #1
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, #REP8_7f
-	eor	diff, data1, data2	/* Non-zero if differences found.  */
-	csinv	endloop, diff, xzr, pl	/* Last Dword or differences.  */
-	bics	has_nul, tmp1, tmp2	/* Non-zero if NUL terminator.  */
-	ccmp	endloop, #0, #0, eq
-	b.eq	.Lloop_aligned
-	/* End of performance-critical section  -- one 64B cache line.  */
-
-	/* Not reached the limit, must have found the end or a diff.  */
-	tbz	limit_wd, #63, .Lnot_limit
-
-	/* Limit % 8 == 0 => all bytes significant.  */
-	ands	limit, limit, #7
-	b.eq	.Lnot_limit
-
-	lsl	limit, limit, #3	/* Bits -> bytes.  */
-	mov	mask, #~0
-#ifdef __AARCH64EB__
-	lsr	mask, mask, limit
-#else
-	lsl	mask, mask, limit
-#endif
-	bic	data1, data1, mask
-	bic	data2, data2, mask
-
-	/* Make sure that the NUL byte is marked in the syndrome.  */
-	orr	has_nul, has_nul, mask
-
-.Lnot_limit:
-	orr	syndrome, diff, has_nul
-
-#ifndef	__AARCH64EB__
-	rev	syndrome, syndrome
-	rev	data1, data1
-	/* The MS-non-zero bit of the syndrome marks either the first bit
-	   that is different, or the top bit of the first zero byte.
-	   Shifting left now will bring the critical information into the
-	   top bits.  */
-	clz	pos, syndrome
-	rev	data2, data2
-	lsl	data1, data1, pos
-	lsl	data2, data2, pos
-	/* But we need to zero-extend (char is unsigned) the value and then
-	   perform a signed 32-bit subtraction.  */
-	lsr	data1, data1, #56
-	sub	result, data1, data2, lsr #56
-	ret
-#else
-	/* For big-endian we cannot use the trick with the syndrome value
-	   as carry-propagation can corrupt the upper bits if the trailing
-	   bytes in the string contain 0x01.  */
-	/* However, if there is no NUL byte in the dword, we can generate
-	   the result directly.  We can't just subtract the bytes as the
-	   MSB might be significant.  */
-	cbnz	has_nul, 1f
-	cmp	data1, data2
-	cset	result, ne
-	cneg	result, result, lo
-	ret
-1:
-	/* Re-compute the NUL-byte detection, using a byte-reversed value.  */
-	rev	tmp3, data1
-	sub	tmp1, tmp3, zeroones
-	orr	tmp2, tmp3, #REP8_7f
-	bic	has_nul, tmp1, tmp2
-	rev	has_nul, has_nul
-	orr	syndrome, diff, has_nul
-	clz	pos, syndrome
-	/* The MS-non-zero bit of the syndrome marks either the first bit
-	   that is different, or the top bit of the first zero byte.
-	   Shifting left now will bring the critical information into the
-	   top bits.  */
-	lsl	data1, data1, pos
-	lsl	data2, data2, pos
-	/* But we need to zero-extend (char is unsigned) the value and then
-	   perform a signed 32-bit subtraction.  */
-	lsr	data1, data1, #56
-	sub	result, data1, data2, lsr #56
-	ret
-#endif
-
-.Lmutual_align:
-	/* Sources are mutually aligned, but are not currently at an
-	   alignment boundary.  Round down the addresses and then mask off
-	   the bytes that precede the start point.
-	   We also need to adjust the limit calculations, but without
-	   overflowing if the limit is near ULONG_MAX.  */
-	bic	src1, src1, #7
-	bic	src2, src2, #7
-	ldr	data1, [src1], #8
-	neg	tmp3, count, lsl #3	/* 64 - bits(bytes beyond align). */
-	ldr	data2, [src2], #8
-	mov	tmp2, #~0
-	sub	limit_wd, limit, #1	/* limit != 0, so no underflow.  */
-#ifdef __AARCH64EB__
-	/* Big-endian.  Early bytes are at MSB.  */
-	lsl	tmp2, tmp2, tmp3	/* Shift (count & 63).  */
-#else
-	/* Little-endian.  Early bytes are at LSB.  */
-	lsr	tmp2, tmp2, tmp3	/* Shift (count & 63).  */
-#endif
-	and	tmp3, limit_wd, #7
-	lsr	limit_wd, limit_wd, #3
-	/* Adjust the limit. Only low 3 bits used, so overflow irrelevant.  */
-	add	limit, limit, count
-	add	tmp3, tmp3, count
-	orr	data1, data1, tmp2
-	orr	data2, data2, tmp2
-	add	limit_wd, limit_wd, tmp3, lsr #3
-	b	.Lstart_realigned
-
-	.p2align 6
-	/* Don't bother with dwords for up to 16 bytes.  */
-.Lmisaligned8:
-	cmp	limit, #16
-	b.hs	.Ltry_misaligned_words
-
-.Lbyte_loop:
-	/* Perhaps we can do better than this.  */
-	ldrb	data1w, [src1], #1
-	ldrb	data2w, [src2], #1
-	subs	limit, limit, #1
-	ccmp	data1w, #1, #0, hi	/* NZCV = 0b0000.  */
-	ccmp	data1w, data2w, #0, cs	/* NZCV = 0b0000.  */
-	b.eq	.Lbyte_loop
-.Ldone:
-	sub	result, data1, data2
-	ret
-	/* Align the SRC1 to a dword by doing a bytewise compare and then do
-	   the dword loop.  */
-.Ltry_misaligned_words:
-	lsr	limit_wd, limit, #3
-	cbz	count, .Ldo_misaligned
-
-	neg	count, count
-	and	count, count, #7
-	sub	limit, limit, count
-	lsr	limit_wd, limit, #3
-
-.Lpage_end_loop:
-	ldrb	data1w, [src1], #1
-	ldrb	data2w, [src2], #1
-	cmp	data1w, #1
-	ccmp	data1w, data2w, #0, cs	/* NZCV = 0b0000.  */
-	b.ne	.Ldone
-	subs	count, count, #1
-	b.hi	.Lpage_end_loop
-
-.Ldo_misaligned:
-	/* Prepare ourselves for the next page crossing.  Unlike the aligned
-	   loop, we fetch 1 less dword because we risk crossing bounds on
-	   SRC2.  */
-	mov	count, #8
-	subs	limit_wd, limit_wd, #1
-	b.lo	.Ldone_loop
-.Lloop_misaligned:
-	and	tmp2, src2, #0xff8
-	eor	tmp2, tmp2, #0xff8
-	cbz	tmp2, .Lpage_end_loop
-
-	ldr	data1, [src1], #8
-	ldr	data2, [src2], #8
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, #REP8_7f
-	eor	diff, data1, data2	/* Non-zero if differences found.  */
-	bics	has_nul, tmp1, tmp2	/* Non-zero if NUL terminator.  */
-	ccmp	diff, #0, #0, eq
-	b.ne	.Lnot_limit
-	subs	limit_wd, limit_wd, #1
-	b.pl	.Lloop_misaligned
-
-.Ldone_loop:
-	/* We found a difference or a NULL before the limit was reached.  */
-	and	limit, limit, #7
-	cbz	limit, .Lnot_limit
-	/* Read the last word.  */
-	sub	src1, src1, 8
-	sub	src2, src2, 8
-	ldr	data1, [src1, limit]
-	ldr	data2, [src2, limit]
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, #REP8_7f
-	eor	diff, data1, data2	/* Non-zero if differences found.  */
-	bics	has_nul, tmp1, tmp2	/* Non-zero if NUL terminator.  */
-	ccmp	diff, #0, #0, eq
-	b.ne	.Lnot_limit
-
-.Lret0:
-	mov	result, #0
-	ret
-END(strncmp_default)
diff --git a/libc/arch-arm64/default/bionic/strnlen.S b/libc/arch-arm64/default/bionic/strnlen.S
deleted file mode 100644
index 1694532..0000000
--- a/libc/arch-arm64/default/bionic/strnlen.S
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Copyright (c) 2014, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
-#include <private/bionic_asm.h>
-
-/* Arguments and results.  */
-#define srcin		x0
-#define len		x0
-#define limit		x1
-
-/* Locals and temporaries.  */
-#define src		x2
-#define data1		x3
-#define data2		x4
-#define data2a		x5
-#define has_nul1	x6
-#define has_nul2	x7
-#define tmp1		x8
-#define tmp2		x9
-#define tmp3		x10
-#define tmp4		x11
-#define zeroones	x12
-#define pos		x13
-#define limit_wd	x14
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-	.text
-	.p2align	6
-.Lstart:
-	/* Pre-pad to ensure critical loop begins an icache line.  */
-	.rep 7
-	nop
-	.endr
-	/* Put this code here to avoid wasting more space with pre-padding.  */
-.Lhit_limit:
-	mov	len, limit
-	ret
-
-ENTRY(strnlen_default)
-	cbz	limit, .Lhit_limit
-	mov	zeroones, #REP8_01
-	bic	src, srcin, #15
-	ands	tmp1, srcin, #15
-	b.ne	.Lmisaligned
-	/* Calculate the number of full and partial words -1.  */
-	sub	limit_wd, limit, #1	/* Limit != 0, so no underflow.  */
-	lsr	limit_wd, limit_wd, #4	/* Convert to Qwords.  */
-
-	/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
-	   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
-	   can be done in parallel across the entire word.  */
-	/* The inner loop deals with two Dwords at a time.  This has a
-	   slightly higher start-up cost, but we should win quite quickly,
-	   especially on cores with a high number of issue slots per
-	   cycle, as we get much better parallelism out of the operations.  */
-
-	/* Start of critial section -- keep to one 64Byte cache line.  */
-.Lloop:
-	ldp	data1, data2, [src], #16
-.Lrealigned:
-	sub	tmp1, data1, zeroones
-	orr	tmp2, data1, #REP8_7f
-	sub	tmp3, data2, zeroones
-	orr	tmp4, data2, #REP8_7f
-	bic	has_nul1, tmp1, tmp2
-	bic	has_nul2, tmp3, tmp4
-	subs	limit_wd, limit_wd, #1
-	orr	tmp1, has_nul1, has_nul2
-	ccmp	tmp1, #0, #0, pl	/* NZCV = 0000  */
-	b.eq	.Lloop
-	/* End of critical section -- keep to one 64Byte cache line.  */
-
-	orr	tmp1, has_nul1, has_nul2
-	cbz	tmp1, .Lhit_limit	/* No null in final Qword.  */
-
-	/* We know there's a null in the final Qword.  The easiest thing
-	   to do now is work out the length of the string and return
-	   MIN (len, limit).  */
-
-	sub	len, src, srcin
-	cbz	has_nul1, .Lnul_in_data2
-#ifdef __AARCH64EB__
-	mov	data2, data1
-#endif
-	sub	len, len, #8
-	mov	has_nul2, has_nul1
-.Lnul_in_data2:
-#ifdef __AARCH64EB__
-	/* For big-endian, carry propagation (if the final byte in the
-	   string is 0x01) means we cannot use has_nul directly.  The
-	   easiest way to get the correct byte is to byte-swap the data
-	   and calculate the syndrome a second time.  */
-	rev	data2, data2
-	sub	tmp1, data2, zeroones
-	orr	tmp2, data2, #REP8_7f
-	bic	has_nul2, tmp1, tmp2
-#endif
-	sub	len, len, #8
-	rev	has_nul2, has_nul2
-	clz	pos, has_nul2
-	add	len, len, pos, lsr #3		/* Bits to bytes.  */
-	cmp	len, limit
-	csel	len, len, limit, ls		/* Return the lower value.  */
-	ret
-
-.Lmisaligned:
-	/* Deal with a partial first word.
-	   We're doing two things in parallel here;
-	   1) Calculate the number of words (but avoiding overflow if
-	      limit is near ULONG_MAX) - to do this we need to work out
-	      limit + tmp1 - 1 as a 65-bit value before shifting it;
-	   2) Load and mask the initial data words - we force the bytes
-	      before the ones we are interested in to 0xff - this ensures
-	      early bytes will not hit any zero detection.  */
-	sub	limit_wd, limit, #1
-	neg	tmp4, tmp1
-	cmp	tmp1, #8
-
-	and	tmp3, limit_wd, #15
-	lsr	limit_wd, limit_wd, #4
-	mov	tmp2, #~0
-
-	ldp	data1, data2, [src], #16
-	lsl	tmp4, tmp4, #3		/* Bytes beyond alignment -> bits.  */
-	add	tmp3, tmp3, tmp1
-
-#ifdef __AARCH64EB__
-	/* Big-endian.  Early bytes are at MSB.  */
-	lsl	tmp2, tmp2, tmp4	/* Shift (tmp1 & 63).  */
-#else
-	/* Little-endian.  Early bytes are at LSB.  */
-	lsr	tmp2, tmp2, tmp4	/* Shift (tmp1 & 63).  */
-#endif
-	add	limit_wd, limit_wd, tmp3, lsr #4
-
-	orr	data1, data1, tmp2
-	orr	data2a, data2, tmp2
-
-	csinv	data1, data1, xzr, le
-	csel	data2, data2, data2a, le
-	b	.Lrealigned
-END(strnlen_default)
diff --git a/libc/arch-arm64/dynamic_function_dispatch.cpp b/libc/arch-arm64/dynamic_function_dispatch.cpp
index 37abea4..0fd331f 100644
--- a/libc/arch-arm64/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm64/dynamic_function_dispatch.cpp
@@ -45,54 +45,81 @@
 typedef void* memchr_func(const void*, int, size_t);
 DEFINE_IFUNC_FOR(memchr) {
     if (supports_mte(arg->_hwcap2)) {
-        RETURN_FUNC(memchr_func, memchr_mte);
+        RETURN_FUNC(memchr_func, __memchr_aarch64_mte);
     } else {
-        RETURN_FUNC(memchr_func, memchr_default);
+        RETURN_FUNC(memchr_func, __memchr_aarch64);
+    }
+}
+
+typedef int stpcpy_func(char*, const char*);
+DEFINE_IFUNC_FOR(stpcpy) {
+    if (supports_mte(arg->_hwcap2)) {
+        RETURN_FUNC(stpcpy_func, __stpcpy_aarch64_mte);
+    } else {
+        RETURN_FUNC(stpcpy_func, __stpcpy_aarch64);
     }
 }
 
 typedef char* strchr_func(const char*, int);
 DEFINE_IFUNC_FOR(strchr) {
     if (supports_mte(arg->_hwcap2)) {
-        RETURN_FUNC(strchr_func, strchr_mte);
+        RETURN_FUNC(strchr_func, __strchr_aarch64_mte);
     } else {
-        RETURN_FUNC(strchr_func, strchr_default);
+        RETURN_FUNC(strchr_func, __strchr_aarch64);
+    }
+}
+
+typedef char* strchrnul_func(const char*, int);
+DEFINE_IFUNC_FOR(strchrnul) {
+    if (supports_mte(arg->_hwcap2)) {
+        RETURN_FUNC(strchrnul_func, __strchrnul_aarch64_mte);
+    } else {
+        RETURN_FUNC(strchrnul_func, __strchrnul_aarch64);
     }
 }
 
 typedef int strcmp_func(const char*, const char*);
 DEFINE_IFUNC_FOR(strcmp) {
     if (supports_mte(arg->_hwcap2)) {
-        RETURN_FUNC(strcmp_func, strcmp_mte);
+        RETURN_FUNC(strcmp_func, __strcmp_aarch64_mte);
     } else {
-        RETURN_FUNC(strcmp_func, strcmp_default);
+        RETURN_FUNC(strcmp_func, __strcmp_aarch64);
+    }
+}
+
+typedef int strcpy_func(char*, const char*);
+DEFINE_IFUNC_FOR(strcpy) {
+    if (supports_mte(arg->_hwcap2)) {
+        RETURN_FUNC(strcpy_func, __strcpy_aarch64_mte);
+    } else {
+        RETURN_FUNC(strcpy_func, __strcpy_aarch64);
     }
 }
 
 typedef size_t strlen_func(const char*);
 DEFINE_IFUNC_FOR(strlen) {
     if (supports_mte(arg->_hwcap2)) {
-        RETURN_FUNC(strlen_func, strlen_mte);
+        RETURN_FUNC(strlen_func, __strlen_aarch64_mte);
     } else {
-        RETURN_FUNC(strlen_func, strlen_default);
+        RETURN_FUNC(strlen_func, __strlen_aarch64);
     }
 }
 
 typedef int strncmp_func(const char*, const char*, int);
 DEFINE_IFUNC_FOR(strncmp) {
     if (supports_mte(arg->_hwcap2)) {
-        RETURN_FUNC(strncmp_func, strncmp_mte);
+        RETURN_FUNC(strncmp_func, __strncmp_aarch64_mte);
     } else {
-        RETURN_FUNC(strncmp_func, strncmp_default);
+        RETURN_FUNC(strncmp_func, __strncmp_aarch64);
     }
 }
 
-typedef size_t strnlen_func(const char*, int);
-DEFINE_IFUNC_FOR(strnlen) {
+typedef char* strrchr_func(const char*, int);
+DEFINE_IFUNC_FOR(strrchr) {
     if (supports_mte(arg->_hwcap2)) {
-        RETURN_FUNC(strnlen_func, strnlen_mte);
+        RETURN_FUNC(strrchr_func, __strrchr_aarch64_mte);
     } else {
-        RETURN_FUNC(strnlen_func, strnlen_default);
+        RETURN_FUNC(strrchr_func, __strrchr_aarch64);
     }
 }
 
diff --git a/libc/arch-arm64/generic/bionic/memcmp.S b/libc/arch-arm64/generic/bionic/memcmp.S
deleted file mode 100644
index bff54ae..0000000
--- a/libc/arch-arm64/generic/bionic/memcmp.S
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2017 ARM Ltd
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the company may not be used to endorse or promote
- *    products derived from this software without specific prior written
- *    permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
- */
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64, unaligned accesses.
- */
-
-#include <private/bionic_asm.h>
-
-#define L(l) .L ## l
-
-/* Parameters and result.  */
-#define src1		x0
-#define src2		x1
-#define limit		x2
-#define result		w0
-
-/* Internal variables.  */
-#define data1		x3
-#define data1w		w3
-#define data1h		x4
-#define data2		x5
-#define data2w		w5
-#define data2h		x6
-#define tmp1		x7
-#define tmp2		x8
-
-/* Small inputs of less than 8 bytes are handled separately.  This allows the
-   main code to be speed up using unaligned loads since there are now at least
-   8 bytes to be compared.  If the first 8 bytes are equal, align src1.
-   This ensures each iteration does at most one unaligned access even if both
-   src1 and src2 are unaligned, and mutually aligned inputs behave as if
-   aligned.  After the main loop, process the last 16 bytes using unaligned
-   accesses.  */
-
-ENTRY(memcmp)
-.p2align 6
-	subs	limit, limit, 8
-	b.lo	L(less8)
-
-	/* Limit >= 8, so check first 8 bytes using unaligned loads.  */
-	ldr	data1, [src1], 8
-	ldr	data2, [src2], 8
-	cmp	data1, data2
-	b.ne	L(return)
-
-	subs	limit, limit, 8
-	b.gt	L(more16)
-
-	ldr	data1, [src1, limit]
-	ldr	data2, [src2, limit]
-	b	L(return)
-
-L(more16):
-	ldr	data1, [src1], 8
-	ldr	data2, [src2], 8
-	cmp	data1, data2
-	bne	L(return)
-
-	/* Jump directly to comparing the last 16 bytes for 32 byte (or less)
-	   strings.  */
-	subs	limit, limit, 16
-	b.ls	L(last_bytes)
-
-	/* We overlap loads between 0-32 bytes at either side of SRC1 when we
-	   try to align, so limit it only to strings larger than 128 bytes.  */
-	cmp	limit, 96
-	b.ls	L(loop16)
-
-	/* Align src1 and adjust src2 with bytes not yet done.  */
-	and	tmp1, src1, 15
-	add	limit, limit, tmp1
-	sub	src1, src1, tmp1
-	sub	src2, src2, tmp1
-
-	/* Loop performing 16 bytes per iteration using aligned src1.
-	   Limit is pre-decremented by 16 and must be larger than zero.
-	   Exit if <= 16 bytes left to do or if the data is not equal.  */
-	.p2align 4
-L(loop16):
-	ldp	data1, data1h, [src1], 16
-	ldp	data2, data2h, [src2], 16
-	subs	limit, limit, 16
-	ccmp	data1, data2, 0, hi
-	ccmp	data1h, data2h, 0, eq
-	b.eq	L(loop16)
-
-	cmp	data1, data2
-	bne	L(return)
-	mov	data1, data1h
-	mov	data2, data2h
-	cmp	data1, data2
-	bne	L(return)
-
-	/* Compare last 1-16 bytes using unaligned access.  */
-L(last_bytes):
-	add	src1, src1, limit
-	add	src2, src2, limit
-	ldp	data1, data1h, [src1]
-	ldp	data2, data2h, [src2]
-	cmp     data1, data2
-	bne	L(return)
-	mov	data1, data1h
-	mov	data2, data2h
-	cmp	data1, data2
-
-	/* Compare data bytes and set return value to 0, -1 or 1.  */
-L(return):
-#ifndef __AARCH64EB__
-	rev	data1, data1
-	rev	data2, data2
-#endif
-	cmp     data1, data2
-L(ret_eq):
-	cset	result, ne
-	cneg	result, result, lo
-	ret
-
-	.p2align 4
-	/* Compare up to 8 bytes.  Limit is [-8..-1].  */
-L(less8):
-	adds	limit, limit, 4
-	b.lo	L(less4)
-	ldr	data1w, [src1], 4
-	ldr	data2w, [src2], 4
-	cmp	data1w, data2w
-	b.ne	L(return)
-	sub	limit, limit, 4
-L(less4):
-	adds	limit, limit, 4
-	beq	L(ret_eq)
-L(byte_loop):
-	ldrb	data1w, [src1], 1
-	ldrb	data2w, [src2], 1
-	subs	limit, limit, 1
-	ccmp	data1w, data2w, 0, ne	/* NZCV = 0b0000.  */
-	b.eq	L(byte_loop)
-	sub	result, data1w, data2w
-	ret
-
-END(memcmp)
diff --git a/libc/arch-arm64/generic/bionic/stpcpy.S b/libc/arch-arm64/generic/bionic/stpcpy.S
deleted file mode 100644
index e4a7993..0000000
--- a/libc/arch-arm64/generic/bionic/stpcpy.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2014 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 STPCPY
-#include "string_copy.S"
diff --git a/libc/arch-arm64/generic/bionic/strcpy.S b/libc/arch-arm64/generic/bionic/strcpy.S
deleted file mode 100644
index 260c321..0000000
--- a/libc/arch-arm64/generic/bionic/strcpy.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2014 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 STRCPY
-#include "string_copy.S"
diff --git a/libc/arch-arm64/generic/bionic/string_copy.S b/libc/arch-arm64/generic/bionic/string_copy.S
deleted file mode 100644
index 2bf969d..0000000
--- a/libc/arch-arm64/generic/bionic/string_copy.S
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2014 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) 2014, Linaro Limited
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the Linaro nor the
-         names of its contributors may be used to endorse or promote products
-         derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-   HOLDER 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.
-*/
-
-/* Assumptions:
- *
- * ARMv8-a, AArch64
- */
-
-#if !defined(STPCPY) && !defined(STRCPY)
-#error "Either STPCPY or STRCPY must be defined."
-#endif
-
-#include <private/bionic_asm.h>
-
-/* Arguments and results.  */
-#if defined(STPCPY)
-#define dst         x0
-#elif defined(STRCPY)
-#define dstin       x0
-#endif
-#define src         x1
-
-/* Locals and temporaries.  */
-#if defined(STRCPY)
-#define dst         x2
-#endif
-#define data1       x3
-#define data1_w     w3
-#define data2       x4
-#define data2_w     w4
-#define has_nul1    x5
-#define has_nul1_w  w5
-#define has_nul2    x6
-#define tmp1        x7
-#define tmp2        x8
-#define tmp3        x9
-#define tmp4        x10
-#define zeroones    x11
-#define zeroones_w  w11
-#define pos         x12
-
-#define REP8_01 0x0101010101010101
-#define REP8_7f 0x7f7f7f7f7f7f7f7f
-#define REP8_80 0x8080808080808080
-
-#if defined(STPCPY)
-ENTRY(stpcpy)
-#elif defined(STRCPY)
-ENTRY(strcpy)
-#endif
-    mov     zeroones, #REP8_01
-#if defined(STRCPY)
-    mov     dst, dstin
-#endif
-    ands    tmp1, src, #15
-    b.ne    .Lmisaligned
-    // NUL detection works on the principle that (X - 1) & (~X) & 0x80
-    // (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
-    // can be done in parallel across the entire word.
-    // The inner loop deals with two Dwords at a time.  This has a
-    // slightly higher start-up cost, but we should win quite quickly,
-    // especially on cores with a high number of issue slots per
-    // cycle, as we get much better parallelism out of the operations.
-.Lloop:
-    ldp     data1, data2, [src], #16
-    sub     tmp1, data1, zeroones
-    orr     tmp2, data1, #REP8_7f
-    bic     has_nul1, tmp1, tmp2
-    cbnz    has_nul1, .Lnul_in_data1
-    sub     tmp3, data2, zeroones
-    orr     tmp4, data2, #REP8_7f
-    bic     has_nul2, tmp3, tmp4
-    cbnz    has_nul2, .Lnul_in_data2
-    // No NUL in either register, copy it in a single instruction.
-    stp     data1, data2, [dst], #16
-    b       .Lloop
-
-.Lnul_in_data1:
-    rev     has_nul1, has_nul1
-    clz     pos, has_nul1
-    add     tmp1, pos, #0x8
-
-    tbz     tmp1, #6, 1f
-#if defined(STPCPY)
-    str     data1, [dst], #7
-#elif defined(STRCPY)
-    str     data1, [dst]
-#endif
-    ret
-1:
-    tbz     tmp1, #5, 1f
-    str     data1_w, [dst], #4
-    lsr     data1, data1, #32
-1:
-    tbz     tmp1, #4, 1f
-    strh    data1_w, [dst], #2
-    lsr     data1, data1, #16
-1:
-    tbz     tmp1, #3, 1f
-    strb    data1_w, [dst]
-#if defined(STPCPY)
-    ret
-#endif
-1:
-#if defined(STPCPY)
-    // Back up one so that dst points to the '\0' string terminator.
-    sub     dst, dst, #1
-#endif
-    ret
-
-.Lnul_in_data2:
-    str     data1, [dst], #8
-    rev     has_nul2, has_nul2
-    clz     pos, has_nul2
-    add     tmp1, pos, #0x8
-
-    tbz     tmp1, #6, 1f
-#if defined(STPCPY)
-    str     data2, [dst], #7
-#elif defined(STRCPY)
-    str     data2, [dst]
-#endif
-    ret
-1:
-    tbz     tmp1, #5, 1f
-    str     data2_w, [dst], #4
-    lsr     data2, data2, #32
-1:
-    tbz     tmp1, #4, 1f
-    strh    data2_w, [dst], #2
-    lsr     data2, data2, #16
-1:
-    tbz     tmp1, #3, 1f
-    strb    data2_w, [dst]
-#if defined(STPCPY)
-    ret
-#endif
-1:
-#if defined(STPCPY)
-    // Back up one so that dst points to the '\0' string terminator.
-    sub     dst, dst, #1
-#endif
-    ret
-
-.Lmisaligned:
-    tbz     src, #0, 1f
-    ldrb    data1_w, [src], #1
-    strb    data1_w, [dst], #1
-    cbnz    data1_w, 1f
-#if defined(STPCPY)
-    // Back up one so that dst points to the '\0' string terminator.
-    sub     dst, dst, #1
-#endif
-    ret
-1:
-    tbz     src, #1, 1f
-    ldrb    data1_w, [src], #1
-    strb    data1_w, [dst], #1
-    cbz     data1_w, .Ldone
-    ldrb    data2_w, [src], #1
-    strb    data2_w, [dst], #1
-    cbnz    data2_w, 1f
-.Ldone:
-#if defined(STPCPY)
-    // Back up one so that dst points to the '\0' string terminator.
-    sub     dst, dst, #1
-#endif
-    ret
-1:
-    tbz     src, #2, 1f
-    ldr     data1_w, [src], #4
-    // Check for a zero.
-    sub     has_nul1_w, data1_w, zeroones_w
-    bic     has_nul1_w, has_nul1_w, data1_w
-    ands    has_nul1_w, has_nul1_w, #0x80808080
-    b.ne    .Lnul_in_data1
-    str     data1_w, [dst], #4
-1:
-    tbz     src, #3, .Lloop
-    ldr     data1, [src], #8
-    // Check for a zero.
-    sub     tmp1, data1, zeroones
-    orr     tmp2, data1, #REP8_7f
-    bics    has_nul1, tmp1, tmp2
-    b.ne    .Lnul_in_data1
-    str     data1, [dst], #8
-    b       .Lloop
-#if defined(STPCPY)
-END(stpcpy)
-#elif defined(STRCPY)
-END(strcpy)
-#endif
diff --git a/libc/arch-arm64/mte/bionic/memchr.c b/libc/arch-arm64/mte/bionic/memchr.c
deleted file mode 100644
index 33b2fc2..0000000
--- a/libc/arch-arm64/mte/bionic/memchr.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define memchr memchr_mte
-#include <upstream-openbsd/lib/libc/string/memchr.c>
diff --git a/libc/arch-arm64/mte/bionic/strchr.cpp b/libc/arch-arm64/mte/bionic/strchr.cpp
deleted file mode 100644
index 7d394df..0000000
--- a/libc/arch-arm64/mte/bionic/strchr.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 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 strchr strchr_mte
-#include <bionic/strchr.cpp>
diff --git a/libc/arch-arm64/mte/bionic/strcmp.c b/libc/arch-arm64/mte/bionic/strcmp.c
deleted file mode 100644
index 0e134f0..0000000
--- a/libc/arch-arm64/mte/bionic/strcmp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strcmp strcmp_mte
-#include <upstream-openbsd/lib/libc/string/strcmp.c>
diff --git a/libc/arch-arm64/mte/bionic/strncmp.c b/libc/arch-arm64/mte/bionic/strncmp.c
deleted file mode 100644
index 54d08e9..0000000
--- a/libc/arch-arm64/mte/bionic/strncmp.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <upstream-openbsd/android/include/openbsd-compat.h>
-
-#define strncmp strncmp_mte
-#include <upstream-openbsd/lib/libc/string/strncmp.c>
diff --git a/libc/arch-arm64/mte/bionic/strnlen.c b/libc/arch-arm64/mte/bionic/strnlen.c
deleted file mode 100644
index 3dc251d..0000000
--- a/libc/arch-arm64/mte/bionic/strnlen.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 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 strnlen strnlen_mte
-#include <bionic/strnlen.c>
diff --git a/libc/arch-arm64/static_function_dispatch.S b/libc/arch-arm64/static_function_dispatch.S
index 8e3a4c1..65a1492 100644
--- a/libc/arch-arm64/static_function_dispatch.S
+++ b/libc/arch-arm64/static_function_dispatch.S
@@ -33,9 +33,12 @@
     b impl; \
 END(name)
 
-FUNCTION_DELEGATE(memchr, memchr_mte)
-FUNCTION_DELEGATE(strchr, strchr_mte)
-FUNCTION_DELEGATE(strcmp, strcmp_mte)
-FUNCTION_DELEGATE(strlen, strlen_mte)
-FUNCTION_DELEGATE(strncmp, strncmp_mte)
-FUNCTION_DELEGATE(strnlen, strnlen_mte)
+FUNCTION_DELEGATE(memchr, __memchr_aarch64_mte)
+FUNCTION_DELEGATE(stpcpy, __stpcpy_aarch64_mte)
+FUNCTION_DELEGATE(strchr, __strchr_aarch64_mte)
+FUNCTION_DELEGATE(strchrnul, __strchrnul_aarch64_mte)
+FUNCTION_DELEGATE(strcmp, __strcmp_aarch64_mte)
+FUNCTION_DELEGATE(strcpy, __strcpy_aarch64_mte)
+FUNCTION_DELEGATE(strlen, __strlen_aarch64_mte)
+FUNCTION_DELEGATE(strrchr, __strrchr_aarch64_mte)
+FUNCTION_DELEGATE(strncmp, __strncmp_aarch64_mte)
diff --git a/libc/arch-x86/atom/string/sse2-memset-atom.S b/libc/arch-x86/atom/string/sse2-memset-atom.S
index 016c49e..e4cd038 100644
--- a/libc/arch-x86/atom/string/sse2-memset-atom.S
+++ b/libc/arch-x86/atom/string/sse2-memset-atom.S
@@ -77,15 +77,6 @@
     /* We loaded the jump table and adjusted EDX. Go.  */	\
     jmp		*%ebx
 
-	.section	.gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits
-	.globl	__x86.get_pc_thunk.bx
-	.hidden	__x86.get_pc_thunk.bx
-	ALIGN(4)
-	.type	__x86.get_pc_thunk.bx,@function
-__x86.get_pc_thunk.bx:
-	movl	(%esp), %ebx
-	ret
-
 ENTRY(__memset_chk_atom)
   ENTRANCE
 
diff --git a/libc/arch-x86/bionic/__libc_init_sysinfo.cpp b/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
index 5c44b4e..db931d1 100644
--- a/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
+++ b/libc/arch-x86/bionic/__libc_init_sysinfo.cpp
@@ -37,8 +37,8 @@
 }
 
 __LIBC_HIDDEN__ void __libc_init_sysinfo() {
-  bool dummy;
-  __libc_sysinfo = reinterpret_cast<void*>(__bionic_getauxval(AT_SYSINFO, dummy));
+  bool unused;
+  __libc_sysinfo = reinterpret_cast<void*>(__bionic_getauxval(AT_SYSINFO, &unused));
 }
 
 // TODO: lose this function and just access __libc_sysinfo directly.
diff --git a/libc/arch-x86/bionic/__x86.get_pc_thunk.S b/libc/arch-x86/bionic/__x86.get_pc_thunk.S
new file mode 100644
index 0000000..58dbb08
--- /dev/null
+++ b/libc/arch-x86/bionic/__x86.get_pc_thunk.S
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// Typically GCC outputs functions like these into any object file that needs a PIC base register,
+// and one of the copies for each register is used. Clang doesn't use these functions, but some of
+// the quasi-hand-written assembly in the optimized string routines does.
+
+    .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+    .globl __x86.get_pc_thunk.bx
+    .hidden __x86.get_pc_thunk.bx
+    .p2align 4
+    .type __x86.get_pc_thunk.bx,@function
+__x86.get_pc_thunk.bx:
+    .cfi_startproc
+    movl (%esp), %ebx
+    ret
+    .cfi_endproc
+
+    .section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
+    .globl __x86.get_pc_thunk.cx
+    .hidden __x86.get_pc_thunk.cx
+    .p2align 4
+    .type __x86.get_pc_thunk.cx,@function
+__x86.get_pc_thunk.cx:
+    .cfi_startproc
+    movl (%esp), %ecx
+    ret
+    .cfi_endproc
diff --git a/libc/arch-x86/silvermont/string/sse2-memset-slm.S b/libc/arch-x86/silvermont/string/sse2-memset-slm.S
index adaccae..b7633f5 100644
--- a/libc/arch-x86/silvermont/string/sse2-memset-slm.S
+++ b/libc/arch-x86/silvermont/string/sse2-memset-slm.S
@@ -77,15 +77,6 @@
     /* We loaded the jump table and adjusted EDX. Go.  */	\
     jmp		*%ebx
 
-	.section	.gnu.linkonce.t.__x86.get_pc_thunk.bx,"ax",@progbits
-	.globl	__x86.get_pc_thunk.bx
-	.hidden	__x86.get_pc_thunk.bx
-	ALIGN(4)
-	.type	__x86.get_pc_thunk.bx,@function
-__x86.get_pc_thunk.bx:
-	movl	(%esp), %ebx
-	ret
-
 ENTRY(__memset_chk_generic)
   ENTRANCE
 
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 207035a..8b2a32b 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -30,6 +30,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/net.h>
 #include <pthread.h>
 #include <stdarg.h>
 #include <stddef.h>
@@ -51,12 +52,22 @@
 #include "private/ErrnoRestorer.h"
 #include "private/ScopedPthreadMutexLocker.h"
 
-// Don't call libc's close, since it might call back into us as a result of fdsan.
+// Don't call libc's close or socket, since it might call back into us as a result of fdsan/fdtrack.
 #pragma GCC poison close
 static int __close(int fd) {
   return syscall(__NR_close, fd);
 }
 
+static int __socket(int domain, int type, int protocol) {
+#if defined(__i386__)
+  unsigned long args[3] = {static_cast<unsigned long>(domain), static_cast<unsigned long>(type),
+                           static_cast<unsigned long>(protocol)};
+  return syscall(__NR_socketcall, SYS_SOCKET, &args);
+#else
+  return syscall(__NR_socket, domain, type, protocol);
+#endif
+}
+
 // Must be kept in sync with frameworks/base/core/java/android/util/EventLog.java.
 enum AndroidEventLogType {
   EVENT_TYPE_INT = 0,
@@ -460,7 +471,7 @@
   // found that all logd crashes thus far have had no problem stuffing
   // the UNIX domain socket and moving on so not critical *today*.
 
-  int log_fd = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
+  int log_fd = TEMP_FAILURE_RETRY(__socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
   if (log_fd == -1) {
     return -1;
   }
diff --git a/libc/async_safe/include/async_safe/CHECK.h b/libc/async_safe/include/async_safe/CHECK.h
index bec89a3..46d460c 100644
--- a/libc/async_safe/include/async_safe/CHECK.h
+++ b/libc/async_safe/include/async_safe/CHECK.h
@@ -36,12 +36,12 @@
 
 // TODO: replace this with something more like <android-base/logging.h>'s family of macros.
 
-#define CHECK(predicate) \
-  do { \
-    if (!(predicate)) { \
-      async_safe_fatal("%s:%d: %s CHECK '" #predicate "' failed", \
-          __FILE__, __LINE__, __FUNCTION__); \
-    } \
-  } while(0)
+#define CHECK(predicate)                                                                \
+  do {                                                                                  \
+    if (!(predicate)) {                                                                 \
+      async_safe_fatal("%s:%d: %s CHECK '%s' failed", __FILE__, __LINE__, __FUNCTION__, \
+                       #predicate);                                                     \
+    }                                                                                   \
+  } while (0)
 
 __END_DECLS
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 56a8488..95f46e9 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -101,6 +101,19 @@
   __set_tcb_dtv(tcb, const_cast<TlsDtv*>(&zero_dtv));
 }
 
+// This is public so that the zygote can call it too. It is not expected
+// to be useful otherwise.
+//
+// Note in particular that it is not possible to return from any existing
+// stack frame with stack protector enabled after this function is called.
+extern "C" void android_reset_stack_guards() {
+  // The TLS stack guard is set from the global, so ensure that we've initialized the global
+  // before we initialize the TLS. Dynamic executables will initialize their copy of the global
+  // stack protector from the one in the main thread's TLS.
+  __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard));
+  __init_tcb_stack_guard(__get_bionic_tcb());
+}
+
 // Finish initializing the main thread.
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
 extern "C" void __libc_init_main_thread_late() {
@@ -119,11 +132,7 @@
   // User code should never see this; we'll compute it when asked.
   pthread_attr_setstacksize(&main_thread.attr, 0);
 
-  // The TLS stack guard is set from the global, so ensure that we've initialized the global
-  // before we initialize the TLS. Dynamic executables will initialize their copy of the global
-  // stack protector from the one in the main thread's TLS.
-  __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard));
-  __init_tcb_stack_guard(__get_bionic_tcb());
+  android_reset_stack_guards();
 
   __init_thread(&main_thread);
 
diff --git a/libc/bionic/android_unsafe_frame_pointer_chase.cpp b/libc/bionic/android_unsafe_frame_pointer_chase.cpp
index e25867b..b3b1942 100644
--- a/libc/bionic/android_unsafe_frame_pointer_chase.cpp
+++ b/libc/bionic/android_unsafe_frame_pointer_chase.cpp
@@ -28,8 +28,14 @@
 
 #include "platform/bionic/android_unsafe_frame_pointer_chase.h"
 
-#include "pthread_internal.h"
 #include "platform/bionic/mte.h"
+#include "private/bionic_defs.h"
+#include "pthread_internal.h"
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+extern "C" __LIBC_HIDDEN__ uintptr_t __get_thread_stack_top() {
+  return __get_thread()->stack_top;
+}
 
 /*
  * Implement fast stack unwinding for stack frames with frame pointers. Stores at most num_entries
@@ -56,7 +62,7 @@
   };
 
   auto begin = reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
-  uintptr_t end = __get_thread()->stack_top;
+  auto end = __get_thread_stack_top();
 
   stack_t ss;
   if (sigaltstack(nullptr, &ss) == 0 && (ss.ss_flags & SS_ONSTACK)) {
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index b6d6ba7..98183d4 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -394,6 +394,26 @@
   }
 }
 
+size_t BionicAllocator::get_chunk_size(void* ptr) {
+  if (ptr == nullptr) return 0;
+
+  page_info* info = get_page_info_unchecked(ptr);
+  if (memcmp(info->signature, kSignature, sizeof(kSignature)) != 0) {
+    // Invalid pointer (mismatched signature)
+    return 0;
+  }
+  if (info->type == kLargeObject) {
+    return info->allocated_size - (static_cast<char*>(ptr) - reinterpret_cast<char*>(info));
+  }
+
+  BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
+  if (allocator != info->allocator_addr) {
+    // Invalid pointer.
+    return 0;
+  }
+  return allocator->get_block_size();
+}
+
 BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator(uint32_t type) {
   if (type < kSmallObjectMinSizeLog2 || type > kSmallObjectMaxSizeLog2) {
     async_safe_fatal("invalid type: %u", type);
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index 61d826c..d5fb05a 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -28,6 +28,7 @@
 
 #include "private/bionic_elf_tls.h"
 
+#include <async_safe/CHECK.h>
 #include <async_safe/log.h>
 #include <string.h>
 #include <sys/param.h>
@@ -269,6 +270,12 @@
         continue;
       }
     }
+    if (modules.on_destruction_cb != nullptr) {
+      void* dtls_begin = dtv->modules[i];
+      void* dtls_end =
+          static_cast<void*>(static_cast<char*>(dtls_begin) + allocator.get_chunk_size(dtls_begin));
+      modules.on_destruction_cb(dtls_begin, dtls_end);
+    }
     allocator.free(dtv->modules[i]);
     dtv->modules[i] = nullptr;
   }
@@ -297,6 +304,12 @@
       memcpy(mod_ptr, segment.init_ptr, segment.init_size);
     }
     dtv->modules[module_idx] = mod_ptr;
+
+    // Reports the allocation to the listener, if any.
+    if (modules.on_creation_cb != nullptr) {
+      modules.on_creation_cb(mod_ptr,
+                             static_cast<void*>(static_cast<char*>(mod_ptr) + segment.size));
+    }
   }
 
   return static_cast<char*>(mod_ptr) + ti->offset;
@@ -351,6 +364,14 @@
       // This module's TLS memory is allocated statically, so don't free it here.
       continue;
     }
+
+    if (modules.on_destruction_cb != nullptr) {
+      void* dtls_begin = dtv->modules[i];
+      void* dtls_end =
+          static_cast<void*>(static_cast<char*>(dtls_begin) + allocator.get_chunk_size(dtls_begin));
+      modules.on_destruction_cb(dtls_begin, dtls_end);
+    }
+
     allocator.free(dtv->modules[i]);
   }
 
@@ -364,3 +385,22 @@
   // Clear the DTV slot. The DTV must not be used again with this thread.
   tcb->tls_slot(TLS_SLOT_DTV) = nullptr;
 }
+
+// Invokes all the registered thread_exit callbacks, if any.
+void __notify_thread_exit_callbacks() {
+  TlsModules& modules = __libc_shared_globals()->tls_modules;
+  if (modules.first_thread_exit_callback == nullptr) {
+    // If there is no first_thread_exit_callback, there shouldn't be a tail.
+    CHECK(modules.thread_exit_callback_tail_node == nullptr);
+    return;
+  }
+
+  // Callbacks are supposed to be invoked in the reverse order
+  // in which they were registered.
+  CallbackHolder* node = modules.thread_exit_callback_tail_node;
+  while (node != nullptr) {
+    node->cb();
+    node = node->prev;
+  }
+  modules.first_thread_exit_callback();
+}
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index fd97712..0de51c5 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -14,52 +14,50 @@
  * limitations under the License.
  */
 
+#include "private/bionic_systrace.h"
+
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "private/bionic_lock.h"
-#include "private/bionic_systrace.h"
-#include "private/CachedProperty.h"
-
 #include <async_safe/log.h>
 #include <cutils/trace.h> // For ATRACE_TAG_BIONIC.
 
+#include "private/CachedProperty.h"
+#include "private/bionic_lock.h"
+
 #define WRITE_OFFSET   32
 
 static Lock g_lock;
-static CachedProperty g_debug_atrace_tags_enableflags("debug.atrace.tags.enableflags");
-static uint64_t g_tags;
-static int g_trace_marker_fd = -1;
 
-static bool should_trace() {
+bool should_trace(const uint64_t enable_tags) {
+  static uint64_t tags_val;
+  static CachedProperty tags_prop(kTraceTagsProp);
   g_lock.lock();
-  if (g_debug_atrace_tags_enableflags.DidChange()) {
-    g_tags = strtoull(g_debug_atrace_tags_enableflags.Get(), nullptr, 0);
+  if (tags_prop.DidChange()) {
+    tags_val = strtoull(tags_prop.Get(), nullptr, 0);
   }
   g_lock.unlock();
-  return ((g_tags & ATRACE_TAG_BIONIC) != 0);
+  return tags_val & enable_tags;
 }
 
-static int get_trace_marker_fd() {
+int get_trace_marker_fd() {
+  static int opened_trace_marker_fd = -1;
   g_lock.lock();
-  if (g_trace_marker_fd == -1) {
-    g_trace_marker_fd = open("/sys/kernel/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
-    if (g_trace_marker_fd == -1) {
-      g_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
+  if (opened_trace_marker_fd == -1) {
+    opened_trace_marker_fd = open("/sys/kernel/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
+    if (opened_trace_marker_fd == -1) {
+      opened_trace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_CLOEXEC | O_WRONLY);
     }
   }
   g_lock.unlock();
-  return g_trace_marker_fd;
+  return opened_trace_marker_fd;
 }
 
-void bionic_trace_begin(const char* message) {
-  if (!should_trace()) {
-    return;
-  }
-
+// event could be 'B' for begin or 'E' for end.
+void output_trace(const char* message, const char event) {
   int trace_marker_fd = get_trace_marker_fd();
   if (trace_marker_fd == -1) {
     return;
@@ -69,13 +67,22 @@
   // kernel trace_marker.
   int length = strlen(message);
   char buf[length + WRITE_OFFSET];
-  size_t len = async_safe_format_buffer(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message);
+  size_t len =
+      async_safe_format_buffer(buf, length + WRITE_OFFSET, "%c|%d|%s", event, getpid(), message);
 
   // Tracing may stop just after checking property and before writing the message.
   // So the write is acceptable to fail. See b/20666100.
   TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len));
 }
 
+void bionic_trace_begin(const char* message) {
+  if (!should_trace()) {
+    return;
+  }
+
+  output_trace(message);
+}
+
 void bionic_trace_end() {
   if (!should_trace()) {
     return;
diff --git a/libc/bionic/clock.cpp b/libc/bionic/clock.cpp
index fda0708..31e6c3c 100644
--- a/libc/bionic/clock.cpp
+++ b/libc/bionic/clock.cpp
@@ -35,8 +35,6 @@
 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html
 clock_t clock() {
   timespec ts;
-  if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) {
-    return -1;
-  }
+  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
   return (ts.tv_sec * CLOCKS_PER_SEC) + (ts.tv_nsec / (NS_PER_S / CLOCKS_PER_SEC));
 }
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 3309585..fd2c401 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -44,9 +44,10 @@
 
 extern "C" char** environ;
 
-enum ExecVariant { kIsExecL, kIsExecLE, kIsExecLP };
+enum { ExecL, ExecLE, ExecLP };
 
-static int __execl(const char* name, const char* argv0, ExecVariant variant, va_list ap) {
+template <int variant>
+static int __execl(const char* name, const char* argv0, va_list ap) {
   // Count the arguments.
   va_list count_ap;
   va_copy(count_ap, ap);
@@ -65,17 +66,17 @@
   }
 
   // Collect the argp too.
-  char** argp = (variant == kIsExecLE) ? va_arg(ap, char**) : environ;
+  char** argp = (variant == ExecLE) ? va_arg(ap, char**) : environ;
 
   va_end(ap);
 
-  return (variant == kIsExecLP) ? execvp(name, argv) : execve(name, argv, argp);
+  return (variant == ExecLP) ? execvp(name, argv) : execve(name, argv, argp);
 }
 
 int execl(const char* name, const char* arg, ...) {
   va_list ap;
   va_start(ap, arg);
-  int result = __execl(name, arg, kIsExecL, ap);
+  int result = __execl<ExecL>(name, arg, ap);
   va_end(ap);
   return result;
 }
@@ -83,7 +84,7 @@
 int execle(const char* name, const char* arg, ...) {
   va_list ap;
   va_start(ap, arg);
-  int result = __execl(name, arg, kIsExecLE, ap);
+  int result = __execl<ExecLE>(name, arg, ap);
   va_end(ap);
   return result;
 }
@@ -91,7 +92,7 @@
 int execlp(const char* name, const char* arg, ...) {
   va_list ap;
   va_start(ap, arg);
-  int result = __execl(name, arg, kIsExecLP, ap);
+  int result = __execl<ExecLP>(name, arg, ap);
   va_end(ap);
   return result;
 }
diff --git a/libc/arch-arm64/mte/bionic/strlen.c b/libc/bionic/exit.cpp
similarity index 78%
copy from libc/arch-arm64/mte/bionic/strlen.c
copy to libc/bionic/exit.cpp
index de88320..a5aed78 100644
--- a/libc/arch-arm64/mte/bionic/strlen.c
+++ b/libc/bionic/exit.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,17 @@
  * SUCH DAMAGE.
  */
 
-#include <upstream-openbsd/android/include/openbsd-compat.h>
+#include <stdlib.h>
+#include <unistd.h>
 
-#define strlen strlen_mte
-#include <upstream-openbsd/lib/libc/string/strlen.c>
+#include "private/bionic_defs.h"
+
+extern "C" void __cxa_finalize(void* dso_handle);
+extern "C" void __cxa_thread_finalize();
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+void exit(int status) {
+  __cxa_thread_finalize();
+  __cxa_finalize(nullptr);
+  _exit(status);
+}
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 4b89918..043510c 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -137,7 +137,7 @@
     return;
   }
 
-  // Lots of code will (sensibly) fork, blindly call close on all of their fds,
+  // Lots of code will (sensibly) fork, call close on all of their fds,
   // and then exec. Compare our cached pid value against the real one to detect
   // this scenario and permit it.
   pid_t cached_pid = __get_cached_pid();
diff --git a/libc/bionic/ffs.cpp b/libc/bionic/ffs.cpp
index b2270e5..aa7e504 100644
--- a/libc/bionic/ffs.cpp
+++ b/libc/bionic/ffs.cpp
@@ -26,8 +26,5 @@
  * SUCH DAMAGE.
  */
 
+#define __BIONIC_STRINGS_INLINE /* Out of line. */
 #include <strings.h>
-
-int ffs(int x) {
-  return __builtin_ffs(x);
-}
diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp
index 3814ed0..5bc7d3f 100644
--- a/libc/bionic/fork.cpp
+++ b/libc/bionic/fork.cpp
@@ -34,7 +34,7 @@
 #include "pthread_internal.h"
 
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __clone_for_fork() {
+extern "C" __LIBC_HIDDEN__ int __clone_for_fork() {
   pthread_internal_t* self = __get_thread();
 
   int result = clone(nullptr, nullptr, (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD),
@@ -56,7 +56,7 @@
 
   if (result == 0) {
     // Disable fdsan post-fork, so we don't falsely trigger on processes that
-    // fork, close all of their fds blindly, and then exec.
+    // fork, close all of their fds, and then exec.
     android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
 
     // Reset the stack_and_tls VMA name so it doesn't end with a tid from the
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 3b804b0..88ae477 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -94,9 +94,6 @@
 }
 
 char* __fgets_chk(char* dst, int supplied_size, FILE* stream, size_t dst_len_from_compiler) {
-  if (supplied_size < 0) {
-    __fortify_fatal("fgets: buffer size %d < 0", supplied_size);
-  }
   __check_buffer_access("fgets", "write into", supplied_size, dst_len_from_compiler);
   return fgets(dst, supplied_size, stream);
 }
diff --git a/libc/bionic/getauxval.cpp b/libc/bionic/getauxval.cpp
index d6f75f8..a3c6b19 100644
--- a/libc/bionic/getauxval.cpp
+++ b/libc/bionic/getauxval.cpp
@@ -37,20 +37,20 @@
 
 // This function needs to be safe to call before TLS is set up, so it can't
 // access errno or the stack protector.
-__LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool& exists) {
+__LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool* exists) {
   for (ElfW(auxv_t)* v = __libc_shared_globals()->auxv; v->a_type != AT_NULL; ++v) {
     if (v->a_type == type) {
-      exists = true;
+      *exists = true;
       return v->a_un.a_val;
     }
   }
-  exists = false;
+  *exists = false;
   return 0;
 }
 
 extern "C" unsigned long getauxval(unsigned long type) {
   bool exists;
-  unsigned long result = __bionic_getauxval(type, exists);
+  unsigned long result = __bionic_getauxval(type, &exists);
   if (!exists) errno = ENOENT;
   return result;
 }
diff --git a/libc/bionic/gethostname.cpp b/libc/bionic/gethostname.cpp
index 962fea1..b780a2f 100644
--- a/libc/bionic/gethostname.cpp
+++ b/libc/bionic/gethostname.cpp
@@ -32,10 +32,8 @@
 #include <unistd.h>
 
 int gethostname(char* buf, size_t n) {
-  struct utsname name;
-  if (uname(&name) == -1) {
-    return -1;
-  }
+  utsname name = {};
+  uname(&name);
 
   size_t name_length = static_cast<size_t>(strlen(name.nodename) + 1);
   if (name_length > n) {
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index 62b5f5c..540372b 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -34,19 +34,19 @@
 #include <platform/bionic/mte_kernel.h>
 
 extern "C" void scudo_malloc_disable_memory_tagging();
+extern "C" void scudo_malloc_set_track_allocation_stacks(int);
 
 static HeapTaggingLevel heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
 
 void SetDefaultHeapTaggingLevel() {
 #if defined(__aarch64__)
-#define PR_SET_TAGGED_ADDR_CTRL 55
-#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
 #ifdef ANDROID_EXPERIMENTAL_MTE
   // First, try enabling MTE in asynchronous mode, with tag 0 excluded. This will fail if the kernel
   // or hardware doesn't support MTE, and we will fall back to just enabling tagged pointers in
   // syscall arguments.
   if (prctl(PR_SET_TAGGED_ADDR_CTRL,
-            PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | (1 << PR_MTE_EXCL_SHIFT), 0, 0, 0) == 0) {
+            PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | (0xfffe << PR_MTE_TAG_SHIFT), 0, 0,
+            0) == 0) {
     heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC;
     return;
   }
@@ -80,34 +80,48 @@
 
   switch (tag_level) {
     case M_HEAP_TAGGING_LEVEL_NONE:
+#if defined(USE_SCUDO)
+      scudo_malloc_disable_memory_tagging();
+#endif
+      if (heap_tagging_level == M_HEAP_TAGGING_LEVEL_TBI) {
+        __libc_globals.mutate([](libc_globals* globals) {
+          // Preserve the untag mask (we still want to untag pointers when passing them to the
+          // allocator), but clear the fixed tag and the check mask, so that pointers are no longer
+          // tagged and checks no longer happen.
+          globals->heap_pointer_tag = static_cast<uintptr_t>(0xffull << UNTAG_SHIFT);
+        });
+      }
       break;
     case M_HEAP_TAGGING_LEVEL_TBI:
     case M_HEAP_TAGGING_LEVEL_ASYNC:
+    case M_HEAP_TAGGING_LEVEL_SYNC:
       if (heap_tagging_level == M_HEAP_TAGGING_LEVEL_NONE) {
         error_log(
             "SetHeapTaggingLevel: re-enabling tagging after it was disabled is not supported");
-      } else {
-        error_log("SetHeapTaggingLevel: switching between TBI and ASYNC is not supported");
+        return false;
+      } else if (tag_level == M_HEAP_TAGGING_LEVEL_TBI ||
+                 heap_tagging_level == M_HEAP_TAGGING_LEVEL_TBI) {
+        error_log("SetHeapTaggingLevel: switching between TBI and ASYNC/SYNC is not supported");
+        return false;
       }
-      return false;
+
+      if (tag_level == M_HEAP_TAGGING_LEVEL_ASYNC) {
+#if defined(USE_SCUDO)
+        scudo_malloc_set_track_allocation_stacks(0);
+#endif
+      } else if (tag_level == M_HEAP_TAGGING_LEVEL_SYNC) {
+#if defined(USE_SCUDO)
+        scudo_malloc_set_track_allocation_stacks(1);
+#endif
+      }
+      break;
     default:
       error_log("SetHeapTaggingLevel: unknown tagging level");
       return false;
   }
+
   heap_tagging_level = tag_level;
   info_log("SetHeapTaggingLevel: tag level set to %d", tag_level);
 
-  if (heap_tagging_level == M_HEAP_TAGGING_LEVEL_NONE) {
-#if defined(USE_SCUDO)
-    scudo_malloc_disable_memory_tagging();
-#endif
-    __libc_globals.mutate([](libc_globals* globals) {
-      // Preserve the untag mask (we still want to untag pointers when passing them to the
-      // allocator if we were doing so before), but clear the fixed tag and the check mask,
-      // so that pointers are no longer tagged and checks no longer happen.
-      globals->heap_pointer_tag &= 0xffull << UNTAG_SHIFT;
-    });
-  }
-
   return true;
 }
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
index e89b0bf..1536333 100644
--- a/libc/bionic/ifaddrs.cpp
+++ b/libc/bionic/ifaddrs.cpp
@@ -28,6 +28,7 @@
 
 #include <ifaddrs.h>
 
+#include <async_safe/log.h>
 #include <cutils/misc.h>           // FIRST_APPLICATION_UID
 #include <errno.h>
 #include <linux/if_packet.h>
@@ -205,12 +206,12 @@
     new_addr->interface_index = static_cast<int>(msg->ifa_index);
 
     // If this is a known interface, copy what we already know.
+    // If we don't know about this interface yet, we try to resolve the name and flags using ioctl
+    // calls during postprocessing.
     if (known_addr != nullptr) {
       strcpy(new_addr->name, known_addr->name);
       new_addr->ifa.ifa_name = new_addr->name;
       new_addr->ifa.ifa_flags = known_addr->ifa.ifa_flags;
-    } else {
-      new_addr->ifa.ifa_flags = msg->ifa_flags;
     }
 
     // Go through the various bits of information and find the name, address
@@ -271,10 +272,34 @@
     } else {
       prev_addr = addr;
     }
+
     addr = reinterpret_cast<ifaddrs_storage*>(next_addr);
   }
 }
 
+static void get_interface_flags_via_ioctl(ifaddrs** list) {
+  ScopedFd s(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+  if (s.get() == -1) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC) failed in ifaddrs: %s",
+                          strerror(errno));
+    return;
+  }
+
+  for (ifaddrs_storage* addr = reinterpret_cast<ifaddrs_storage*>(*list); addr != nullptr;
+       addr = reinterpret_cast<ifaddrs_storage*>(addr->ifa.ifa_next)) {
+    ifreq ifr = {};
+    strlcpy(ifr.ifr_name, addr->ifa.ifa_name, sizeof(ifr.ifr_name));
+    if (ioctl(s.get(), SIOCGIFFLAGS, &ifr) != -1) {
+      addr->ifa.ifa_flags = ifr.ifr_flags;
+    } else {
+      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                            "ioctl(SIOCGIFFLAGS) for \"%s\" failed in ifaddrs: %s",
+                            addr->ifa.ifa_name, strerror(errno));
+    }
+  }
+}
+
 int getifaddrs(ifaddrs** out) {
   // We construct the result directly into `out`, so terminate the list.
   *out = nullptr;
@@ -303,6 +328,9 @@
     // If we weren't able to depend on GETLINK messages, it's possible some
     // interfaces never got their name set. Resolve them using if_indextoname or remove them.
     resolve_or_remove_nameless_interfaces(out);
+    // Similarly, without GETLINK messages, interfaces will not have their flags set.
+    // Resolve them using the SIOCGIFFLAGS ioctl call.
+    get_interface_flags_via_ioctl(out);
   }
 
   return 0;
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index a82ca50..01b6a42 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -52,6 +52,8 @@
 #include "pthread_internal.h"
 
 extern "C" int __system_properties_init(void);
+extern "C" void scudo_malloc_set_zero_contents(int);
+extern "C" void scudo_malloc_set_pattern_fill_contents(int);
 
 __LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
 
@@ -83,6 +85,17 @@
   _thread_arc4_lock();
 }
 
+static void __libc_init_malloc_fill_contents() {
+// TODO(b/158870657) make this unconditional when all devices support SCUDO.
+#if defined(USE_SCUDO)
+#if defined(SCUDO_PATTERN_FILL_CONTENTS)
+  scudo_malloc_set_pattern_fill_contents(1);
+#elif defined(SCUDO_ZERO_CONTENTS)
+  scudo_malloc_set_zero_contents(1);
+#endif
+#endif
+}
+
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void __libc_add_main_thread() {
   // Get the main thread from TLS and add it to the thread list.
@@ -106,6 +119,7 @@
   __libc_init_fdsan(); // Requires system properties (for debug.fdsan).
   __libc_init_fdtrack();
 
+  __libc_init_malloc_fill_contents();
   SetDefaultHeapTaggingLevel();
 }
 
@@ -348,10 +362,8 @@
   Dtor* fini_array = reinterpret_cast<Dtor*>(array);
   const Dtor minus1 = reinterpret_cast<Dtor>(static_cast<uintptr_t>(-1));
 
-  // Sanity check - first entry must be -1.
-  if (array == nullptr || fini_array[0] != minus1) {
-    return;
-  }
+  // Validity check: the first entry must be -1.
+  if (array == nullptr || fini_array[0] != minus1) return;
 
   // Skip over it.
   fini_array += 1;
@@ -362,15 +374,9 @@
     ++count;
   }
 
-  // Now call each destructor in reverse order.
+  // Now call each destructor in reverse order, ignoring any -1s.
   while (count > 0) {
     Dtor dtor = fini_array[--count];
-
-    // Sanity check, any -1 in the list is ignored.
-    if (dtor == minus1) {
-      continue;
-    }
-
-    dtor();
+    if (dtor != minus1) dtor();
   }
 }
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index cf5423e..e3a447d 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -147,6 +147,7 @@
     mod.first_generation = kTlsGenerationFirst;
 
     modules.module_count = 1;
+    modules.static_module_count = 1;
     modules.module_table = &mod;
   } else {
     layout.reserve_exe_segment_and_tcb(nullptr, progname);
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index da87c33..6a82ae3 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -366,6 +366,9 @@
   return true;
 }
 
+extern "C" const char* __scudo_get_stack_depot_addr();
+extern "C" const char* __scudo_get_region_info_addr();
+
 // Initializes memory allocation framework once per process.
 static void MallocInitImpl(libc_globals* globals) {
   char prop[PROP_VALUE_MAX];
@@ -373,6 +376,11 @@
 
   MaybeInitGwpAsanFromLibc(globals);
 
+#if defined(USE_SCUDO)
+  __libc_shared_globals()->scudo_stack_depot = __scudo_get_stack_depot_addr();
+  __libc_shared_globals()->scudo_region_info = __scudo_get_region_info_addr();
+#endif
+
   // Prefer malloc debug since it existed first and is a more complete
   // malloc interceptor than the hooks.
   bool hook_installed = false;
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index 51becf0..198bcba 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -56,8 +56,8 @@
 // +--->+-------------+------------------+
 // | +->+kInitialState+----------------+ |  malloc functions are not intercepted in any way.
 // | |  +-------+-----+                | |
-// | |          |                      | |
-// | |          v                      | |
+// | |          | HandleHeapprofd      | |
+// | |          v Signal()             | |
 // | |  +-------+----------------+     | |  currently installing the ephemeral hooks.
 // | |  |kInstallingEphemeralHook|<--+ | |
 // | |  +-------+----------------+   | | |
@@ -65,9 +65,9 @@
 // | |          v                    | | |
 // | |  +-------+---------------+    | | |  ephemeral hooks are installed. on the first call to
 // | |  |kEphemeralHookInstalled|    | | |  malloc these hooks spawn a thread that installs the
-// | |  +-------+---------------+    | | |  heapprofd hooks.
-// | |          |                    | | |
-// | |          v                    | | |
+// | |  +-------+---------------+    A B C  heapprofd hooks.
+// | |          | MallocInit         | | |
+// | |          v HeapprofdHook ()   | | |
 // | |  +-------+--------------+     | | |  first call to malloc happened. the hooks are reset to
 // | +--|kRemovingEphemeralHook|     | | |  kInitialState.
 // |    +----------------------+     | | |
@@ -81,7 +81,7 @@
 // |    +-------+------+             |   |  heapprofd hooks are installed. these forward calls to
 // |    |kHookInstalled|-------------+   |  malloc / free / etc. to heapprofd_client.so.
 // |    +-------+------+                 |
-// |            |                        |
+// |            | DispatchReset()        |
 // |            v                        |
 // |    +-------+---------+              |  currently resetting the hooks to default.
 // |----+kUninstallingHook|              |
@@ -92,6 +92,10 @@
 //      |kIncompatibleHooks+<------------+  precendence over heapprofd, so heapprofd will not get
 //      +------------------+                enabled. this is a terminal state.
 //
+//
+// A) HandleHeapprofdSignal()
+// B) HeapprofdInstallHooksAtInit() / InitHeapprofd()
+// C) HeapprofdRememberHookConflict()
 enum MallocHeapprofdState : uint8_t {
   kInitialState,
   kInstallingEphemeralHook,
diff --git a/libc/bionic/memmem.cpp b/libc/bionic/memmem.cpp
deleted file mode 100644
index 019e772..0000000
--- a/libc/bionic/memmem.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 <string.h>
-
-void* memmem(const void* void_haystack, size_t n, const void* void_needle, size_t m) {
-  const unsigned char* haystack = reinterpret_cast<const unsigned char*>(void_haystack);
-  const unsigned char* needle = reinterpret_cast<const unsigned char*>(void_needle);
-
-  if (n < m) return nullptr;
-
-  if (m == 0) return const_cast<void*>(void_haystack);
-  if (m == 1) return const_cast<void*>(memchr(haystack, needle[0], n));
-
-  // This uses the "Not So Naive" algorithm, a very simple but usually effective algorithm.
-  // http://www-igm.univ-mlv.fr/~lecroq/string/
-  const unsigned char* y = haystack;
-  const unsigned char* x = needle;
-  size_t j = 0;
-  size_t k = 1, l = 2;
-
-  if (x[0] == x[1]) {
-    k = 2;
-    l = 1;
-  }
-  while (j <= n-m) {
-    if (x[1] != y[j+1]) {
-      j += k;
-    } else {
-      if (!memcmp(x+2, y+j+2, m-2) && x[0] == y[j]) return const_cast<unsigned char*>(&y[j]);
-      j += l;
-    }
-  }
-  return nullptr;
-}
diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp
index e9a5b5b..b15a317 100644
--- a/libc/bionic/ndk_cruft.cpp
+++ b/libc/bionic/ndk_cruft.cpp
@@ -55,8 +55,9 @@
 // By the time any NDK-built code is running, there are plenty of threads.
 int __isthreaded = 1;
 
-// These were accidentally declared in <unistd.h> because we stupidly used to inline
-// getpagesize() and __getpageshift(). Needed for backwards compatibility with old NDK apps.
+// These were accidentally declared in <unistd.h> because we used to inline
+// getpagesize() and __getpageshift(). Needed for backwards compatibility
+// with old NDK apps.
 unsigned int __page_size = PAGE_SIZE;
 unsigned int __page_shift = 12;
 
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index 3c4b169..89aa289 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -30,13 +30,13 @@
 
 #include <inttypes.h>
 #include <stdio.h>
+#include <string.h>
 #include <sys/resource.h>
 #include <unistd.h>
 
 #include <async_safe/log.h>
 
 #include "private/bionic_defs.h"
-#include "private/bionic_string_utils.h"
 #include "private/ErrnoRestorer.h"
 #include "pthread_internal.h"
 
@@ -192,7 +192,8 @@
     return errno;
   }
 
-  // If the current RLIMIT_STACK is RLIM_INFINITY, only admit to an 8MiB stack for sanity's sake.
+  // If the current RLIMIT_STACK is RLIM_INFINITY, only admit to an 8MiB stack
+  // in case callers such as ART take infinity too literally.
   if (stack_limit.rlim_cur == RLIM_INFINITY) {
     stack_limit.rlim_cur = 8 * 1024 * 1024;
   }
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index d4a8bef..c528105 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -350,7 +350,7 @@
   return 0;
 }
 
-// A dummy start routine for pthread_create failures where we've created a thread but aren't
+// A no-op start routine for pthread_create failures where we've created a thread but aren't
 // going to run user code on it. We swap out the user's start routine for this and take advantage
 // of the regular thread teardown to free up resources.
 static void* __do_nothing(void*) {
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index 3b873b3..81dab57 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -112,7 +112,6 @@
   munmap(thread->shadow_call_stack_guard_region, SCS_GUARD_REGION_SIZE);
 #endif
 
-  // Free the ELF TLS DTV and all dynamically-allocated ELF TLS memory.
   __free_dynamic_tls(__get_bionic_tcb());
 
   if (old_state == THREAD_DETACHED) {
@@ -128,6 +127,7 @@
     if (thread->mmap_size != 0) {
       // We need to free mapped space for detached threads when they exit.
       // That's not something we can do in C.
+      __notify_thread_exit_callbacks();
       __hwasan_thread_exit();
       _exit_with_stack_teardown(thread->mmap_base, thread->mmap_size);
     }
@@ -135,6 +135,8 @@
 
   // No need to free mapped space. Either there was no space mapped, or it is left for
   // the pthread_join caller to clean up.
+  __notify_thread_exit_callbacks();
   __hwasan_thread_exit();
+
   __exit(0);
 }
diff --git a/libc/bionic/pty.cpp b/libc/bionic/pty.cpp
index 71e14d9..c0e2721 100644
--- a/libc/bionic/pty.cpp
+++ b/libc/bionic/pty.cpp
@@ -112,14 +112,14 @@
   return ioctl(fd, TIOCSPTLCK, &unlock);
 }
 
-int openpty(int* master, int* slave, char* name, const termios* t, const winsize* ws) {
-  *master = getpt();
-  if (*master == -1) {
+int openpty(int* pty, int* tty, char* name, const termios* t, const winsize* ws) {
+  *pty = getpt();
+  if (*pty == -1) {
     return -1;
   }
 
-  if (grantpt(*master) == -1 || unlockpt(*master) == -1) {
-    close(*master);
+  if (grantpt(*pty) == -1 || unlockpt(*pty) == -1) {
+    close(*pty);
     return -1;
   }
 
@@ -127,54 +127,54 @@
   if (name == nullptr) {
     name = buf;
   }
-  if (ptsname_r(*master, name, sizeof(buf)) != 0) {
-    close(*master);
+  if (ptsname_r(*pty, name, sizeof(buf)) != 0) {
+    close(*pty);
     return -1;
   }
 
-  *slave = open(name, O_RDWR|O_NOCTTY);
-  if (*slave == -1) {
-    close(*master);
+  *tty = open(name, O_RDWR | O_NOCTTY);
+  if (*tty == -1) {
+    close(*pty);
     return -1;
   }
 
   if (t != nullptr) {
-    tcsetattr(*slave, TCSAFLUSH, t);
+    tcsetattr(*tty, TCSAFLUSH, t);
   }
   if (ws != nullptr) {
-    ioctl(*slave, TIOCSWINSZ, ws);
+    ioctl(*tty, TIOCSWINSZ, ws);
   }
 
   return 0;
 }
 
-int forkpty(int* amaster, char* name, const termios* t, const winsize* ws) {
-  int master;
-  int slave;
-  if (openpty(&master, &slave, name, t, ws) == -1) {
+int forkpty(int* parent_pty, char* child_tty_name, const termios* t, const winsize* ws) {
+  int pty;
+  int tty;
+  if (openpty(&pty, &tty, child_tty_name, t, ws) == -1) {
     return -1;
   }
 
   pid_t pid = fork();
   if (pid == -1) {
-    close(master);
-    close(slave);
+    close(pty);
+    close(tty);
     return -1;
   }
 
   if (pid == 0) {
     // Child.
-    *amaster = -1;
-    close(master);
-    if (login_tty(slave) == -1) {
+    *parent_pty = -1;
+    close(pty);
+    if (login_tty(tty) == -1) {
       _exit(1);
     }
     return 0;
   }
 
   // Parent.
-  *amaster = master;
-  close(slave);
+  *parent_pty = pty;
+  close(tty);
   return pid;
 }
 
diff --git a/libc/bionic/pututline.c b/libc/bionic/pututline.c
deleted file mode 100644
index 8cbf470..0000000
--- a/libc/bionic/pututline.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 <string.h>
-#include <stdio.h>
-#include <utmp.h>
-
-
-void pututline(struct utmp* utmp)
-{
-    FILE* f;
-    struct utmp u;
-    long i;
-
-    if (!(f = fopen(_PATH_UTMP, "w+e")))
-        return;
-
-    while (fread(&u, sizeof(struct utmp), 1, f) == 1)
-    {
-        if (!strncmp(utmp->ut_line, u.ut_line, sizeof(u.ut_line) -1))
-        {
-            if ((i = ftell(f)) < 0)
-                goto ret;
-            if (fseek(f, i - sizeof(struct utmp), SEEK_SET) < 0)
-                goto ret;
-            fwrite(utmp, sizeof(struct utmp), 1, f);
-            goto ret;
-        }
-    }
-
-
-    fclose(f);
-
-    if (!(f = fopen(_PATH_UTMP, "w+e")))
-        return;
-    fwrite(utmp, sizeof(struct utmp), 1, f);
-
-ret:
-    fclose(f);
-}
diff --git a/libc/bionic/scudo/Android.bp b/libc/bionic/scudo/Android.bp
deleted file mode 100644
index 9b77c06..0000000
--- a/libc/bionic/scudo/Android.bp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-cc_library_shared {
-    name: "libscudo_wrapper",
-    vendor_available: true,
-    srcs: ["scudo.cpp"],
-
-    stl: "none",
-    system_shared_libs: [],
-    host_supported: false,
-
-    header_libs: ["libc_headers"],
-    include_dirs: [
-        "bionic/libc",
-        "bionic/libc/bionic",
-    ],
-
-    whole_static_libs: ["libasync_safe"],
-
-    arch: {
-        arm: {
-            whole_static_libs: ["libclang_rt.scudo_minimal-arm-android.static"],
-        },
-        arm64: {
-            whole_static_libs: ["libclang_rt.scudo_minimal-aarch64-android.static"],
-        },
-        x86: {
-            whole_static_libs: ["libclang_rt.scudo_minimal-i686-android.static"],
-        },
-        x86_64: {
-            whole_static_libs: ["libclang_rt.scudo_minimal-x86_64-android.static"],
-        },
-    },
-
-    // Will be referencing other libc code that won't be defined here.
-    allow_undefined_symbols: true,
-
-    multilib: {
-        lib32: {
-            version_script: "exported32.map",
-        },
-        lib64: {
-            version_script: "exported64.map",
-        },
-    },
-
-    // Like libc, disable native coverage for libscudo_wrapper.
-    native_coverage: false,
-}
diff --git a/libc/bionic/scudo/exported32.map b/libc/bionic/scudo/exported32.map
deleted file mode 100644
index 4b6791d..0000000
--- a/libc/bionic/scudo/exported32.map
+++ /dev/null
@@ -1,16 +0,0 @@
-LIBC_SCUDO {
-  global:
-    scudo_aligned_alloc;
-    scudo_calloc;
-    scudo_free;
-    scudo_mallinfo;
-    scudo_malloc;
-    scudo_malloc_usable_size;
-    scudo_memalign;
-    scudo_posix_memalign;
-    scudo_pvalloc;
-    scudo_realloc;
-    scudo_valloc;
-  local:
-    *;
-};
diff --git a/libc/bionic/scudo/exported64.map b/libc/bionic/scudo/exported64.map
deleted file mode 100644
index 1346b4b..0000000
--- a/libc/bionic/scudo/exported64.map
+++ /dev/null
@@ -1,14 +0,0 @@
-LIBC_SCUDO {
-  global:
-    scudo_aligned_alloc;
-    scudo_calloc;
-    scudo_free;
-    scudo_mallinfo;
-    scudo_malloc;
-    scudo_malloc_usable_size;
-    scudo_memalign;
-    scudo_posix_memalign;
-    scudo_realloc;
-  local:
-    *;
-};
diff --git a/libc/bionic/scudo/scudo.cpp b/libc/bionic/scudo/scudo.cpp
deleted file mode 100644
index 2cd36b1..0000000
--- a/libc/bionic/scudo/scudo.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2019 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 <errno.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/prctl.h>
-
-#include "platform/bionic/macros.h"
-
-#include "scudo.h"
-
-// Disable Scudo's mismatch allocation check, as it is being triggered
-// by some third party code.
-extern "C" const char *__scudo_default_options() {
-  return "DeallocationTypeMismatch=false";
-}
-
-static inline bool AllocTooBig(size_t bytes) {
-#if defined(__LP64__)
-  if (__predict_false(bytes > 0x10000000000ULL)) {
-#else
-  if (__predict_false(bytes > 0x80000000ULL)) {
-#endif
-    return true;
-  }
-  return false;
-}
-
-void* scudo_aligned_alloc(size_t alignment, size_t size) {
-  if (alignment == 0 || !powerof2(alignment) || (size % alignment) != 0) {
-    errno = EINVAL;
-    return nullptr;
-  }
-  if (AllocTooBig(size)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-
-  return aligned_alloc(alignment, size);
-}
-
-void* scudo_calloc(size_t item_count, size_t item_size) {
-  size_t total;
-  if (__builtin_mul_overflow(item_count, item_size, &total) || AllocTooBig(total)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-  return calloc(item_count, item_size);
-}
-
-void scudo_free(void* ptr) {
-  free(ptr);
-}
-
-extern "C" size_t __sanitizer_get_current_allocated_bytes();
-extern "C" size_t __sanitizer_get_heap_size();
-
-struct mallinfo scudo_mallinfo() {
-  struct mallinfo info {};
-  info.uordblks = __sanitizer_get_current_allocated_bytes();
-  info.hblkhd = __sanitizer_get_heap_size();
-  info.usmblks = info.hblkhd;
-  return info;
-}
-
-void* scudo_malloc(size_t byte_count) {
-  if (AllocTooBig(byte_count)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-  return malloc(byte_count);
-}
-
-size_t scudo_malloc_usable_size(const void* ptr) {
-  return malloc_usable_size(ptr);
-}
-
-void* scudo_memalign(size_t alignment, size_t byte_count) {
-  if (AllocTooBig(byte_count)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-  if (alignment != 0) {
-    if (!powerof2(alignment)) {
-      alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
-    }
-  } else {
-    alignment = 1;
-  }
-  return memalign(alignment, byte_count);
-}
-
-void* scudo_realloc(void* ptr, size_t byte_count) {
-  if (AllocTooBig(byte_count)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-  return realloc(ptr, byte_count);
-}
-
-int scudo_posix_memalign(void** memptr, size_t alignment, size_t size) {
-  if (alignment < sizeof(void*) || !powerof2(alignment)) {
-    return EINVAL;
-  }
-  if (AllocTooBig(size)) {
-    return ENOMEM;
-  }
-  return posix_memalign(memptr, alignment, size);
-}
-
-#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
-extern "C" void* pvalloc(size_t);
-
-void* scudo_pvalloc(size_t size) {
-  if (AllocTooBig(size)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-  return pvalloc(size);
-}
-
-extern "C" void* valloc(size_t);
-
-void* scudo_valloc(size_t size) {
-  if (AllocTooBig(size)) {
-    errno = ENOMEM;
-    return nullptr;
-  }
-  return valloc(size);
-}
-#endif
-
-// Do not try and name the scudo maps by overriding __sanitizer::internal_mmap.
-// There is already a function called MmapNamed that names the maps.
-// Unfortunately, there is no easy way to override MmapNamed because
-// too much of the code is not compiled into functions available in the
-// library, and the code is complicated.
diff --git a/libc/bionic/scudo_wrapper.cpp b/libc/bionic/scudo_wrapper.cpp
deleted file mode 100644
index 1624327..0000000
--- a/libc/bionic/scudo_wrapper.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 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 <errno.h>
-#include <stdio.h>
-
-#include "scudo.h"
-#include "private/bionic_globals.h"
-#include "private/WriteProtected.h"
-
-__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
-
-// Call the libc malloc initialisers.
-__attribute__((constructor(1))) static void __scudo_preinit() {
-  __libc_globals.mutate(__libc_init_malloc);
-}
-
-extern "C" libc_shared_globals* __loader_shared_globals();
-
-__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
-  return __loader_shared_globals();
-}
-
-#if defined(__i386__)
-__LIBC_HIDDEN__ void* __libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80);
-#endif
-
-extern "C" void scudo_malloc_disable_memory_tagging() {}
-
-int scudo_mallopt(int /*param*/, int /*value*/) {
-  return 0;
-}
-
-int scudo_malloc_info(int /*options*/, FILE* /*fp*/) {
-  errno = ENOTSUP;
-  return -1;
-}
-
-int scudo_malloc_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*) {
-  return 0;
-}
-
-void scudo_malloc_disable() {
-}
-
-void scudo_malloc_enable() {
-}
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 583bf32..1cdb021 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -85,6 +85,28 @@
 
 extern "C" int __rt_sigaction(int, const struct sigaction64*, struct sigaction64*, size_t);
 
+// sigaction and sigaction64 get interposed in ART: ensure that we don't end up calling
+//     sigchain sigaction -> bionic sigaction -> sigchain sigaction64 -> bionic sigaction64
+// by extracting the implementation of sigaction64 to a static function.
+static int __sigaction64(int signal, const struct sigaction64* bionic_new,
+                         struct sigaction64* bionic_old) {
+  struct sigaction64 kernel_new;
+  if (bionic_new) {
+    kernel_new = *bionic_new;
+#if defined(SA_RESTORER)
+    if (!(kernel_new.sa_flags & SA_RESTORER)) {
+      kernel_new.sa_flags |= SA_RESTORER;
+      kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
+    }
+#endif
+    // Don't filter signals here; if the caller asked for everything to be blocked, we should obey.
+    kernel_new.sa_mask = kernel_new.sa_mask;
+  }
+
+  return __rt_sigaction(signal, bionic_new ? &kernel_new : nullptr, bionic_old,
+                        sizeof(kernel_new.sa_mask));
+}
+
 int sigaction(int signal, const struct sigaction* bionic_new, struct sigaction* bionic_old) {
   // The 32-bit ABI is broken. struct sigaction includes a too-small sigset_t,
   // so we have to translate to struct sigaction64 first.
@@ -101,7 +123,7 @@
   }
 
   struct sigaction64 kernel_old;
-  int result = sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old);
+  int result = __sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old);
   if (bionic_old) {
     *bionic_old = {};
     bionic_old->sa_flags = kernel_old.sa_flags;
@@ -115,23 +137,7 @@
 }
 
 int sigaction64(int signal, const struct sigaction64* bionic_new, struct sigaction64* bionic_old) {
-  struct sigaction64 kernel_new;
-  if (bionic_new) {
-    kernel_new = *bionic_new;
-#if defined(SA_RESTORER)
-    if (!(kernel_new.sa_flags & SA_RESTORER)) {
-      kernel_new.sa_flags |= SA_RESTORER;
-      kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
-    }
-#endif
-    // Don't filter signals here; if the caller asked for everything to be blocked, we should obey.
-    kernel_new.sa_mask = kernel_new.sa_mask;
-  }
-
-  return __rt_sigaction(signal,
-                        bionic_new ? &kernel_new : nullptr,
-                        bionic_old,
-                        sizeof(kernel_new.sa_mask));
+  return __sigaction64(signal, bionic_new, bionic_old);
 }
 
 #endif
diff --git a/libc/bionic/strtol.cpp b/libc/bionic/strtol.cpp
index 63ac102..77f1d92 100644
--- a/libc/bionic/strtol.cpp
+++ b/libc/bionic/strtol.cpp
@@ -184,9 +184,7 @@
 }
 
 // Public API since L, but not in any header.
-extern "C" long long strtoq(const char* s, char** end, int base) {
-  return strtoll(s, end, base);
-}
+__strong_alias(strtoq, strtoll);
 
 unsigned long strtoul(const char* s, char** end, int base) {
   return StrToU<unsigned long, ULONG_MAX>(s, end, base);
@@ -201,6 +199,4 @@
 }
 
 // Public API since L, but not in any header.
-extern "C" unsigned long long strtouq(const char* s, char** end, int base) {
-  return strtoull(s, end, base);
-}
+__strong_alias(strtouq, strtoull);
diff --git a/libc/bionic/swab.cpp b/libc/bionic/swab.cpp
index bc53ba4..59e1c0f 100644
--- a/libc/bionic/swab.cpp
+++ b/libc/bionic/swab.cpp
@@ -28,14 +28,5 @@
 
 #include <unistd.h>
 
-void swab(const void* void_src, void* void_dst, ssize_t byte_count) {
-  const uint8_t* src = static_cast<const uint8_t*>(void_src);
-  uint8_t* dst = static_cast<uint8_t*>(void_dst);
-  while (byte_count > 1) {
-    uint8_t x = *src++;
-    uint8_t y = *src++;
-    *dst++ = y;
-    *dst++ = x;
-    byte_count -= 2;
-  }
-}
+#define __BIONIC_SWAB_INLINE /* Out of line. */
+#include <bits/swab.h>
diff --git a/libc/bionic/sys_thread_properties.cpp b/libc/bionic/sys_thread_properties.cpp
new file mode 100644
index 0000000..24d7551
--- /dev/null
+++ b/libc/bionic/sys_thread_properties.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2020 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/thread_properties.h>
+
+#include <async_safe/CHECK.h>
+#include <async_safe/log.h>
+
+#include <elf.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <sys/ptrace.h>
+#include <sys/uio.h>
+#include <sys/user.h>
+
+#include "private/bionic_elf_tls.h"
+#include "private/bionic_globals.h"
+#include "private/bionic_tls.h"
+#include "pthread_internal.h"
+
+void __libc_get_static_tls_bounds(void** stls_begin, void** stls_end) {
+  const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
+  *stls_begin = reinterpret_cast<char*>(__get_bionic_tcb()) - layout.offset_bionic_tcb();
+  *stls_end = reinterpret_cast<char*>(*stls_begin) + layout.size();
+}
+
+void __libc_register_thread_exit_callback(thread_exit_cb_t cb) {
+  TlsModules& modules = __libc_shared_globals()->tls_modules;
+
+  if (modules.first_thread_exit_callback == nullptr) {
+    modules.first_thread_exit_callback = cb;
+    return;
+  };
+
+  BionicAllocator& allocator = __libc_shared_globals()->tls_allocator;
+  CallbackHolder* new_node =
+      reinterpret_cast<CallbackHolder*>(allocator.alloc(sizeof(CallbackHolder)));
+  new_node->cb = cb;
+  new_node->prev = modules.thread_exit_callback_tail_node;
+  modules.thread_exit_callback_tail_node = new_node;
+}
+
+static inline __always_inline bionic_tcb* __get_bionic_tcb_for_thread(pid_t tid) {
+  // If tid is same as self, then we don't need ptrace.
+  if (gettid() == tid) return __get_bionic_tcb();
+
+  // Find the thread-pointer register for the given thread.
+  void** tp_reg = nullptr;
+
+#if defined(__x86_64__) || defined(__i386__)
+  struct user_regs_struct regs;
+  struct iovec pt_iov = {
+      .iov_base = &regs,
+      .iov_len = sizeof(regs),
+  };
+  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
+#if defined(__x86_64__)
+    tp_reg = reinterpret_cast<void**>(regs.fs);
+#elif defined(__i386__)
+    tp_reg = reinterpret_cast<void**>(regs.xgs);
+#endif
+  }
+#elif defined(__aarch64__) || defined(__arm__)
+  uint64_t reg;
+  struct iovec pt_iov {
+    .iov_base = &reg, .iov_len = sizeof(reg),
+  };
+
+  if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_TLS, &pt_iov) == 0) {
+    tp_reg = reinterpret_cast<void**>(reg);
+  }
+#endif
+
+  if (tp_reg == nullptr) {
+    async_safe_write_log(ANDROID_LOG_FATAL, "libc",
+                         "__get_bionic_tcb_for_thread failed to read thread register.");
+  }
+
+  return reinterpret_cast<bionic_tcb*>(&tp_reg[MIN_TLS_SLOT]);
+}
+
+void __libc_iterate_dynamic_tls(pid_t tid,
+                                void (*cb)(void* __dynamic_tls_begin, void* __dynamic_tls_end,
+                                           size_t __dso_id, void* __arg),
+                                void* arg) {
+  TlsModules& modules = __libc_shared_globals()->tls_modules;
+  bionic_tcb* const tcb = __get_bionic_tcb_for_thread(tid);
+  TlsDtv* const dtv = __get_tcb_dtv(tcb);
+  BionicAllocator& allocator = __libc_shared_globals()->tls_allocator;
+
+  for (size_t i = modules.static_module_count; i < dtv->count; ++i) {
+    void* dtls_begin = dtv->modules[i];
+    if (dtls_begin == nullptr) continue;
+    void* dtls_end =
+        static_cast<void*>(static_cast<char*>(dtls_begin) + allocator.get_chunk_size(dtls_begin));
+    size_t dso_id = __tls_module_idx_to_id(i);
+
+    cb(dtls_begin, dtls_end, dso_id, arg);
+  }
+}
+
+void __libc_register_dynamic_tls_listeners(dtls_listener_t on_creation,
+                                           dtls_listener_t on_destruction) {
+  TlsModules& tls_modules = __libc_shared_globals()->tls_modules;
+  tls_modules.on_creation_cb = on_creation;
+  tls_modules.on_destruction_cb = on_destruction;
+}
diff --git a/libc/bionic/sysinfo.cpp b/libc/bionic/sysinfo.cpp
index 1d1070e..7ab8e9e 100644
--- a/libc/bionic/sysinfo.cpp
+++ b/libc/bionic/sysinfo.cpp
@@ -38,9 +38,10 @@
 
 static bool __matches_cpuN(const char* s) {
   // The %c trick is to ensure that we have the anchored match "^cpu[0-9]+$".
+  // We can't use %*c because the return value is how many were *assigned*.
   unsigned cpu;
-  char dummy;
-  return (sscanf(s, "cpu%u%c", &cpu, &dummy) == 1);
+  char unused;
+  return (sscanf(s, "cpu%u%c", &cpu, &unused) == 1);
 }
 
 int get_nprocs_conf() {
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index 56822ac..6823b6a 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -41,12 +41,13 @@
 #include <sys/_system_properties.h>
 #include <unistd.h>
 
-#include <async_safe/log.h>
 #include <async_safe/CHECK.h>
+#include <async_safe/log.h>
+#include <system_properties/prop_trace.h>
 
-#include "private/bionic_defs.h"
 #include "platform/bionic/macros.h"
 #include "private/ScopedFd.h"
+#include "private/bionic_defs.h"
 
 static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
 static const char* kServiceVersionPropertyName = "ro.property_service.version";
@@ -209,7 +210,6 @@
       // mostly for ctl.* properties, but we do try and wait 250
       // ms so callers who do read-after-write can reliably see
       // what they've written.  Most of the time.
-      // TODO: fix the system properties design.
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
                             "Property service has timed out while trying to set \"%s\" to \"%s\"",
                             msg->name, msg->value);
@@ -250,6 +250,8 @@
   if (key == nullptr) return -1;
   if (value == nullptr) value = "";
 
+  SyspropTrace trace(key, value, nullptr /* prop_info */, PropertyAction::kPropertySet);
+
   if (g_propservice_protocol_version == 0) {
     detect_protocol_version();
   }
diff --git a/libc/bionic/tmpfile.cpp b/libc/bionic/tmpfile.cpp
index 4378e84..d7ce897 100644
--- a/libc/bionic/tmpfile.cpp
+++ b/libc/bionic/tmpfile.cpp
@@ -31,6 +31,7 @@
  */
 
 #include <errno.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -39,48 +40,48 @@
 #include <unistd.h>
 
 #include "private/ErrnoRestorer.h"
-#include "private/ScopedSignalBlocker.h"
 
-static FILE* __tmpfile_dir(const char* tmp_dir) {
+static FILE* __fd_to_fp(int fd) {
+  FILE* fp = fdopen(fd, "w+");
+  if (fp != nullptr) return fp;
+
+  ErrnoRestorer errno_restorer;
+  close(fd);
+  return nullptr;
+}
+
+static FILE* __tmpfile_dir_legacy(const char* tmp_dir) {
   char* path = nullptr;
   if (asprintf(&path, "%s/tmp.XXXXXXXXXX", tmp_dir) == -1) {
     return nullptr;
   }
 
-  int fd;
-  {
-    ScopedSignalBlocker ssb;
-    fd = mkstemp(path);
-    if (fd == -1) {
-      free(path);
-      return nullptr;
-    }
-
-    // Unlink the file now so that it's removed when closed.
-    unlink(path);
+  int fd = mkstemp(path);
+  if (fd == -1) {
     free(path);
-
-    // Can we still use the file now it's unlinked?
-    // File systems without hard link support won't have the usual Unix semantics.
-    struct stat sb;
-    int rc = fstat(fd, &sb);
-    if (rc == -1) {
-      ErrnoRestorer errno_restorer;
-      close(fd);
-      return nullptr;
-    }
+    return nullptr;
   }
 
-  // Turn the file descriptor into a FILE*.
-  FILE* fp = fdopen(fd, "w+");
-  if (fp != nullptr) {
-    return fp;
+  // Unlink the file now so that it's removed when closed.
+  unlink(path);
+  free(path);
+
+  // Can we still use the file now it's unlinked?
+  // File systems without hard link support won't have the usual Unix semantics.
+  struct stat sb;
+  if (fstat(fd, &sb) == -1) {
+    ErrnoRestorer errno_restorer;
+    close(fd);
+    return nullptr;
   }
 
-  // Failure. Clean up. We already unlinked, so we just need to close.
-  ErrnoRestorer errno_restorer;
-  close(fd);
-  return nullptr;
+  return __fd_to_fp(fd);
+}
+
+static FILE* __tmpfile_dir(const char* tmp_dir) {
+  int fd = open(tmp_dir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
+  if (fd == -1) return __tmpfile_dir_legacy(tmp_dir);
+  return __fd_to_fp(fd);
 }
 
 FILE* tmpfile() {
diff --git a/libc/arch-arm64/mte/bionic/strlen.c b/libc/bionic/utmp.cpp
similarity index 81%
copy from libc/arch-arm64/mte/bionic/strlen.c
copy to libc/bionic/utmp.cpp
index de88320..aa00cd5 100644
--- a/libc/arch-arm64/mte/bionic/strlen.c
+++ b/libc/bionic/utmp.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,23 @@
  * SUCH DAMAGE.
  */
 
-#include <upstream-openbsd/android/include/openbsd-compat.h>
+#include <utmp.h>
 
-#define strlen strlen_mte
-#include <upstream-openbsd/lib/libc/string/strlen.c>
+#include <errno.h>
+
+void endutent() {}
+
+void setutent() {}
+
+utmp* getutent() {
+  return nullptr;
+}
+
+utmp* pututline(const utmp*) {
+  return nullptr;
+}
+
+int utmpname(const char*) {
+  errno = ENOTSUP;
+  return -1;
+}
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 1b8af78..bcddddd 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -29,6 +29,13 @@
 #pragma once
 
 /**
+ * @defgroup apilevels API Levels
+ *
+ * Defines functions and constants for working with Android API levels.
+ * @{
+ */
+
+/**
  * @file android/api-level.h
  * @brief Functions and constants for dealing with multiple API levels.
  *
@@ -50,9 +57,40 @@
 /* This #ifndef should never be true except when doxygen is generating docs. */
 #ifndef __ANDROID_API__
 /**
- * `__ANDROID_API__` is the API level being targeted. For the OS,
- * this is `__ANDROID_API_FUTURE__`. For the NDK, this is set by the
- * compiler system based on the API level you claimed to target. See
+ * `__ANDROID_API__` is the [API
+ * level](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)
+ * this code is being built for. The resulting binaries are only guaranteed to
+ * be compatible with devices which have an API level greater than or equal to
+ * `__ANDROID_API__`.
+ *
+ * For NDK and APEX builds, this macro will always be defined. It is set
+ * automatically by Clang using the version suffix that is a part of the target
+ * name. For example, `__ANDROID_API__` will be 24 when Clang is given the
+ * argument `-target aarch64-linux-android24`.
+ *
+ * For non-APEX OS code, this defaults to  __ANDROID_API_FUTURE__.
+ *
+ * The value of `__ANDROID_API__` can be compared to the named constants in
+ * `<android/api-level.h>`.
+ *
+ * The interpretation of `__ANDROID_API__` is similar to the AndroidManifest.xml
+ * `minSdkVersion`. In most cases `__ANDROID_API__` will be identical to
+ * `minSdkVersion`, but as it is a build time constant it is possible for
+ * library code to use a different value than the app it will be included in.
+ * When libraries and applications build for different API levels, the
+ * `minSdkVersion` of the application must be at least as high as the highest
+ * API level used by any of its libraries which are loaded unconditionally.
+ *
+ * Note that in some cases the resulting binaries may load successfully on
+ * devices with an older API level. That behavior should not be relied upon,
+ * even if you are careful to avoid using new APIs, as the toolchain may make
+ * use of new features by default. For example, additional FORTIFY features may
+ * implicitly make use of new APIs, SysV hashes may be omitted in favor of GNU
+ * hashes to improve library load times, or relocation packing may be enabled to
+ * reduce binary size.
+ *
+ * See android_get_device_api_level(),
+ * android_get_application_target_sdk_version() and
  * https://android.googlesource.com/platform/bionic/+/master/docs/defines.md.
  */
 #define __ANDROID_API__ __ANDROID_API_FUTURE__
@@ -110,10 +148,13 @@
 /** Names the "R" API level (30), for comparison against `__ANDROID_API__`. */
 #define __ANDROID_API_R__ 30
 
+/** Names the "S" API level (31), for comparison against `__ANDROID_API__`. */
+#define __ANDROID_API_S__ 31
+
 /**
- * Returns the `targetSdkVersion` of the caller, or `__ANDROID_API_FUTURE__`
- * if there is no known target SDK version (for code not running in the
- * context of an app).
+ * Returns the `targetSdkVersion` of the caller, or `__ANDROID_API_FUTURE__` if
+ * there is no known target SDK version (for code not running in the context of
+ * an app).
  *
  * The returned values correspond to the named constants in `<android/api-level.h>`,
  * and is equivalent to the AndroidManifest.xml `targetSdkVersion`.
@@ -145,3 +186,5 @@
 #endif
 
 __END_DECLS
+
+/** @} */
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 83b9318..e23de85 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -186,7 +186,8 @@
  * Set the error level and return the previous state.
  *
  * Error checking is automatically disabled in the child of a fork, to maintain
- * compatibility with code that forks, blindly closes FDs, and then execs.
+ * compatibility with code that forks, closes all file descriptors, and then
+ * execs.
  *
  * In cases such as the zygote, where the child has no intention of calling
  * exec, call this function to reenable fdsan checks.
diff --git a/libc/arch-arm64/mte/bionic/strlen.c b/libc/include/android/legacy_unistd_inlines.h
similarity index 90%
rename from libc/arch-arm64/mte/bionic/strlen.c
rename to libc/include/android/legacy_unistd_inlines.h
index de88320..4a5206b 100644
--- a/libc/arch-arm64/mte/bionic/strlen.c
+++ b/libc/include/android/legacy_unistd_inlines.h
@@ -26,7 +26,13 @@
  * SUCH DAMAGE.
  */
 
-#include <upstream-openbsd/android/include/openbsd-compat.h>
+#pragma once
 
-#define strlen strlen_mte
-#include <upstream-openbsd/lib/libc/string/strlen.c>
+#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < 28
+
+#define __BIONIC_SWAB_INLINE static __inline
+#include <bits/swab.h>
+
+#endif
diff --git a/libc/include/bits/auxvec.h b/libc/include/bits/auxvec.h
index 4d39477..2d6522a 100644
--- a/libc/include/bits/auxvec.h
+++ b/libc/include/bits/auxvec.h
@@ -37,6 +37,14 @@
 
 #include <linux/auxvec.h>
 
+// AT_HWCAP isn't useful without these constants.
+#if __has_include(<asm/hwcap.h>)
+#include <asm/hwcap.h>
+#endif
+#if __has_include(<asm/hwcap2.h>)
+#include <asm/hwcap2.h>
+#endif
+
 /** Historical SuperH cruft. Irrelevant on Android. */
 #define AT_FPUCW 18
 /** Historical PowerPC cruft. Irrelevant on Android. */
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index aabcaab..71e67a3 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -186,6 +186,9 @@
 #if defined(__NR_faccessat)
   #define SYS_faccessat __NR_faccessat
 #endif
+#if defined(__NR_faccessat2)
+  #define SYS_faccessat2 __NR_faccessat2
+#endif
 #if defined(__NR_fadvise64)
   #define SYS_fadvise64 __NR_fadvise64
 #endif
@@ -702,6 +705,9 @@
 #if defined(__NR_openat)
   #define SYS_openat __NR_openat
 #endif
+#if defined(__NR_openat2)
+  #define SYS_openat2 __NR_openat2
+#endif
 #if defined(__NR_pause)
   #define SYS_pause __NR_pause
 #endif
@@ -720,6 +726,9 @@
 #if defined(__NR_personality)
   #define SYS_personality __NR_personality
 #endif
+#if defined(__NR_pidfd_getfd)
+  #define SYS_pidfd_getfd __NR_pidfd_getfd
+#endif
 #if defined(__NR_pidfd_open)
   #define SYS_pidfd_open __NR_pidfd_open
 #endif
diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h
index 633cb86..2ce6ee6 100644
--- a/libc/include/bits/stdatomic.h
+++ b/libc/include/bits/stdatomic.h
@@ -41,7 +41,7 @@
  */
 
 #include <stddef.h>  /* For ptrdiff_t. */
-#include <stdint.h>  /* TODO: don't drag in all the macros, just the types. */
+#include <stdint.h>
 // Include uchar.h only when available.  Bionic's stdatomic.h is also used for
 // the host (via a copy in prebuilts/clang) and uchar.h is not available in the
 // glibc used for the host.
diff --git a/libc/include/android/legacy_strings_inlines.h b/libc/include/bits/swab.h
similarity index 70%
rename from libc/include/android/legacy_strings_inlines.h
rename to libc/include/bits/swab.h
index 2cc2da2..63281b6 100644
--- a/libc/include/android/legacy_strings_inlines.h
+++ b/libc/include/bits/swab.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,17 +28,26 @@
 
 #pragma once
 
+#include <stdint.h>
 #include <sys/cdefs.h>
+#include <sys/types.h>
 
-#if defined(__i386__) && __ANDROID_API__ < 18
-
-#include <strings.h>
+#if !defined(__BIONIC_SWAB_INLINE)
+#define __BIONIC_SWAB_INLINE static __inline
+#endif
 
 __BEGIN_DECLS
 
-/* Everyone except x86 had ffs since the beginning. */
-static __inline int ffs(int __n) { return __builtin_ffs(__n); }
+__BIONIC_SWAB_INLINE void swab(const void* __void_src, void* __void_dst, ssize_t __byte_count) {
+  const uint8_t* __src = __BIONIC_CAST(static_cast, const uint8_t*, __void_src);
+  uint8_t* __dst = __BIONIC_CAST(static_cast, uint8_t*, __void_dst);
+  while (__byte_count > 1) {
+    uint8_t x = *__src++;
+    uint8_t y = *__src++;
+    *__dst++ = y;
+    *__dst++ = x;
+    __byte_count -= 2;
+  }
+}
 
 __END_DECLS
-
-#endif
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index d6819f2..2328b1a 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -26,8 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _DIRENT_H_
-#define _DIRENT_H_
+#pragma once
+
+/**
+ * @file dirent.h
+ * @brief Directory entry iteration.
+ */
 
 #include <stdint.h>
 #include <sys/cdefs.h>
@@ -35,17 +39,23 @@
 
 __BEGIN_DECLS
 
-#ifndef DT_UNKNOWN
+/** d_type value when the type is not known. */
 #define DT_UNKNOWN 0
+/** d_type value for a FIFO. */
 #define DT_FIFO 1
+/** d_type value for a character device. */
 #define DT_CHR 2
+/** d_type value for a directory. */
 #define DT_DIR 4
+/** d_type value for a block device. */
 #define DT_BLK 6
+/** d_type value for a regular file. */
 #define DT_REG 8
+/** d_type value for a symbolic link. */
 #define DT_LNK 10
+/** d_type value for a socket. */
 #define DT_SOCK 12
 #define DT_WHT 14
-#endif
 
 #if defined(__LP64__)
 #define __DIRENT64_INO_T ino_t
@@ -60,7 +70,9 @@
     unsigned char d_type; \
     char d_name[256]; \
 
+/** The structure returned by readdir(). Identical to dirent64 on Android. */
 struct dirent { __DIRENT64_BODY };
+/** The structure returned by readdir64(). Identical to dirent on Android. */
 struct dirent64 { __DIRENT64_BODY };
 
 #undef __DIRENT64_BODY
@@ -74,29 +86,158 @@
 
 #define d_fileno d_ino
 
+/** The structure returned by opendir()/fopendir(). */
 typedef struct DIR DIR;
 
+/**
+ * [opendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * opens a directory stream for the directory at `__path`.
+ *
+ * Returns null and sets `errno` on failure.
+ */
 DIR* opendir(const char* __path);
+
+/**
+ * [fopendir(3)](http://man7.org/linux/man-pages/man3/opendir.3.html)
+ * opens a directory stream for the directory at `__dir_fd`.
+ *
+ * Returns null and sets `errno` on failure.
+ */
 DIR* fdopendir(int __dir_fd);
+
+/**
+ * [readdir(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
+ * returns the next directory entry in the given directory.
+ *
+ * Returns a pointer to a directory entry on success,
+ * or returns null and leaves `errno` unchanged at the end of the directory,
+ * or returns null and sets `errno` on failure.
+ */
 struct dirent* readdir(DIR* __dir);
+
+/**
+ * [readdir64(3)](http://man7.org/linux/man-pages/man3/readdir.3.html)
+ * returns the next directory entry in the given directory.
+ *
+ * Returns a pointer to a directory entry on success,
+ * or returns null and leaves `errno` unchanged at the end of the directory,
+ * or returns null and sets `errno` on failure.
+ */
 struct dirent64* readdir64(DIR* __dir) __INTRODUCED_IN(21);
+
 int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
 int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
+
+/**
+ * [closedir(3)](http://man7.org/linux/man-pages/man3/closedir.3.html)
+ * closes a directory stream.
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
 int closedir(DIR* __dir);
+
+/**
+ * [rewinddir(3)](http://man7.org/linux/man-pages/man3/rewinddir.3.html)
+ * rewinds a directory stream to the first entry.
+ */
 void rewinddir(DIR* __dir);
+
+/**
+ * [seekdir(3)](http://man7.org/linux/man-pages/man3/seekdir.3.html)
+ * seeks a directory stream to the given entry, which must be a value returned
+ * by telldir().
+ *
+ * Available since API level 23.
+ */
 void seekdir(DIR* __dir, long __location) __INTRODUCED_IN(23);
+
+/**
+ * [telldir(3)](http://man7.org/linux/man-pages/man3/telldir.3.html)
+ * returns a value representing the current position in the directory
+ * for use with seekdir().
+ *
+ * Returns the current position on success and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 23.
+ */
 long telldir(DIR* __dir) __INTRODUCED_IN(23);
+
+/**
+ * [dirfd(3)](http://man7.org/linux/man-pages/man3/dirfd.3.html)
+ * returns the file descriptor backing the given directory stream.
+ *
+ * Returns a file descriptor on success and returns -1 and sets `errno` on failure.
+ */
 int dirfd(DIR* __dir);
+
+/**
+ * [alphasort](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * comparator for use with scandir() that uses strcoll().
+ */
 int alphasort(const struct dirent** __lhs, const struct dirent** __rhs);
+
+/**
+ * [alphasort64](http://man7.org/linux/man-pages/man3/alphasort.3.html) is a
+ * comparator for use with scandir64() that uses strcmp().
+ *
+ * Available since API level 21.
+ */
 int alphasort64(const struct dirent64** __lhs, const struct dirent64** __rhs) __INTRODUCED_IN(21);
-int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+
+/**
+ * [scandir(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
+ * scans all the directory `__path`, filtering entries with `__filter` and
+ * sorting them with qsort() using the given `__comparator`, and storing them
+ * into `__name_list`. Passing NULL as the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ */
 int scandir(const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**));
 
+/**
+ * [scandir64(3)](http://man7.org/linux/man-pages/man3/scandir.3.html)
+ * scans all the directory `__path`, filtering entries with `__filter` and
+ * sorting them with qsort() using the given `__comparator`, and storing them
+ * into `__name_list`. Passing NULL as the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 21.
+ */
+int scandir64(const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(21);
+
 #if defined(__USE_GNU)
+
+/**
+ * [scandirat64(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
+ * scans all the directory referenced by the pair of `__dir_fd` and `__path`,
+ * filtering entries with `__filter` and sorting them with qsort() using the
+ * given `__comparator`, and storing them into `__name_list`. Passing NULL as
+ * the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 24.
+ */
 int scandirat64(int __dir_fd, const char* __path, struct dirent64*** __name_list, int (*__filter)(const struct dirent64*), int (*__comparator)(const struct dirent64**, const struct dirent64**)) __INTRODUCED_IN(24);
+
+/**
+ * [scandirat(3)](http://man7.org/linux/man-pages/man3/scandirat.3.html)
+ * scans all the directory referenced by the pair of `__dir_fd` and `__path`,
+ * filtering entries with `__filter` and sorting them with qsort() using the
+ * given `__comparator`, and storing them into `__name_list`. Passing NULL as
+ * the filter accepts all entries.
+ *
+ * Returns the number of entries returned in the list on success,
+ * and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 24.
+ */
 int scandirat(int __dir_fd, const char* __path, struct dirent*** __name_list, int (*__filter)(const struct dirent*), int (*__comparator)(const struct dirent**, const struct dirent**)) __INTRODUCED_IN(24);
+
 #endif
 
 __END_DECLS
-
-#endif
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index ba0af3c..833fa59 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -170,6 +170,28 @@
  * Available since API level 28.
  */
 #define M_PURGE (-101)
+/**
+ * mallopt() option to set the maximum number of items in the secondary
+ * cache of the scudo allocator.
+ *
+ * Available since API level 31.
+ */
+#define M_CACHE_COUNT_MAX (-200)
+/**
+ * mallopt() option to set the maximum size in bytes of a cacheable item in
+ * the secondary cache of the scudo allocator.
+ *
+ * Available since API level 31.
+ */
+#define M_CACHE_SIZE_MAX (-201)
+/**
+ * mallopt() option to increase the maximum number of shared thread-specific
+ * data structures that can be created. This number cannot be decreased,
+ * only increased and only applies to the scudo allocator.
+ *
+ * Available since API level 31.
+ */
+#define M_TSDS_COUNT_MAX (-202)
 
 /**
  * [mallopt(3)](http://man7.org/linux/man-pages/man3/mallopt.3.html) modifies
diff --git a/libc/include/math.h b/libc/include/math.h
index 7efc83a..8c084b2 100644
--- a/libc/include/math.h
+++ b/libc/include/math.h
@@ -10,12 +10,10 @@
  */
 
 /*
- * from: @(#)fdlibm.h 5.1 93/09/24
- * $FreeBSD$
+ * Originally based on fdlibm.h 5.1 via FreeBSD.
  */
 
-#ifndef _MATH_H_
-#define _MATH_H_
+#pragma once
 
 #include <sys/cdefs.h>
 #include <limits.h>
@@ -408,5 +406,3 @@
 #endif
 
 __END_DECLS
-
-#endif
diff --git a/libc/include/nl_types.h b/libc/include/nl_types.h
index 622880a..1c80e4e 100644
--- a/libc/include/nl_types.h
+++ b/libc/include/nl_types.h
@@ -32,7 +32,7 @@
  * @file nl_types.h
  * @brief Message catalogs.
  *
- * Android offers a dummy implementation of these functions to ease porting of historical software.
+ * Android offers a no-op implementation of these functions to ease porting of historical software.
  */
 
 #include <sys/cdefs.h>
diff --git a/libc/include/pty.h b/libc/include/pty.h
index 90d6686..be447d6 100644
--- a/libc/include/pty.h
+++ b/libc/include/pty.h
@@ -49,16 +49,17 @@
  *
  * Available since API level 23.
  */
-int openpty(int* _Nonnull __master_fd, int* _Nonnull __slave_fd, char* _Nullable __slave_name, const struct termios* _Nullable __termios_ptr, const struct winsize* _Nullable __winsize_ptr) __INTRODUCED_IN(23);
+int openpty(int* _Nonnull __pty_fd, int* _Nonnull __tty_fd, char* _Nullable __tty_name, const struct termios* _Nullable __termios_ptr, const struct winsize* _Nullable __winsize_ptr) __INTRODUCED_IN(23);
 
 /**
  * [forkpty(3)](http://man7.org/linux/man-pages/man3/forkpty.3.html) creates
  * a new process connected to a pseudoterminal from openpty().
  *
- * Returns 0 on success and returns -1 and sets `errno` on failure.
+ * Returns 0 in the child/the pid of the child in the parent on success,
+ * and returns -1 and sets `errno` on failure.
  *
  * Available since API level 23.
  */
-int forkpty(int* _Nonnull __master_fd, char* _Nullable __slave_name, const struct termios* _Nullable __termios_ptr, const struct winsize* _Nullable __winsize_ptr) __INTRODUCED_IN(23);
+int forkpty(int* _Nonnull __parent_pty_fd, char* _Nullable __child_tty_name, const struct termios* _Nullable __termios_ptr, const struct winsize* _Nullable __winsize_ptr) __INTRODUCED_IN(23);
 
 __END_DECLS
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 08c2326..ff6b925 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -49,6 +49,14 @@
 
 #include <bits/strcasecmp.h>
 
+#if !defined(__BIONIC_STRINGS_INLINE)
+#define __BIONIC_STRINGS_INLINE static __inline
+#endif
+
+#undef ffs
+#undef ffsl
+#undef ffsll
+
 __BEGIN_DECLS
 
 /** Deprecated. Use memmove() instead. */
@@ -63,19 +71,41 @@
   __builtin_memset(b, 0, len);
 }
 
-#if !defined(__i386__) || __ANDROID_API__ >= 18
 /**
- * [ffs(3)](http://man7.org/linux/man-pages/man3/ffs.3.html) finds the first set bit in `__i`.
+ * [ffs(3)](http://man7.org/linux/man-pages/man3/ffs.3.html) finds the
+ * first set bit in `__n`.
  *
- * Returns 0 if no bit is set, or the index of the lowest set bit (counting from 1) otherwise.
+ * Returns 0 if no bit is set, or the index of the lowest set bit (counting
+ * from 1) otherwise.
  */
-int ffs(int __i) __INTRODUCED_IN_X86(18);
-#endif
+__BIONIC_STRINGS_INLINE int ffs(int __n) {
+  return __builtin_ffs(__n);
+}
+
+/**
+ * [ffsl(3)](http://man7.org/linux/man-pages/man3/ffsl.3.html) finds the
+ * first set bit in `__n`.
+ *
+ * Returns 0 if no bit is set, or the index of the lowest set bit (counting
+ * from 1) otherwise.
+ */
+__BIONIC_STRINGS_INLINE int ffsl(long __n) {
+  return __builtin_ffsl(__n);
+}
+
+/**
+ * [ffsll(3)](http://man7.org/linux/man-pages/man3/ffsll.3.html) finds the
+ * first set bit in `__n`.
+ *
+ * Returns 0 if no bit is set, or the index of the lowest set bit (counting
+ * from 1) otherwise.
+ */
+__BIONIC_STRINGS_INLINE int ffsll(long long __n) {
+  return __builtin_ffsll(__n);
+}
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #include <bits/fortify/strings.h>
 #endif
 
 __END_DECLS
-
-#include <android/legacy_strings_inlines.h>
diff --git a/libc/include/sys/auxv.h b/libc/include/sys/auxv.h
index c651940..bf70dda 100644
--- a/libc/include/sys/auxv.h
+++ b/libc/include/sys/auxv.h
@@ -40,7 +40,7 @@
 __BEGIN_DECLS
 
 /**
- * [getauxval(3)](http://man7.org/linux/man-pages/man2/personality.2.html) returns values from
+ * [getauxval(3)](http://man7.org/linux/man-pages/man3/getauxval.3.html) returns values from
  * the ELF auxiliary vector passed by the kernel.
  *
  * Returns the corresponding value on success,
diff --git a/libc/include/sys/procfs.h b/libc/include/sys/procfs.h
index 75a1e98..a082e97 100644
--- a/libc/include/sys/procfs.h
+++ b/libc/include/sys/procfs.h
@@ -26,16 +26,24 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _SYS_PROCFS_H_
-#define _SYS_PROCFS_H_
+#pragma once
 
 #include <sys/cdefs.h>
+#include <sys/ptrace.h>
 #include <sys/ucontext.h>
 
 __BEGIN_DECLS
 
+#if defined(__arm__)
+#define ELF_NGREG (sizeof(struct user_regs) / sizeof(elf_greg_t))
+#elif defined(__aarch64__)
+#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t))
+#else
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+#endif
+
 typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[NGREG];
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef fpregset_t elf_fpregset_t;
 
@@ -58,5 +66,3 @@
 #define ELF_PRARGSZ 80
 
 __END_DECLS
-
-#endif
diff --git a/libc/include/sys/thread_properties.h b/libc/include/sys/thread_properties.h
new file mode 100644
index 0000000..b5d30c7
--- /dev/null
+++ b/libc/include/sys/thread_properties.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+/**
+ * @file thread_properties.h
+ * @brief Thread properties API.
+ *
+ * https://sourceware.org/glibc/wiki/ThreadPropertiesAPI
+ * API for querying various properties of the current thread, used mostly by
+ * the sanitizers.
+ *
+ * Available since API level 31.
+ *
+ */
+
+#include <sys/cdefs.h>
+#include <unistd.h>
+
+__BEGIN_DECLS
+
+/**
+ * Gets the bounds of static TLS for the current thread.
+ *
+ * Available since API level 31.
+ */
+void __libc_get_static_tls_bounds(void** __static_tls_begin,
+                                  void** __static_tls_end) __INTRODUCED_IN(31);
+
+
+/**
+ * Registers callback to be called right before the thread is dead.
+ * The callbacks are chained, they are called in the order opposite to the order
+ * they were registered.
+ *
+ * The callbacks must be registered only before any threads were created.
+ * No signals may arrive during the calls to these callbacks.
+ * The callbacks may not access the thread's dynamic TLS because they will have
+ * been freed by the time these callbacks are invoked.
+ *
+ * Available since API level 31.
+ */
+void __libc_register_thread_exit_callback(void (*__cb)(void)) __INTRODUCED_IN(31);
+
+/**
+ * Iterates over all dynamic TLS chunks for the given thread.
+ * The thread should have been suspended. It is undefined-behaviour if there is concurrent
+ * modification of the target thread's dynamic TLS.
+ *
+ * Available since API level 31.
+ */
+void __libc_iterate_dynamic_tls(pid_t __tid,
+                                void (*__cb)(void* __dynamic_tls_begin,
+                                             void* __dynamic_tls_end,
+                                             size_t __dso_id,
+                                             void* __arg),
+                                void* __arg) __INTRODUCED_IN(31);
+
+/**
+ * Register on_creation and on_destruction callbacks, which will be called after a dynamic
+ * TLS creation and before a dynamic TLS destruction, respectively.
+ *
+ * Available since API level 31.
+ */
+void __libc_register_dynamic_tls_listeners(
+    void (*__on_creation)(void* __dynamic_tls_begin,
+                          void* __dynamic_tls_end),
+    void (*__on_destruction)(void* __dynamic_tls_begin,
+                             void* __dynamic_tls_end)) __INTRODUCED_IN(31);
+
+__END_DECLS
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index aaa8f22..e360421 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -313,7 +313,9 @@
 int getdomainname(char* __buf, size_t __buf_size) __INTRODUCED_IN(26);
 int setdomainname(const char* __name, size_t __n) __INTRODUCED_IN(26);
 
+#if __ANDROID_API__ >= 28
 void swab(const void* __src, void* __dst, ssize_t __byte_count) __INTRODUCED_IN(28);
+#endif
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #define _UNISTD_H_
@@ -322,3 +324,5 @@
 #endif
 
 __END_DECLS
+
+#include <android/legacy_unistd_inlines.h>
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index 6a52511..cb72ce2 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -25,8 +25,13 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#ifndef _UTMP_H_
-#define _UTMP_H_
+
+#pragma once
+
+/**
+ * @file utmp.h
+ * @brief POSIX login records.
+ */
 
 #include <sys/cdefs.h>
 #include <sys/types.h>
@@ -57,52 +62,71 @@
 #define DEAD_PROCESS  8
 #define ACCOUNTING    9
 
-struct lastlog
-{
-    time_t ll_time;
-    char ll_line[UT_LINESIZE];
-    char ll_host[UT_HOSTSIZE];
+struct lastlog {
+  time_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
 };
 
-struct exit_status
-{
-    short int e_termination;
-    short int e_exit;
+struct exit_status {
+  short int e_termination;
+  short int e_exit;
 };
 
+struct utmp {
+  short int ut_type;
+  pid_t ut_pid;
+  char ut_line[UT_LINESIZE];
+  char ut_id[4];
+  char ut_user[UT_NAMESIZE];
+  char ut_host[UT_HOSTSIZE];
 
-struct utmp
-{
-    short int ut_type;
-    pid_t ut_pid;
-    char ut_line[UT_LINESIZE];
-    char ut_id[4];
-    char ut_user[UT_NAMESIZE];
-    char ut_host[UT_HOSTSIZE];
+  struct exit_status ut_exit;
 
-    struct exit_status ut_exit;
+  long int ut_session;
+  struct timeval ut_tv;
 
-    long int ut_session;
-    struct timeval ut_tv;
-
-    int32_t ut_addr_v6[4];
-    char unsed[20];
+  int32_t ut_addr_v6[4];
+  char unused[20];
 };
 
-
 #define ut_name ut_user
 #define ut_time ut_tv.tv_sec
 #define ut_addr ut_addr_v6[0]
 
 __BEGIN_DECLS
 
+/**
+ * Does nothing.
+ */
 int utmpname(const char* __path);
+/**
+ * Does nothing.
+ */
 void setutent(void);
+/**
+ * Does nothing.
+ */
 struct utmp* getutent(void);
+/**
+ * Does nothing.
+ */
+struct utmp* pututline(const struct utmp* __entry);
+/**
+ * Does nothing.
+ */
 void endutent(void);
 
+/**
+ * [login_tty(3)](https://www.man7.org/linux/man-pages/man3/login_tty.3.html)
+ * prepares for login on the given file descriptor.
+ *
+ * See also forkpty() which combines openpty(), fork(), and login_tty().
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 23.
+ */
 int login_tty(int __fd) __INTRODUCED_IN(23);
 
 __END_DECLS
-
-#endif /* _UTMP_H_ */
diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py
index 92a2139..2c2d001 100755
--- a/libc/kernel/tools/clean_header.py
+++ b/libc/kernel/tools/clean_header.py
@@ -112,6 +112,7 @@
     if arch and arch in kernel_arch_token_replacements:
         blocks.replaceTokens(kernel_arch_token_replacements[arch])
 
+    blocks.removeStructs(kernel_structs_to_remove)
     blocks.optimizeMacros(macros)
     blocks.optimizeIf01()
     blocks.removeVarsAndFuncs(kernel_known_generic_statics)
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 1ada59e..8538eb0 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -30,10 +30,7 @@
 # Note that setting LD_LIBRARY_PATH with os.putenv() sometimes doesn't help.
 clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64/libclang_android.so'))
 
-from defaults import kCppUndefinedMacro
-from defaults import kernel_remove_config_macros
-from defaults import kernel_struct_replacements
-from defaults import kernel_token_replacements
+from defaults import *
 
 
 debugBlockParser = False
@@ -270,7 +267,7 @@
 
     def parseString(self, lines):
         """Parse a list of text lines into a BlockList object."""
-        file_ = 'dummy.c'
+        file_ = 'no-filename-available.c'
         self._tu = self._indexer.parse(file_, self.clang_flags,
                                        unsaved_files=[(file_, lines)],
                                        options=self.options)
@@ -1198,6 +1195,52 @@
             if b.isIf():
                 b.expr.optimize(macros)
 
+    def removeStructs(self, structs):
+        """Remove structs."""
+        for b in self.blocks:
+            # Have to look in each block for a top-level struct definition.
+            if b.directive:
+                continue
+            num_tokens = len(b.tokens)
+            # A struct definition has at least 5 tokens:
+            #   struct
+            #   ident
+            #   {
+            #   }
+            #   ;
+            if num_tokens < 5:
+                continue
+            # This is a simple struct finder, it might fail if a top-level
+            # structure has an #if type directives that confuses the algorithm
+            # for finding th end of the structure. Or if there is another
+            # structure definition embedded in the structure.
+            i = 0
+            while i < num_tokens - 2:
+                if (b.tokens[i].kind != TokenKind.KEYWORD or
+                    b.tokens[i].id != "struct"):
+                    i += 1
+                    continue
+                if (b.tokens[i + 1].kind == TokenKind.IDENTIFIER and
+                    b.tokens[i + 2].kind == TokenKind.PUNCTUATION and
+                    b.tokens[i + 2].id == "{" and b.tokens[i + 1].id in structs):
+                    # Search forward for the end of the structure.
+                    # Very simple search, look for } and ; tokens. If something
+                    # more complicated is needed we can add it later.
+                    j = i + 3
+                    while j < num_tokens - 1:
+                        if (b.tokens[j].kind == TokenKind.PUNCTUATION and
+                            b.tokens[j].id == "}" and
+                            b.tokens[j + 1].kind == TokenKind.PUNCTUATION and
+                            b.tokens[j + 1].id == ";"):
+                            b.tokens = b.tokens[0:i] + b.tokens[j + 2:num_tokens]
+                            num_tokens = len(b.tokens)
+                            j = i
+                            break
+                        j += 1
+                    i = j
+                    continue
+                i += 1
+
     def optimizeAll(self, macros):
         self.optimizeMacros(macros)
         self.optimizeIf01()
@@ -1755,7 +1798,6 @@
     def parse(self, text, macros=None):
         out = utils.StringOutput()
         blocks = BlockParser().parse(CppStringTokenizer(text))
-        blocks.replaceTokens(kernel_token_replacements)
         blocks.optimizeAll(macros)
         blocks.write(out)
         return out.get()
@@ -1931,8 +1973,8 @@
 #endif /* SIGRTMAX */
 """
         expected = """\
-#ifndef __SIGRTMAX
-#define __SIGRTMAX 123
+#ifndef SIGRTMAX
+#define SIGRTMAX 123
 #endif
 """
         self.assertEqual(self.parse(text), expected)
@@ -1948,6 +1990,146 @@
         expected = ""
         self.assertEqual(self.parse(text), expected)
 
+class RemoveStructsTests(unittest.TestCase):
+    def parse(self, text, structs):
+        out = utils.StringOutput()
+        blocks = BlockParser().parse(CppStringTokenizer(text))
+        blocks.removeStructs(structs)
+        blocks.write(out)
+        return out.get()
+
+    def test_remove_struct_from_start(self):
+        text = """\
+struct remove {
+  int val1;
+  int val2;
+};
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        expected = """\
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_struct_from_end(self):
+        text = """\
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct remove {
+  int val1;
+  int val2;
+};
+"""
+        expected = """\
+struct something {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_minimal_struct(self):
+        text = """\
+struct remove {
+};
+"""
+        expected = "";
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_struct_with_struct_fields(self):
+        text = """\
+struct something {
+  struct remove val1;
+  struct remove val2;
+};
+struct remove {
+  int val1;
+  struct something val3;
+  int val2;
+};
+"""
+        expected = """\
+struct something {
+  struct remove val1;
+  struct remove val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove"])), expected)
+
+    def test_remove_consecutive_structs(self):
+        text = """\
+struct keep1 {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct remove1 {
+  int val1;
+  int val2;
+};
+struct remove2 {
+  int val1;
+  int val2;
+  int val3;
+};
+struct keep2 {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        expected = """\
+struct keep1 {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct keep2 {
+  struct timeval val1;
+  struct timeval val2;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove1", "remove2"])), expected)
+
+    def test_remove_multiple_structs(self):
+        text = """\
+struct keep1 {
+  int val;
+};
+struct remove1 {
+  int val1;
+  int val2;
+};
+struct keep2 {
+  int val;
+};
+struct remove2 {
+  struct timeval val1;
+  struct timeval val2;
+};
+struct keep3 {
+  int val;
+};
+"""
+        expected = """\
+struct keep1 {
+  int val;
+};
+struct keep2 {
+  int val;
+};
+struct keep3 {
+  int val;
+};
+"""
+        self.assertEqual(self.parse(text, set(["remove1", "remove2"])), expected)
+
+
 class FullPathTest(unittest.TestCase):
     """Test of the full path parsing."""
 
@@ -1956,9 +2138,12 @@
             keep = set()
         out = utils.StringOutput()
         blocks = BlockParser().parse(CppStringTokenizer(text))
+
+        blocks.removeStructs(kernel_structs_to_remove)
         blocks.removeVarsAndFuncs(keep)
         blocks.replaceTokens(kernel_token_replacements)
         blocks.optimizeAll(None)
+
         blocks.write(out)
         return out.get()
 
@@ -2241,6 +2426,38 @@
 """
         self.assertEqual(self.parse(text), expected)
 
+    def test_verify_timeval_itemerval(self):
+        text = """\
+struct __kernel_old_timeval {
+  struct something val;
+};
+struct __kernel_old_itimerval {
+  struct __kernel_old_timeval val;
+};
+struct fields {
+  struct __kernel_old_timeval timeval;
+  struct __kernel_old_itimerval itimerval;
+};
+"""
+        expected = """\
+struct fields {
+  struct timeval timeval;
+  struct itimerval itimerval;
+};
+"""
+        self.assertEqual(self.parse(text), expected)
+
+    def test_token_replacement(self):
+        text = """\
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+"""
+        expected = """\
+#define __SIGRTMIN 32
+#define __SIGRTMAX _KERNEL__NSIG
+"""
+        self.assertEqual(self.parse(text), expected)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 90b56f5..04eb5f1 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -35,6 +35,17 @@
     "__kernel_old_timeval": "1",
     }
 
+# this is the set of known kernel data structures we want to remove from
+# the final headers
+kernel_structs_to_remove = set(
+        [
+          # Remove the structures since they are still the same as
+          # timeval, itimerval.
+          "__kernel_old_timeval",
+          "__kernel_old_itimerval",
+        ]
+    )
+
 # define to true if you want to remove all defined(CONFIG_FOO) tests
 # from the clean headers. testing shows that this is not strictly necessary
 # but just generates cleaner results
@@ -86,6 +97,8 @@
     # If struct __kernel_old_timeval and struct timeval become different,
     # then a different solution needs to be implemented.
     "__kernel_old_timeval": "timeval",
+    # Do the same for __kernel_old_itimerval as for timeval.
+    "__kernel_old_itimerval": "itimerval",
     }
 
 
diff --git a/libc/kernel/tools/generate_uapi_headers.sh b/libc/kernel/tools/generate_uapi_headers.sh
index 088c12e..4e7d2af 100755
--- a/libc/kernel/tools/generate_uapi_headers.sh
+++ b/libc/kernel/tools/generate_uapi_headers.sh
@@ -264,11 +264,6 @@
                  "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}/asm"
 done
 
-# The arm types.h uapi header is not properly being generated, so copy it
-# directly.
-cp "${KERNEL_DIR}/include/uapi/asm-generic/types.h" \
-   "${ANDROID_KERNEL_DIR}/uapi/asm-arm/asm"
-
 # Verify if modified headers have changed.
 verify_modified_hdrs "${KERNEL_DIR}/include/scsi" \
                      "${ANDROID_KERNEL_DIR}/scsi" \
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
deleted file mode 100644
index 6a6d963..0000000
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ /dev/null
@@ -1,216 +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 __ARM_KVM_H__
-#define __ARM_KVM_H__
-#include <linux/types.h>
-#include <linux/psci.h>
-#include <asm/ptrace.h>
-#define __KVM_HAVE_GUEST_DEBUG
-#define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_READONLY_MEM
-#define __KVM_HAVE_VCPU_EVENTS
-#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
-#define KVM_REG_SIZE(id) (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
-#define KVM_ARM_SVC_sp svc_regs[0]
-#define KVM_ARM_SVC_lr svc_regs[1]
-#define KVM_ARM_SVC_spsr svc_regs[2]
-#define KVM_ARM_ABT_sp abt_regs[0]
-#define KVM_ARM_ABT_lr abt_regs[1]
-#define KVM_ARM_ABT_spsr abt_regs[2]
-#define KVM_ARM_UND_sp und_regs[0]
-#define KVM_ARM_UND_lr und_regs[1]
-#define KVM_ARM_UND_spsr und_regs[2]
-#define KVM_ARM_IRQ_sp irq_regs[0]
-#define KVM_ARM_IRQ_lr irq_regs[1]
-#define KVM_ARM_IRQ_spsr irq_regs[2]
-#define KVM_ARM_FIQ_r8 fiq_regs[0]
-#define KVM_ARM_FIQ_r9 fiq_regs[1]
-#define KVM_ARM_FIQ_r10 fiq_regs[2]
-#define KVM_ARM_FIQ_fp fiq_regs[3]
-#define KVM_ARM_FIQ_ip fiq_regs[4]
-#define KVM_ARM_FIQ_sp fiq_regs[5]
-#define KVM_ARM_FIQ_lr fiq_regs[6]
-#define KVM_ARM_FIQ_spsr fiq_regs[7]
-struct kvm_regs {
-  struct pt_regs usr_regs;
-  unsigned long svc_regs[3];
-  unsigned long abt_regs[3];
-  unsigned long und_regs[3];
-  unsigned long irq_regs[3];
-  unsigned long fiq_regs[8];
-};
-#define KVM_ARM_TARGET_CORTEX_A15 0
-#define KVM_ARM_TARGET_CORTEX_A7 1
-#define KVM_ARM_NUM_TARGETS 2
-#define KVM_ARM_DEVICE_TYPE_SHIFT 0
-#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT)
-#define KVM_ARM_DEVICE_ID_SHIFT 16
-#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT)
-#define KVM_ARM_DEVICE_VGIC_V2 0
-#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
-#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
-#define KVM_VGIC_V2_DIST_SIZE 0x1000
-#define KVM_VGIC_V2_CPU_SIZE 0x2000
-#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
-#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
-#define KVM_VGIC_ITS_ADDR_TYPE 4
-#define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION 5
-#define KVM_VGIC_V3_DIST_SIZE SZ_64K
-#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
-#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
-#define KVM_ARM_VCPU_POWER_OFF 0
-#define KVM_ARM_VCPU_PSCI_0_2 1
-struct kvm_vcpu_init {
-  __u32 target;
-  __u32 features[7];
-};
-struct kvm_sregs {
-};
-struct kvm_fpu {
-};
-struct kvm_guest_debug_arch {
-};
-struct kvm_debug_exit_arch {
-};
-struct kvm_sync_regs {
-  __u64 device_irq_level;
-};
-struct kvm_arch_memory_slot {
-};
-struct kvm_vcpu_events {
-  struct {
-    __u8 serror_pending;
-    __u8 serror_has_esr;
-    __u8 ext_dabt_pending;
-    __u8 pad[5];
-    __u64 serror_esr;
-  } exception;
-  __u32 reserved[12];
-};
-#define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
-#define KVM_REG_ARM_COPROC_SHIFT 16
-#define KVM_REG_ARM_32_OPC2_MASK 0x0000000000000007
-#define KVM_REG_ARM_32_OPC2_SHIFT 0
-#define KVM_REG_ARM_OPC1_MASK 0x0000000000000078
-#define KVM_REG_ARM_OPC1_SHIFT 3
-#define KVM_REG_ARM_CRM_MASK 0x0000000000000780
-#define KVM_REG_ARM_CRM_SHIFT 7
-#define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800
-#define KVM_REG_ARM_32_CRN_SHIFT 11
-#define KVM_REG_ARM_SECURE_MASK 0x0000000010000000
-#define KVM_REG_ARM_SECURE_SHIFT 28
-#define ARM_CP15_REG_SHIFT_MASK(x,n) (((x) << KVM_REG_ARM_ ##n ##_SHIFT) & KVM_REG_ARM_ ##n ##_MASK)
-#define __ARM_CP15_REG(op1,crn,crm,op2) (KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT) | ARM_CP15_REG_SHIFT_MASK(op1, OPC1) | ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN) | ARM_CP15_REG_SHIFT_MASK(crm, CRM) | ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2))
-#define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32)
-#define __ARM_CP15_REG64(op1,crm) (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
-#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
-#define KVM_REG_ARM_PTIMER_CTL ARM_CP15_REG32(0, 14, 2, 1)
-#define KVM_REG_ARM_PTIMER_CNT ARM_CP15_REG64(0, 14)
-#define KVM_REG_ARM_PTIMER_CVAL ARM_CP15_REG64(2, 14)
-#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
-#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
-#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
-#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
-#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4)
-#define KVM_REG_ARM_DEMUX (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
-#define KVM_REG_ARM_DEMUX_ID_MASK 0x000000000000FF00
-#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
-#define KVM_REG_ARM_DEMUX_ID_CCSIDR (0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
-#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00000000000000FF
-#define KVM_REG_ARM_DEMUX_VAL_SHIFT 0
-#define KVM_REG_ARM_VFP (0x0012 << KVM_REG_ARM_COPROC_SHIFT)
-#define KVM_REG_ARM_VFP_MASK 0x000000000000FFFF
-#define KVM_REG_ARM_VFP_BASE_REG 0x0
-#define KVM_REG_ARM_VFP_FPSID 0x1000
-#define KVM_REG_ARM_VFP_FPSCR 0x1001
-#define KVM_REG_ARM_VFP_MVFR1 0x1006
-#define KVM_REG_ARM_VFP_MVFR0 0x1007
-#define KVM_REG_ARM_VFP_FPEXC 0x1008
-#define KVM_REG_ARM_VFP_FPINST 0x1009
-#define KVM_REG_ARM_VFP_FPINST2 0x100A
-#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
-#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_FW | ((r) & 0xffff))
-#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0)
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 KVM_REG_ARM_FW_REG(1)
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL 0
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL 1
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED 2
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 KVM_REG_ARM_FW_REG(2)
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL 0
-#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN 1
-#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_DEV_ARM_VGIC_GRP_ADDR 0
-#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
-#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
-#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32
-#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT)
-#define KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT 32
-#define KVM_DEV_ARM_VGIC_V3_MPIDR_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
-#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
-#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
-#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
-#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
-#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
-#define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
-#define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
-#define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7
-#define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
-#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10
-#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
-#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
-#define VGIC_LEVEL_INFO_LINE_LEVEL 0
-#define KVM_ARM_VCPU_PMU_V3_CTRL 0
-#define KVM_ARM_VCPU_PMU_V3_IRQ 0
-#define KVM_ARM_VCPU_PMU_V3_INIT 1
-#define KVM_ARM_VCPU_TIMER_CTRL 1
-#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
-#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
-#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
-#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
-#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
-#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES 3
-#define KVM_DEV_ARM_ITS_CTRL_RESET 4
-#define KVM_ARM_IRQ_VCPU2_SHIFT 28
-#define KVM_ARM_IRQ_VCPU2_MASK 0xf
-#define KVM_ARM_IRQ_TYPE_SHIFT 24
-#define KVM_ARM_IRQ_TYPE_MASK 0xf
-#define KVM_ARM_IRQ_VCPU_SHIFT 16
-#define KVM_ARM_IRQ_VCPU_MASK 0xff
-#define KVM_ARM_IRQ_NUM_SHIFT 0
-#define KVM_ARM_IRQ_NUM_MASK 0xffff
-#define KVM_ARM_IRQ_TYPE_CPU 0
-#define KVM_ARM_IRQ_TYPE_SPI 1
-#define KVM_ARM_IRQ_TYPE_PPI 2
-#define KVM_ARM_IRQ_CPU_IRQ 0
-#define KVM_ARM_IRQ_CPU_FIQ 1
-#define KVM_ARM_IRQ_GIC_MAX 127
-#define KVM_NR_IRQCHIPS 1
-#define KVM_PSCI_FN_BASE 0x95c1ba5e
-#define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
-#define KVM_PSCI_FN_CPU_SUSPEND KVM_PSCI_FN(0)
-#define KVM_PSCI_FN_CPU_OFF KVM_PSCI_FN(1)
-#define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
-#define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
-#define KVM_PSCI_RET_SUCCESS PSCI_RET_SUCCESS
-#define KVM_PSCI_RET_NI PSCI_RET_NOT_SUPPORTED
-#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
-#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
-#endif
diff --git a/libc/kernel/uapi/asm-arm/asm/types.h b/libc/kernel/uapi/asm-arm/asm/types.h
index ea6e7df..461e485 100644
--- a/libc/kernel/uapi/asm-arm/asm/types.h
+++ b/libc/kernel/uapi/asm-arm/asm/types.h
@@ -16,7 +16,19 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _ASM_GENERIC_TYPES_H
-#define _ASM_GENERIC_TYPES_H
+#ifndef _UAPI_ASM_TYPES_H
+#define _UAPI_ASM_TYPES_H
 #include <asm-generic/int-ll64.h>
+#ifdef __INT32_TYPE__
+#undef __INT32_TYPE__
+#define __INT32_TYPE__ int
+#endif
+#ifdef __UINT32_TYPE__
+#undef __UINT32_TYPE__
+#define __UINT32_TYPE__ unsigned int
+#endif
+#ifdef __UINTPTR_TYPE__
+#undef __UINTPTR_TYPE__
+#define __UINTPTR_TYPE__ unsigned long
+#endif
 #endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-common.h b/libc/kernel/uapi/asm-arm/asm/unistd-common.h
index 091bd74..5784399 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-common.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-common.h
@@ -407,4 +407,7 @@
 #define __NR_fspick (__NR_SYSCALL_BASE + 433)
 #define __NR_pidfd_open (__NR_SYSCALL_BASE + 434)
 #define __NR_clone3 (__NR_SYSCALL_BASE + 435)
+#define __NR_openat2 (__NR_SYSCALL_BASE + 437)
+#define __NR_pidfd_getfd (__NR_SYSCALL_BASE + 438)
+#define __NR_faccessat2 (__NR_SYSCALL_BASE + 439)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 8a38ab7..dcca79b 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -59,4 +59,13 @@
 #define HWCAP2_SVESM4 (1 << 6)
 #define HWCAP2_FLAGM2 (1 << 7)
 #define HWCAP2_FRINT (1 << 8)
+#define HWCAP2_SVEI8MM (1 << 9)
+#define HWCAP2_SVEF32MM (1 << 10)
+#define HWCAP2_SVEF64MM (1 << 11)
+#define HWCAP2_SVEBF16 (1 << 12)
+#define HWCAP2_I8MM (1 << 13)
+#define HWCAP2_BF16 (1 << 14)
+#define HWCAP2_DGH (1 << 15)
+#define HWCAP2_RNG (1 << 16)
+#define HWCAP2_BTI (1 << 17)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index efe1a9c..7c64817 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -137,8 +137,8 @@
 #define KVM_REG_ARM_PTIMER_CVAL ARM64_SYS_REG(3, 3, 14, 2, 2)
 #define KVM_REG_ARM_PTIMER_CNT ARM64_SYS_REG(3, 3, 14, 0, 1)
 #define KVM_REG_ARM_TIMER_CTL ARM64_SYS_REG(3, 3, 14, 3, 1)
-#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
 #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2)
+#define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2)
 #define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
 #define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_FW | ((r) & 0xffff))
 #define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0)
diff --git a/libc/kernel/uapi/asm-arm64/asm/mman.h b/libc/kernel/uapi/asm-arm64/asm/mman.h
index 6c23fb6..ed77d09 100644
--- a/libc/kernel/uapi/asm-arm64/asm/mman.h
+++ b/libc/kernel/uapi/asm-arm64/asm/mman.h
@@ -16,4 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
+#ifndef _UAPI__ASM_MMAN_H
+#define _UAPI__ASM_MMAN_H
 #include <asm-generic/mman.h>
+#define PROT_BTI 0x10
+#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index b3e0aea..31ba117 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -34,17 +34,24 @@
 #define PSR_I_BIT 0x00000080
 #define PSR_A_BIT 0x00000100
 #define PSR_D_BIT 0x00000200
+#define PSR_BTYPE_MASK 0x00000c00
 #define PSR_SSBS_BIT 0x00001000
 #define PSR_PAN_BIT 0x00400000
 #define PSR_UAO_BIT 0x00800000
+#define PSR_DIT_BIT 0x01000000
 #define PSR_V_BIT 0x10000000
 #define PSR_C_BIT 0x20000000
 #define PSR_Z_BIT 0x40000000
 #define PSR_N_BIT 0x80000000
+#define PSR_BTYPE_SHIFT 10
 #define PSR_f 0xff000000
 #define PSR_s 0x00ff0000
 #define PSR_x 0x0000ff00
 #define PSR_c 0x000000ff
+#define PSR_BTYPE_NONE (0b00 << PSR_BTYPE_SHIFT)
+#define PSR_BTYPE_JC (0b01 << PSR_BTYPE_SHIFT)
+#define PSR_BTYPE_C (0b10 << PSR_BTYPE_SHIFT)
+#define PSR_BTYPE_J (0b11 << PSR_BTYPE_SHIFT)
 #define PTRACE_SYSEMU 31
 #define PTRACE_SYSEMU_SINGLESTEP 32
 #ifndef __ASSEMBLY__
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index 2128ff5..efb5218 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -396,8 +396,11 @@
 #ifdef __ARCH_WANT_SYS_CLONE3
 #define __NR_clone3 435
 #endif
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
 #undef __NR_syscalls
-#define __NR_syscalls 436
+#define __NR_syscalls 440
 #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/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index d4865fb..58a20ce 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -324,9 +324,13 @@
 #define KVM_STATE_NESTED_GUEST_MODE 0x00000001
 #define KVM_STATE_NESTED_RUN_PENDING 0x00000002
 #define KVM_STATE_NESTED_EVMCS 0x00000004
+#define KVM_STATE_NESTED_MTF_PENDING 0x00000008
+#define KVM_STATE_NESTED_GIF_SET 0x00000100
 #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001
 #define KVM_STATE_NESTED_SMM_VMXON 0x00000002
 #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000
+#define KVM_STATE_NESTED_SVM_VMCB_SIZE 0x1000
+#define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE 0x00000001
 struct kvm_vmx_nested_state_data {
   __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
   __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
@@ -337,6 +341,14 @@
   struct {
     __u16 flags;
   } smm;
+  __u32 flags;
+  __u64 preemption_timer_deadline;
+};
+struct kvm_svm_nested_state_data {
+  __u8 vmcb12[KVM_STATE_NESTED_SVM_VMCB_SIZE];
+};
+struct kvm_svm_nested_state_hdr {
+  __u64 vmcb_pa;
 };
 struct kvm_nested_state {
   __u16 flags;
@@ -344,10 +356,12 @@
   __u32 size;
   union {
     struct kvm_vmx_nested_state_hdr vmx;
+    struct kvm_svm_nested_state_hdr svm;
     __u8 pad[120];
   } hdr;
   union {
     struct kvm_vmx_nested_state_data vmx[0];
+    struct kvm_svm_nested_state_data svm[0];
   } data;
 };
 struct kvm_pmu_event_filter {
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm_para.h b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
index ad8fe0b..8352761 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm_para.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
@@ -34,6 +34,7 @@
 #define KVM_FEATURE_PV_SEND_IPI 11
 #define KVM_FEATURE_POLL_CONTROL 12
 #define KVM_FEATURE_PV_SCHED_YIELD 13
+#define KVM_FEATURE_ASYNC_PF_INT 14
 #define KVM_HINTS_REALTIME 0
 #define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 24
 #define MSR_KVM_WALL_CLOCK 0x11
@@ -45,6 +46,8 @@
 #define MSR_KVM_STEAL_TIME 0x4b564d03
 #define MSR_KVM_PV_EOI_EN 0x4b564d04
 #define MSR_KVM_POLL_CONTROL 0x4b564d05
+#define MSR_KVM_ASYNC_PF_INT 0x4b564d06
+#define MSR_KVM_ASYNC_PF_ACK 0x4b564d07
 struct kvm_steal_time {
   __u64 steal;
   __u32 version;
@@ -70,6 +73,8 @@
 #define KVM_ASYNC_PF_ENABLED (1 << 0)
 #define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1)
 #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_MMU_OP_WRITE_PTE 1
 #define KVM_MMU_OP_FLUSH_TLB 2
 #define KVM_MMU_OP_RELEASE_PT 3
@@ -92,8 +97,9 @@
 #define KVM_PV_REASON_PAGE_NOT_PRESENT 1
 #define KVM_PV_REASON_PAGE_READY 2
 struct kvm_vcpu_pv_apf_data {
-  __u32 reason;
-  __u8 pad[60];
+  __u32 flags;
+  __u32 token;
+  __u8 pad[56];
   __u32 enabled;
 };
 #define KVM_PV_EOI_BIT 0
diff --git a/libc/kernel/uapi/asm-x86/asm/mce.h b/libc/kernel/uapi/asm-x86/asm/mce.h
index 4a3230c..359af57 100644
--- a/libc/kernel/uapi/asm-x86/asm/mce.h
+++ b/libc/kernel/uapi/asm-x86/asm/mce.h
@@ -45,6 +45,7 @@
   __u64 ipid;
   __u64 ppin;
   __u32 microcode;
+  __u64 kflags;
 };
 #define MCE_GET_RECORD_LEN _IOR('M', 1, int)
 #define MCE_GET_LOG_LEN _IOR('M', 2, int)
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd.h b/libc/kernel/uapi/asm-x86/asm/unistd.h
index 4bb90cf..8cab383 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef _UAPI_ASM_X86_UNISTD_H
 #define _UAPI_ASM_X86_UNISTD_H
-#define __X32_SYSCALL_BIT 0x40000000UL
+#define __X32_SYSCALL_BIT 0x40000000
 #ifdef __i386__
 #include <asm/unistd_32.h>
 #elif defined(__ILP32__)
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index 06e4a01..a3256c0 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -443,4 +443,7 @@
 #define __NR_fspick 433
 #define __NR_pidfd_open 434
 #define __NR_clone3 435
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index bcb6eae..9c12a3d 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -365,4 +365,7 @@
 #define __NR_fspick 433
 #define __NR_pidfd_open 434
 #define __NR_clone3 435
+#define __NR_openat2 437
+#define __NR_pidfd_getfd 438
+#define __NR_faccessat2 439
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index 3357bd1..5f92cfd 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -318,6 +318,9 @@
 #define __NR_fspick (__X32_SYSCALL_BIT + 433)
 #define __NR_pidfd_open (__X32_SYSCALL_BIT + 434)
 #define __NR_clone3 (__X32_SYSCALL_BIT + 435)
+#define __NR_openat2 (__X32_SYSCALL_BIT + 437)
+#define __NR_pidfd_getfd (__X32_SYSCALL_BIT + 438)
+#define __NR_faccessat2 (__X32_SYSCALL_BIT + 439)
 #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 e218d0d..47d5fb2 100644
--- a/libc/kernel/uapi/asm-x86/asm/vmx.h
+++ b/libc/kernel/uapi/asm-x86/asm/vmx.h
@@ -23,7 +23,7 @@
 #define EXIT_REASON_EXTERNAL_INTERRUPT 1
 #define EXIT_REASON_TRIPLE_FAULT 2
 #define EXIT_REASON_INIT_SIGNAL 3
-#define EXIT_REASON_PENDING_INTERRUPT 7
+#define EXIT_REASON_INTERRUPT_WINDOW 7
 #define EXIT_REASON_NMI_WINDOW 8
 #define EXIT_REASON_TASK_SWITCH 9
 #define EXIT_REASON_CPUID 10
@@ -78,7 +78,8 @@
 #define EXIT_REASON_XRSTORS 64
 #define EXIT_REASON_UMWAIT 67
 #define EXIT_REASON_TPAUSE 68
-#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, { EXIT_REASON_LDTR_TR, "LDTR_TR" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_RDTSCP, "RDTSCP" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_XSETBV, "XSETBV" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_RDRAND, "RDRAND" }, { EXIT_REASON_INVPCID, "INVPCID" }, { EXIT_REASON_VMFUNC, "VMFUNC" }, { EXIT_REASON_ENCLS, "ENCLS" }, { EXIT_REASON_RDSEED, "RDSEED" }, { EXIT_REASON_PML_FULL, "PML_FULL" }, { EXIT_REASON_XSAVES, "XSAVES" }, { EXIT_REASON_XRSTORS, "XRSTORS" }, { EXIT_REASON_UMWAIT, "UMWAIT" }, { EXIT_REASON_TPAUSE, "TPAUSE" }
+#define VMX_EXIT_REASONS { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, { EXIT_REASON_INTERRUPT_WINDOW, "INTERRUPT_WINDOW" }, { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, { EXIT_REASON_CPUID, "CPUID" }, { EXIT_REASON_HLT, "HLT" }, { EXIT_REASON_INVD, "INVD" }, { EXIT_REASON_INVLPG, "INVLPG" }, { EXIT_REASON_RDPMC, "RDPMC" }, { EXIT_REASON_RDTSC, "RDTSC" }, { EXIT_REASON_VMCALL, "VMCALL" }, { EXIT_REASON_VMCLEAR, "VMCLEAR" }, { EXIT_REASON_VMLAUNCH, "VMLAUNCH" }, { EXIT_REASON_VMPTRLD, "VMPTRLD" }, { EXIT_REASON_VMPTRST, "VMPTRST" }, { EXIT_REASON_VMREAD, "VMREAD" }, { EXIT_REASON_VMRESUME, "VMRESUME" }, { EXIT_REASON_VMWRITE, "VMWRITE" }, { EXIT_REASON_VMOFF, "VMOFF" }, { EXIT_REASON_VMON, "VMON" }, { EXIT_REASON_CR_ACCESS, "CR_ACCESS" }, { EXIT_REASON_DR_ACCESS, "DR_ACCESS" }, { EXIT_REASON_IO_INSTRUCTION, "IO_INSTRUCTION" }, { EXIT_REASON_MSR_READ, "MSR_READ" }, { EXIT_REASON_MSR_WRITE, "MSR_WRITE" }, { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, { EXIT_REASON_MSR_LOAD_FAIL, "MSR_LOAD_FAIL" }, { EXIT_REASON_MWAIT_INSTRUCTION, "MWAIT_INSTRUCTION" }, { EXIT_REASON_MONITOR_TRAP_FLAG, "MONITOR_TRAP_FLAG" }, { EXIT_REASON_MONITOR_INSTRUCTION, "MONITOR_INSTRUCTION" }, { EXIT_REASON_PAUSE_INSTRUCTION, "PAUSE_INSTRUCTION" }, { EXIT_REASON_MCE_DURING_VMENTRY, "MCE_DURING_VMENTRY" }, { EXIT_REASON_TPR_BELOW_THRESHOLD, "TPR_BELOW_THRESHOLD" }, { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, { EXIT_REASON_GDTR_IDTR, "GDTR_IDTR" }, { EXIT_REASON_LDTR_TR, "LDTR_TR" }, { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, { EXIT_REASON_INVEPT, "INVEPT" }, { EXIT_REASON_RDTSCP, "RDTSCP" }, { EXIT_REASON_PREEMPTION_TIMER, "PREEMPTION_TIMER" }, { EXIT_REASON_INVVPID, "INVVPID" }, { EXIT_REASON_WBINVD, "WBINVD" }, { EXIT_REASON_XSETBV, "XSETBV" }, { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, { EXIT_REASON_RDRAND, "RDRAND" }, { EXIT_REASON_INVPCID, "INVPCID" }, { EXIT_REASON_VMFUNC, "VMFUNC" }, { EXIT_REASON_ENCLS, "ENCLS" }, { EXIT_REASON_RDSEED, "RDSEED" }, { EXIT_REASON_PML_FULL, "PML_FULL" }, { EXIT_REASON_XSAVES, "XSAVES" }, { EXIT_REASON_XRSTORS, "XRSTORS" }, { EXIT_REASON_UMWAIT, "UMWAIT" }, { EXIT_REASON_TPAUSE, "TPAUSE" }
+#define VMX_EXIT_REASON_FLAGS { VMX_EXIT_REASONS_FAILED_VMENTRY, "FAILED_VMENTRY" }
 #define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1
 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2
 #define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index b986d30..91d0a7e 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -69,8 +69,9 @@
 #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_MQD_GFX9 (1 << 8)
+#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)
 struct drm_amdgpu_gem_create_in {
   __u64 bo_size;
   __u64 alignment;
@@ -205,6 +206,10 @@
 #define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF
 #define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43
 #define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMDGPU_TILING_DCC_INDEPENDENT_128B_SHIFT 44
+#define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMDGPU_TILING_SCANOUT_SHIFT 63
+#define AMDGPU_TILING_SCANOUT_MASK 0x1
 #define AMDGPU_TILING_SET(field,value) (((__u64) (value) & AMDGPU_TILING_ ##field ##_MASK) << AMDGPU_TILING_ ##field ##_SHIFT)
 #define AMDGPU_TILING_GET(value,field) (((__u64) (value) >> AMDGPU_TILING_ ##field ##_SHIFT) & AMDGPU_TILING_ ##field ##_MASK)
 #define AMDGPU_GEM_METADATA_OP_SET_METADATA 1
@@ -340,7 +345,7 @@
   __u32 ctx_id;
   __u32 bo_list_handle;
   __u32 num_chunks;
-  __u32 _pad;
+  __u32 flags;
   __u64 chunks;
 };
 struct drm_amdgpu_cs_out {
@@ -355,6 +360,8 @@
 #define AMDGPU_IB_FLAG_PREEMPT (1 << 2)
 #define AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE (1 << 3)
 #define AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID (1 << 4)
+#define AMDGPU_IB_FLAGS_SECURE (1 << 5)
+#define AMDGPU_IB_FLAG_EMIT_MEM_SYNC (1 << 6)
 struct drm_amdgpu_cs_chunk_ib {
   __u32 _pad;
   __u32 flags;
@@ -428,6 +435,7 @@
 #define AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM 0x11
 #define AMDGPU_INFO_FW_DMCU 0x12
 #define AMDGPU_INFO_FW_TA 0x13
+#define AMDGPU_INFO_FW_DMCUB 0x14
 #define AMDGPU_INFO_NUM_BYTES_MOVED 0x0f
 #define AMDGPU_INFO_VRAM_USAGE 0x10
 #define AMDGPU_INFO_GTT_USAGE 0x11
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index c78966c..878e899 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -573,6 +573,7 @@
 #define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
 #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer)
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
 #define DRM_COMMAND_BASE 0x40
 #define DRM_COMMAND_END 0xA0
 struct drm_event {
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index a316269..0ea5c83 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -145,6 +145,8 @@
 #define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
 #define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
 #define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
+#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6)
+#define I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS fourcc_mod_code(INTEL, 7)
 #define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
 #define DRM_FORMAT_MOD_SAMSUNG_16_16_TILE fourcc_mod_code(SAMSUNG, 2)
 #define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1)
@@ -156,13 +158,14 @@
 #define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3)
 #define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
 #define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1)
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) fourcc_mod_code(NVIDIA, 0x10 | ((v) & 0xf))
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB fourcc_mod_code(NVIDIA, 0x10)
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB fourcc_mod_code(NVIDIA, 0x11)
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB fourcc_mod_code(NVIDIA, 0x12)
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB fourcc_mod_code(NVIDIA, 0x13)
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB fourcc_mod_code(NVIDIA, 0x14)
-#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB fourcc_mod_code(NVIDIA, 0x15)
+#define DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c,s,g,k,h) fourcc_mod_code(NVIDIA, (0x10 | ((h) & 0xf) | (((k) & 0xff) << 12) | (((g) & 0x3) << 20) | (((s) & 0x1) << 22) | (((c) & 0x7) << 23)))
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 0, 0, 0, (v))
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4)
+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5)
 #define __fourcc_mod_broadcom_param_shift 8
 #define __fourcc_mod_broadcom_param_bits 48
 #define fourcc_mod_broadcom_code(val,params) fourcc_mod_code(BROADCOM, ((((__u64) params) << __fourcc_mod_broadcom_param_shift) | val))
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 2e61275..001ebd5 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -250,6 +250,7 @@
 #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)
 #define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_MMAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_offset)
 #define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
 #define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
 #define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
@@ -441,6 +442,17 @@
   __u32 pad;
   __u64 offset;
 };
+struct drm_i915_gem_mmap_offset {
+  __u32 handle;
+  __u32 pad;
+  __u64 offset;
+  __u64 flags;
+#define I915_MMAP_OFFSET_GTT 0
+#define I915_MMAP_OFFSET_WC 1
+#define I915_MMAP_OFFSET_WB 2
+#define I915_MMAP_OFFSET_UC 3
+  __u64 extensions;
+};
 struct drm_i915_gem_set_domain {
   __u32 handle;
   __u32 read_domains;
@@ -713,6 +725,7 @@
 #define I915_CONTEXT_PARAM_VM 0x9
 #define I915_CONTEXT_PARAM_ENGINES 0xa
 #define I915_CONTEXT_PARAM_PERSISTENCE 0xb
+#define I915_CONTEXT_PARAM_RINGSIZE 0xc
   __u64 value;
 };
 struct drm_i915_gem_context_param_sseu {
@@ -823,6 +836,8 @@
   DRM_I915_PERF_PROP_OA_FORMAT,
   DRM_I915_PERF_PROP_OA_EXPONENT,
   DRM_I915_PERF_PROP_HOLD_PREEMPTION,
+  DRM_I915_PERF_PROP_GLOBAL_SSEU,
+  DRM_I915_PERF_PROP_POLL_OA_PERIOD,
   DRM_I915_PERF_PROP_MAX
 };
 struct drm_i915_perf_open_param {
diff --git a/libc/kernel/uapi/drm/lima_drm.h b/libc/kernel/uapi/drm/lima_drm.h
index bb70cf7..bd8ba9c 100644
--- a/libc/kernel/uapi/drm/lima_drm.h
+++ b/libc/kernel/uapi/drm/lima_drm.h
@@ -38,6 +38,7 @@
   __u32 pad;
   __u64 value;
 };
+#define LIMA_BO_FLAG_HEAP (1 << 0)
 struct drm_lima_gem_create {
   __u32 size;
   __u32 flags;
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 3c1b734..fcfcc20 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -114,7 +114,16 @@
 #define MSM_SUBMIT_FENCE_FD_IN 0x40000000
 #define MSM_SUBMIT_FENCE_FD_OUT 0x20000000
 #define MSM_SUBMIT_SUDO 0x10000000
-#define MSM_SUBMIT_FLAGS (MSM_SUBMIT_NO_IMPLICIT | MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_FENCE_FD_OUT | MSM_SUBMIT_SUDO | 0)
+#define MSM_SUBMIT_SYNCOBJ_IN 0x08000000
+#define MSM_SUBMIT_SYNCOBJ_OUT 0x04000000
+#define MSM_SUBMIT_FLAGS (MSM_SUBMIT_NO_IMPLICIT | MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_FENCE_FD_OUT | MSM_SUBMIT_SUDO | MSM_SUBMIT_SYNCOBJ_IN | MSM_SUBMIT_SYNCOBJ_OUT | 0)
+#define MSM_SUBMIT_SYNCOBJ_RESET 0x00000001
+#define MSM_SUBMIT_SYNCOBJ_FLAGS (MSM_SUBMIT_SYNCOBJ_RESET | 0)
+struct drm_msm_gem_submit_syncobj {
+  __u32 handle;
+  __u32 flags;
+  __u64 point;
+};
 struct drm_msm_gem_submit {
   __u32 flags;
   __u32 fence;
@@ -124,6 +133,12 @@
   __u64 cmds;
   __s32 fence_fd;
   __u32 queueid;
+  __u64 in_syncobjs;
+  __u64 out_syncobjs;
+  __u32 nr_in_syncobjs;
+  __u32 nr_out_syncobjs;
+  __u32 syncobj_stride;
+  __u32 pad;
 };
 struct drm_msm_wait_fence {
   __u32 fence;
diff --git a/libc/kernel/uapi/drm/nouveau_drm.h b/libc/kernel/uapi/drm/nouveau_drm.h
index 186ffcc..150f729 100644
--- a/libc/kernel/uapi/drm/nouveau_drm.h
+++ b/libc/kernel/uapi/drm/nouveau_drm.h
@@ -92,6 +92,7 @@
   __u64 push;
   __u32 suffix0;
   __u32 suffix1;
+#define NOUVEAU_GEM_PUSHBUF_SYNC (1ULL << 0)
   __u64 vram_available;
   __u64 gart_available;
 };
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index 753192b..982b64f 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -55,6 +55,7 @@
 #define DRM_VMW_CREATE_EXTENDED_CONTEXT 26
 #define DRM_VMW_GB_SURFACE_CREATE_EXT 27
 #define DRM_VMW_GB_SURFACE_REF_EXT 28
+#define DRM_VMW_MSG 29
 #define DRM_VMW_PARAM_NUM_STREAMS 0
 #define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
 #define DRM_VMW_PARAM_3D 2
@@ -70,6 +71,7 @@
 #define DRM_VMW_PARAM_DX 12
 #define DRM_VMW_PARAM_HW_CAPS2 13
 #define DRM_VMW_PARAM_SM4_1 14
+#define DRM_VMW_PARAM_SM5 15
 enum drm_vmw_handle_type {
   DRM_VMW_HANDLE_LEGACY = 0,
   DRM_VMW_HANDLE_PRIME = 1
@@ -329,15 +331,16 @@
 };
 #define drm_vmw_unref_dmabuf_arg drm_vmw_handle_close_arg
 enum drm_vmw_surface_version {
-  drm_vmw_gb_surface_v1
+  drm_vmw_gb_surface_v1,
 };
 struct drm_vmw_gb_surface_create_ext_req {
   struct drm_vmw_gb_surface_create_req base;
   enum drm_vmw_surface_version version;
-  uint32_t svga3d_flags_upper_32_bits;
-  SVGA3dMSPattern multisample_pattern;
-  SVGA3dMSQualityLevel quality_level;
-  uint64_t must_be_zero;
+  __u32 svga3d_flags_upper_32_bits;
+  __u32 multisample_pattern;
+  __u32 quality_level;
+  __u32 buffer_byte_stride;
+  __u32 must_be_zero;
 };
 union drm_vmw_gb_surface_create_ext_arg {
   struct drm_vmw_gb_surface_create_rep rep;
@@ -351,6 +354,12 @@
   struct drm_vmw_gb_surface_ref_ext_rep rep;
   struct drm_vmw_surface_arg req;
 };
+struct drm_vmw_msg_arg {
+  __u64 send;
+  __u64 receive;
+  __s32 send_only;
+  __u32 receive_len;
+};
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index d14f018..d7f1e04 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -81,6 +81,8 @@
 #define AUDIT_FANOTIFY 1331
 #define AUDIT_TIME_INJOFFSET 1332
 #define AUDIT_TIME_ADJNTPVAL 1333
+#define AUDIT_BPF 1334
+#define AUDIT_EVENT_LISTENER 1335
 #define AUDIT_AVC 1400
 #define AUDIT_SELINUX_ERR 1401
 #define AUDIT_AVC_PATH 1402
diff --git a/libc/kernel/uapi/linux/b1lli.h b/libc/kernel/uapi/linux/b1lli.h
deleted file mode 100644
index 29c7fe8..0000000
--- a/libc/kernel/uapi/linux/b1lli.h
+++ /dev/null
@@ -1,64 +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 _B1LLI_H_
-#define _B1LLI_H_
-typedef struct avmb1_t4file {
-  int len;
-  unsigned char * data;
-} avmb1_t4file;
-typedef struct avmb1_loaddef {
-  int contr;
-  avmb1_t4file t4file;
-} avmb1_loaddef;
-typedef struct avmb1_loadandconfigdef {
-  int contr;
-  avmb1_t4file t4file;
-  avmb1_t4file t4config;
-} avmb1_loadandconfigdef;
-typedef struct avmb1_resetdef {
-  int contr;
-} avmb1_resetdef;
-typedef struct avmb1_getdef {
-  int contr;
-  int cardtype;
-  int cardstate;
-} avmb1_getdef;
-typedef struct avmb1_carddef {
-  int port;
-  int irq;
-} avmb1_carddef;
-#define AVM_CARDTYPE_B1 0
-#define AVM_CARDTYPE_T1 1
-#define AVM_CARDTYPE_M1 2
-#define AVM_CARDTYPE_M2 3
-typedef struct avmb1_extcarddef {
-  int port;
-  int irq;
-  int cardtype;
-  int cardnr;
-} avmb1_extcarddef;
-#define AVMB1_LOAD 0
-#define AVMB1_ADDCARD 1
-#define AVMB1_RESETCARD 2
-#define AVMB1_LOAD_AND_CONFIG 3
-#define AVMB1_ADDCARD_WITH_TYPE 4
-#define AVMB1_GET_CARDINFO 5
-#define AVMB1_REMOVECARD 6
-#define AVMB1_REGISTERCARD_IS_OBSOLETE
-#endif
diff --git a/libc/kernel/uapi/linux/bcache.h b/libc/kernel/uapi/linux/bcache.h
index 1bee0a3..5e5377e 100644
--- a/libc/kernel/uapi/linux/bcache.h
+++ b/libc/kernel/uapi/linux/bcache.h
@@ -56,11 +56,46 @@
 #define BCACHE_SB_VERSION_BDEV_WITH_OFFSET 4
 #define BCACHE_SB_MAX_VERSION 4
 #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 pad[8];
+  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];
+};
 struct cache_sb {
   __u64 csum;
   __u64 offset;
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 80a9feb..54b7849 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -95,6 +95,16 @@
   BPF_MAP_LOOKUP_AND_DELETE_ELEM,
   BPF_MAP_FREEZE,
   BPF_BTF_GET_NEXT_ID,
+  BPF_MAP_LOOKUP_BATCH,
+  BPF_MAP_LOOKUP_AND_DELETE_BATCH,
+  BPF_MAP_UPDATE_BATCH,
+  BPF_MAP_DELETE_BATCH,
+  BPF_LINK_CREATE,
+  BPF_LINK_UPDATE,
+  BPF_LINK_GET_FD_BY_ID,
+  BPF_LINK_GET_NEXT_ID,
+  BPF_ENABLE_STATS,
+  BPF_ITER_CREATE,
 };
 enum bpf_map_type {
   BPF_MAP_TYPE_UNSPEC,
@@ -123,6 +133,8 @@
   BPF_MAP_TYPE_STACK,
   BPF_MAP_TYPE_SK_STORAGE,
   BPF_MAP_TYPE_DEVMAP_HASH,
+  BPF_MAP_TYPE_STRUCT_OPS,
+  BPF_MAP_TYPE_RINGBUF,
 };
 enum bpf_prog_type {
   BPF_PROG_TYPE_UNSPEC,
@@ -152,6 +164,9 @@
   BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE,
   BPF_PROG_TYPE_CGROUP_SOCKOPT,
   BPF_PROG_TYPE_TRACING,
+  BPF_PROG_TYPE_STRUCT_OPS,
+  BPF_PROG_TYPE_EXT,
+  BPF_PROG_TYPE_LSM,
 };
 enum bpf_attach_type {
   BPF_CGROUP_INET_INGRESS,
@@ -180,11 +195,29 @@
   BPF_TRACE_RAW_TP,
   BPF_TRACE_FENTRY,
   BPF_TRACE_FEXIT,
+  BPF_MODIFY_RETURN,
+  BPF_LSM_MAC,
+  BPF_TRACE_ITER,
+  BPF_CGROUP_INET4_GETPEERNAME,
+  BPF_CGROUP_INET6_GETPEERNAME,
+  BPF_CGROUP_INET4_GETSOCKNAME,
+  BPF_CGROUP_INET6_GETSOCKNAME,
+  BPF_XDP_DEVMAP,
   __MAX_BPF_ATTACH_TYPE
 };
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
+enum bpf_link_type {
+  BPF_LINK_TYPE_UNSPEC = 0,
+  BPF_LINK_TYPE_RAW_TRACEPOINT = 1,
+  BPF_LINK_TYPE_TRACING = 2,
+  BPF_LINK_TYPE_CGROUP = 3,
+  BPF_LINK_TYPE_ITER = 4,
+  BPF_LINK_TYPE_NETNS = 5,
+  MAX_BPF_LINK_TYPE,
+};
 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
 #define BPF_F_ALLOW_MULTI (1U << 1)
+#define BPF_F_REPLACE (1U << 2)
 #define BPF_F_STRICT_ALIGNMENT (1U << 0)
 #define BPF_F_ANY_ALIGNMENT (1U << 1)
 #define BPF_F_TEST_RND_HI32 (1U << 2)
@@ -192,23 +225,29 @@
 #define BPF_PSEUDO_MAP_FD 1
 #define BPF_PSEUDO_MAP_VALUE 2
 #define BPF_PSEUDO_CALL 1
-#define BPF_ANY 0
-#define BPF_NOEXIST 1
-#define BPF_EXIST 2
-#define BPF_F_LOCK 4
-#define BPF_F_NO_PREALLOC (1U << 0)
-#define BPF_F_NO_COMMON_LRU (1U << 1)
-#define BPF_F_NUMA_NODE (1U << 2)
-#define BPF_OBJ_NAME_LEN 16U
-#define BPF_F_RDONLY (1U << 3)
-#define BPF_F_WRONLY (1U << 4)
-#define BPF_F_STACK_BUILD_ID (1U << 5)
-#define BPF_F_ZERO_SEED (1U << 6)
-#define BPF_F_RDONLY_PROG (1U << 7)
-#define BPF_F_WRONLY_PROG (1U << 8)
-#define BPF_F_CLONE (1U << 9)
-#define BPF_F_MMAPABLE (1U << 10)
+enum {
+  BPF_ANY = 0,
+  BPF_NOEXIST = 1,
+  BPF_EXIST = 2,
+  BPF_F_LOCK = 4,
+};
+enum {
+  BPF_F_NO_PREALLOC = (1U << 0),
+  BPF_F_NO_COMMON_LRU = (1U << 1),
+  BPF_F_NUMA_NODE = (1U << 2),
+  BPF_F_RDONLY = (1U << 3),
+  BPF_F_WRONLY = (1U << 4),
+  BPF_F_STACK_BUILD_ID = (1U << 5),
+  BPF_F_ZERO_SEED = (1U << 6),
+  BPF_F_RDONLY_PROG = (1U << 7),
+  BPF_F_WRONLY_PROG = (1U << 8),
+  BPF_F_CLONE = (1U << 9),
+  BPF_F_MMAPABLE = (1U << 10),
+};
 #define BPF_F_QUERY_EFFECTIVE (1U << 0)
+enum bpf_stats_type {
+  BPF_STATS_RUN_TIME = 0,
+};
 enum bpf_stack_build_id_status {
   BPF_STACK_BUILD_ID_EMPTY = 0,
   BPF_STACK_BUILD_ID_VALID = 1,
@@ -223,6 +262,7 @@
     __u64 ip;
   };
 };
+#define BPF_OBJ_NAME_LEN 16U
 union bpf_attr {
   struct {
     __u32 map_type;
@@ -237,6 +277,7 @@
     __u32 btf_fd;
     __u32 btf_key_type_id;
     __u32 btf_value_type_id;
+    __u32 btf_vmlinux_value_type_id;
   };
   struct {
     __u32 map_fd;
@@ -248,6 +289,16 @@
     __u64 flags;
   };
   struct {
+    __aligned_u64 in_batch;
+    __aligned_u64 out_batch;
+    __aligned_u64 keys;
+    __aligned_u64 values;
+    __u32 count;
+    __u32 map_fd;
+    __u64 elem_flags;
+    __u64 flags;
+  } batch;
+  struct {
     __u32 prog_type;
     __u32 insn_cnt;
     __aligned_u64 insns;
@@ -280,6 +331,7 @@
     __u32 attach_bpf_fd;
     __u32 attach_type;
     __u32 attach_flags;
+    __u32 replace_bpf_fd;
   };
   struct {
     __u32 prog_fd;
@@ -301,6 +353,7 @@
       __u32 prog_id;
       __u32 map_id;
       __u32 btf_id;
+      __u32 link_id;
     };
     __u32 next_id;
     __u32 open_flags;
@@ -340,43 +393,113 @@
     __u64 probe_offset;
     __u64 probe_addr;
   } task_fd_query;
+  struct {
+    __u32 prog_fd;
+    __u32 target_fd;
+    __u32 attach_type;
+    __u32 flags;
+  } link_create;
+  struct {
+    __u32 link_fd;
+    __u32 new_prog_fd;
+    __u32 flags;
+    __u32 old_prog_fd;
+  } link_update;
+  struct {
+    __u32 type;
+  } enable_stats;
+  struct {
+    __u32 link_fd;
+    __u32 flags;
+  } iter_create;
 } __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),
+#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),
 #define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
 enum bpf_func_id {
   __BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
 };
 #undef __BPF_ENUM_FN
-#define BPF_F_RECOMPUTE_CSUM (1ULL << 0)
-#define BPF_F_INVALIDATE_HASH (1ULL << 1)
-#define BPF_F_HDR_FIELD_MASK 0xfULL
-#define BPF_F_PSEUDO_HDR (1ULL << 4)
-#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
-#define BPF_F_MARK_ENFORCE (1ULL << 6)
-#define BPF_F_INGRESS (1ULL << 0)
-#define BPF_F_TUNINFO_IPV6 (1ULL << 0)
-#define BPF_F_SKIP_FIELD_MASK 0xffULL
-#define BPF_F_USER_STACK (1ULL << 8)
-#define BPF_F_FAST_STACK_CMP (1ULL << 9)
-#define BPF_F_REUSE_STACKID (1ULL << 10)
-#define BPF_F_USER_BUILD_ID (1ULL << 11)
-#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
-#define BPF_F_DONT_FRAGMENT (1ULL << 2)
-#define BPF_F_SEQ_NUMBER (1ULL << 3)
-#define BPF_F_INDEX_MASK 0xffffffffULL
-#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
-#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
-#define BPF_F_CURRENT_NETNS (- 1L)
-#define BPF_F_ADJ_ROOM_FIXED_GSO (1ULL << 0)
-#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff
-#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56
-#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 (1ULL << 1)
-#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 (1ULL << 2)
-#define BPF_F_ADJ_ROOM_ENCAP_L4_GRE (1ULL << 3)
-#define BPF_F_ADJ_ROOM_ENCAP_L4_UDP (1ULL << 4)
+enum {
+  BPF_F_RECOMPUTE_CSUM = (1ULL << 0),
+  BPF_F_INVALIDATE_HASH = (1ULL << 1),
+};
+enum {
+  BPF_F_HDR_FIELD_MASK = 0xfULL,
+};
+enum {
+  BPF_F_PSEUDO_HDR = (1ULL << 4),
+  BPF_F_MARK_MANGLED_0 = (1ULL << 5),
+  BPF_F_MARK_ENFORCE = (1ULL << 6),
+};
+enum {
+  BPF_F_INGRESS = (1ULL << 0),
+};
+enum {
+  BPF_F_TUNINFO_IPV6 = (1ULL << 0),
+};
+enum {
+  BPF_F_SKIP_FIELD_MASK = 0xffULL,
+  BPF_F_USER_STACK = (1ULL << 8),
+  BPF_F_FAST_STACK_CMP = (1ULL << 9),
+  BPF_F_REUSE_STACKID = (1ULL << 10),
+  BPF_F_USER_BUILD_ID = (1ULL << 11),
+};
+enum {
+  BPF_F_ZERO_CSUM_TX = (1ULL << 1),
+  BPF_F_DONT_FRAGMENT = (1ULL << 2),
+  BPF_F_SEQ_NUMBER = (1ULL << 3),
+};
+enum {
+  BPF_F_INDEX_MASK = 0xffffffffULL,
+  BPF_F_CURRENT_CPU = BPF_F_INDEX_MASK,
+  BPF_F_CTXLEN_MASK = (0xfffffULL << 32),
+};
+enum {
+  BPF_F_CURRENT_NETNS = (- 1L),
+};
+enum {
+  BPF_CSUM_LEVEL_QUERY,
+  BPF_CSUM_LEVEL_INC,
+  BPF_CSUM_LEVEL_DEC,
+  BPF_CSUM_LEVEL_RESET,
+};
+enum {
+  BPF_F_ADJ_ROOM_FIXED_GSO = (1ULL << 0),
+  BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 = (1ULL << 1),
+  BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 = (1ULL << 2),
+  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),
+};
+enum {
+  BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff,
+  BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 56,
+};
 #define BPF_F_ADJ_ROOM_ENCAP_L2(len) (((__u64) len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
-#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0)
-#define BPF_SK_STORAGE_GET_F_CREATE (1ULL << 0)
+enum {
+  BPF_F_SYSCTL_BASE_NAME = (1ULL << 0),
+};
+enum {
+  BPF_SK_STORAGE_GET_F_CREATE = (1ULL << 0),
+};
+enum {
+  BPF_F_GET_BRANCH_RECORDS_SIZE = (1ULL << 0),
+};
+enum {
+  BPF_RB_NO_WAKEUP = (1ULL << 0),
+  BPF_RB_FORCE_WAKEUP = (1ULL << 1),
+};
+enum {
+  BPF_RB_AVAIL_DATA = 0,
+  BPF_RB_RING_SIZE = 1,
+  BPF_RB_CONS_POS = 2,
+  BPF_RB_PROD_POS = 3,
+};
+enum {
+  BPF_RINGBUF_BUSY_BIT = (1U << 31),
+  BPF_RINGBUF_DISCARD_BIT = (1U << 30),
+  BPF_RINGBUF_HDR_SZ = 8,
+};
 enum bpf_adj_room_mode {
   BPF_ADJ_ROOM_NET,
   BPF_ADJ_ROOM_MAC,
@@ -424,6 +547,7 @@
   __u32 wire_len;
   __u32 gso_segs;
   __bpf_md_ptr(struct bpf_sock *, sk);
+  __u32 gso_size;
 };
 struct bpf_tunnel_key {
   __u32 tunnel_id;
@@ -466,6 +590,7 @@
   __u32 dst_ip4;
   __u32 dst_ip6[4];
   __u32 state;
+  __s32 rx_queue_mapping;
 };
 struct bpf_tcp_sock {
   __u32 snd_cwnd;
@@ -528,6 +653,14 @@
   __u32 data_meta;
   __u32 ingress_ifindex;
   __u32 rx_queue_index;
+  __u32 egress_ifindex;
+};
+struct bpf_devmap_val {
+  __u32 ifindex;
+  union {
+    int fd;
+    __u32 id;
+  } bpf_prog;
 };
 enum sk_action {
   SK_DROP = 0,
@@ -544,6 +677,7 @@
   __u32 remote_port;
   __u32 local_port;
   __u32 size;
+  __bpf_md_ptr(struct bpf_sock *, sk);
 };
 struct sk_reuseport_md {
   __bpf_md_ptr(void *, data);
@@ -601,7 +735,7 @@
   __u32 map_flags;
   char name[BPF_OBJ_NAME_LEN];
   __u32 ifindex;
-  __u32 : 32;
+  __u32 btf_vmlinux_value_type_id;
   __u64 netns_dev;
   __u64 netns_ino;
   __u32 btf_id;
@@ -613,6 +747,28 @@
   __u32 btf_size;
   __u32 id;
 } __attribute__((aligned(8)));
+struct bpf_link_info {
+  __u32 type;
+  __u32 id;
+  __u32 prog_id;
+  union {
+    struct {
+      __aligned_u64 tp_name;
+      __u32 tp_name_len;
+    } raw_tracepoint;
+    struct {
+      __u32 attach_type;
+    } tracing;
+    struct {
+      __u64 cgroup_id;
+      __u32 attach_type;
+    } cgroup;
+    struct {
+      __u32 netns_ino;
+      __u32 attach_type;
+    } netns;
+  };
+} __attribute__((aligned(8)));
 struct bpf_sock_addr {
   __u32 user_family;
   __u32 user_ip4;
@@ -667,11 +823,13 @@
   __u64 bytes_acked;
   __bpf_md_ptr(struct bpf_sock *, sk);
 };
-#define BPF_SOCK_OPS_RTO_CB_FLAG (1 << 0)
-#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1 << 1)
-#define BPF_SOCK_OPS_STATE_CB_FLAG (1 << 2)
-#define BPF_SOCK_OPS_RTT_CB_FLAG (1 << 3)
-#define BPF_SOCK_OPS_ALL_CB_FLAGS 0xF
+enum {
+  BPF_SOCK_OPS_RTO_CB_FLAG = (1 << 0),
+  BPF_SOCK_OPS_RETRANS_CB_FLAG = (1 << 1),
+  BPF_SOCK_OPS_STATE_CB_FLAG = (1 << 2),
+  BPF_SOCK_OPS_RTT_CB_FLAG = (1 << 3),
+  BPF_SOCK_OPS_ALL_CB_FLAGS = 0xF,
+};
 enum {
   BPF_SOCK_OPS_VOID,
   BPF_SOCK_OPS_TIMEOUT_INIT,
@@ -702,18 +860,24 @@
   BPF_TCP_NEW_SYN_RECV,
   BPF_TCP_MAX_STATES
 };
-#define TCP_BPF_IW 1001
-#define TCP_BPF_SNDCWND_CLAMP 1002
+enum {
+  TCP_BPF_IW = 1001,
+  TCP_BPF_SNDCWND_CLAMP = 1002,
+};
 struct bpf_perf_event_value {
   __u64 counter;
   __u64 enabled;
   __u64 running;
 };
-#define BPF_DEVCG_ACC_MKNOD (1ULL << 0)
-#define BPF_DEVCG_ACC_READ (1ULL << 1)
-#define BPF_DEVCG_ACC_WRITE (1ULL << 2)
-#define BPF_DEVCG_DEV_BLOCK (1ULL << 0)
-#define BPF_DEVCG_DEV_CHAR (1ULL << 1)
+enum {
+  BPF_DEVCG_ACC_MKNOD = (1ULL << 0),
+  BPF_DEVCG_ACC_READ = (1ULL << 1),
+  BPF_DEVCG_ACC_WRITE = (1ULL << 2),
+};
+enum {
+  BPF_DEVCG_DEV_BLOCK = (1ULL << 0),
+  BPF_DEVCG_DEV_CHAR = (1ULL << 1),
+};
 struct bpf_cgroup_dev_ctx {
   __u32 access_type;
   __u32 major;
@@ -722,8 +886,10 @@
 struct bpf_raw_tracepoint_args {
   __u64 args[0];
 };
-#define BPF_FIB_LOOKUP_DIRECT (1U << 0)
-#define BPF_FIB_LOOKUP_OUTPUT (1U << 1)
+enum {
+  BPF_FIB_LOOKUP_DIRECT = (1U << 0),
+  BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
+};
 enum {
   BPF_FIB_LKUP_RET_SUCCESS,
   BPF_FIB_LKUP_RET_BLACKHOLE,
@@ -768,9 +934,11 @@
   BPF_FD_TYPE_UPROBE,
   BPF_FD_TYPE_URETPROBE,
 };
-#define BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG (1U << 0)
-#define BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL (1U << 1)
-#define BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP (1U << 2)
+enum {
+  BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = (1U << 0),
+  BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = (1U << 1),
+  BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = (1U << 2),
+};
 struct bpf_flow_keys {
   __u16 nhoff;
   __u16 thoff;
@@ -823,4 +991,8 @@
   __s32 optlen;
   __s32 retval;
 };
+struct bpf_pidns_info {
+  __u32 pid;
+  __u32 tgid;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/btf.h b/libc/kernel/uapi/linux/btf.h
index 21e7596..f22d637 100644
--- a/libc/kernel/uapi/linux/btf.h
+++ b/libc/kernel/uapi/linux/btf.h
@@ -91,7 +91,13 @@
 };
 enum {
   BTF_VAR_STATIC = 0,
-  BTF_VAR_GLOBAL_ALLOCATED,
+  BTF_VAR_GLOBAL_ALLOCATED = 1,
+  BTF_VAR_GLOBAL_EXTERN = 2,
+};
+enum btf_func_linkage {
+  BTF_FUNC_STATIC = 0,
+  BTF_FUNC_GLOBAL = 1,
+  BTF_FUNC_EXTERN = 2,
 };
 struct btf_var {
   __u32 linkage;
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 684b295..45e5572 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -34,7 +34,8 @@
 #define BTRFS_SUBVOL_RDONLY (1ULL << 1)
 #define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2)
 #define BTRFS_DEVICE_SPEC_BY_ID (1ULL << 3)
-#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED (BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY | BTRFS_SUBVOL_QGROUP_INHERIT | BTRFS_DEVICE_SPEC_BY_ID)
+#define BTRFS_SUBVOL_SPEC_BY_ID (1ULL << 4)
+#define BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED (BTRFS_SUBVOL_RDONLY | BTRFS_SUBVOL_QGROUP_INHERIT | BTRFS_DEVICE_SPEC_BY_ID | BTRFS_SUBVOL_SPEC_BY_ID)
 #define BTRFS_FSID_SIZE 16
 #define BTRFS_UUID_SIZE 16
 #define BTRFS_UUID_UNPARSED_SIZE 37
@@ -64,6 +65,9 @@
   __u64 qgroupid;
   struct btrfs_qgroup_limit lim;
 };
+#define BTRFS_DEVICE_REMOVE_ARGS_MASK (BTRFS_DEVICE_SPEC_BY_ID)
+#define BTRFS_SUBVOL_CREATE_ARGS_MASK (BTRFS_SUBVOL_RDONLY | BTRFS_SUBVOL_QGROUP_INHERIT)
+#define BTRFS_SUBVOL_DELETE_ARGS_MASK (BTRFS_SUBVOL_SPEC_BY_ID)
 struct btrfs_ioctl_vol_args_v2 {
   __s64 fd;
   __u64 transid;
@@ -78,6 +82,7 @@
   union {
     char name[BTRFS_SUBVOL_NAME_MAX + 1];
     __u64 devid;
+    __u64 subvolid;
   };
 };
 struct btrfs_scrub_progress {
@@ -517,4 +522,5 @@
 #define BTRFS_IOC_GET_SUBVOL_INFO _IOR(BTRFS_IOCTL_MAGIC, 60, struct btrfs_ioctl_get_subvol_info_args)
 #define BTRFS_IOC_GET_SUBVOL_ROOTREF _IOWR(BTRFS_IOCTL_MAGIC, 61, struct btrfs_ioctl_get_subvol_rootref_args)
 #define BTRFS_IOC_INO_LOOKUP_USER _IOWR(BTRFS_IOCTL_MAGIC, 62, struct btrfs_ioctl_ino_lookup_user_args)
+#define BTRFS_IOC_SNAP_DESTROY_V2 _IOW(BTRFS_IOCTL_MAGIC, 63, struct btrfs_ioctl_vol_args_v2)
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index 50ada36..6049127 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -201,12 +201,6 @@
   __u8 type;
   __le64 offset;
 } __attribute__((__packed__));
-struct btrfs_extent_ref_v0 {
-  __le64 root;
-  __le64 generation;
-  __le64 objectid;
-  __le32 count;
-} __attribute__((__packed__));
 struct btrfs_dev_extent {
   __le64 chunk_tree;
   __le64 chunk_objectid;
diff --git a/libc/kernel/uapi/linux/capability.h b/libc/kernel/uapi/linux/capability.h
index 8ba448e..b830fd6 100644
--- a/libc/kernel/uapi/linux/capability.h
+++ b/libc/kernel/uapi/linux/capability.h
@@ -105,7 +105,9 @@
 #define CAP_WAKE_ALARM 35
 #define CAP_BLOCK_SUSPEND 36
 #define CAP_AUDIT_READ 37
-#define CAP_LAST_CAP CAP_AUDIT_READ
+#define CAP_PERFMON 38
+#define CAP_BPF 39
+#define CAP_LAST_CAP CAP_BPF
 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
 #define CAP_TO_INDEX(x) ((x) >> 5)
 #define CAP_TO_MASK(x) (1 << ((x) & 31))
diff --git a/libc/kernel/uapi/linux/coresight-stm.h b/libc/kernel/uapi/linux/coresight-stm.h
index 2eac7e1..9d89dd6 100644
--- a/libc/kernel/uapi/linux/coresight-stm.h
+++ b/libc/kernel/uapi/linux/coresight-stm.h
@@ -18,8 +18,9 @@
  ****************************************************************************/
 #ifndef __UAPI_CORESIGHT_STM_H_
 #define __UAPI_CORESIGHT_STM_H_
-#define STM_FLAG_TIMESTAMPED BIT(3)
-#define STM_FLAG_GUARANTEED BIT(7)
+#include <linux/const.h>
+#define STM_FLAG_TIMESTAMPED _BITUL(3)
+#define STM_FLAG_GUARANTEED _BITUL(7)
 enum {
   STM_OPTION_GUARANTEED = 0,
   STM_OPTION_INVARIANT,
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index b08fa8a..7730a45 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -93,6 +93,10 @@
   DEVLINK_CMD_TRAP_GROUP_SET,
   DEVLINK_CMD_TRAP_GROUP_NEW,
   DEVLINK_CMD_TRAP_GROUP_DEL,
+  DEVLINK_CMD_TRAP_POLICER_GET,
+  DEVLINK_CMD_TRAP_POLICER_SET,
+  DEVLINK_CMD_TRAP_POLICER_NEW,
+  DEVLINK_CMD_TRAP_POLICER_DEL,
   __DEVLINK_CMD_MAX,
   DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
 };
@@ -131,6 +135,7 @@
   DEVLINK_PORT_FLAVOUR_DSA,
   DEVLINK_PORT_FLAVOUR_PCI_PF,
   DEVLINK_PORT_FLAVOUR_PCI_VF,
+  DEVLINK_PORT_FLAVOUR_VIRTUAL,
 };
 enum devlink_param_cmode {
   DEVLINK_PARAM_CMODE_RUNTIME,
@@ -154,19 +159,23 @@
 enum {
   DEVLINK_ATTR_STATS_RX_PACKETS,
   DEVLINK_ATTR_STATS_RX_BYTES,
+  DEVLINK_ATTR_STATS_RX_DROPPED,
   __DEVLINK_ATTR_STATS_MAX,
   DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
 };
 enum devlink_trap_action {
   DEVLINK_TRAP_ACTION_DROP,
   DEVLINK_TRAP_ACTION_TRAP,
+  DEVLINK_TRAP_ACTION_MIRROR,
 };
 enum devlink_trap_type {
   DEVLINK_TRAP_TYPE_DROP,
   DEVLINK_TRAP_TYPE_EXCEPTION,
+  DEVLINK_TRAP_TYPE_CONTROL,
 };
 enum {
   DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT,
+  DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE,
 };
 enum devlink_attr {
   DEVLINK_ATTR_UNSPEC,
@@ -310,6 +319,10 @@
   DEVLINK_ATTR_NETNS_FD,
   DEVLINK_ATTR_NETNS_PID,
   DEVLINK_ATTR_NETNS_ID,
+  DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
+  DEVLINK_ATTR_TRAP_POLICER_ID,
+  DEVLINK_ATTR_TRAP_POLICER_RATE,
+  DEVLINK_ATTR_TRAP_POLICER_BURST,
   __DEVLINK_ATTR_MAX,
   DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index 51e997f..130c4c7 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -104,9 +104,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 41
+#define DM_VERSION_MINOR 42
 #define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2019-09-16)"
+#define DM_VERSION_EXTRA "-ioctl(2020-02-27)"
 #define DM_READONLY_FLAG (1 << 0)
 #define DM_SUSPEND_FLAG (1 << 1)
 #define DM_PERSISTENT_DEV_FLAG (1 << 3)
diff --git a/libc/kernel/uapi/linux/dma-buf.h b/libc/kernel/uapi/linux/dma-buf.h
index 3d7c099..221c20f 100644
--- a/libc/kernel/uapi/linux/dma-buf.h
+++ b/libc/kernel/uapi/linux/dma-buf.h
@@ -32,4 +32,6 @@
 #define DMA_BUF_BASE 'b'
 #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
 #define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
+#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32)
+#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64)
 #endif
diff --git a/libc/kernel/uapi/linux/gigaset_dev.h b/libc/kernel/uapi/linux/dma-heap.h
similarity index 70%
rename from libc/kernel/uapi/linux/gigaset_dev.h
rename to libc/kernel/uapi/linux/dma-heap.h
index 5741d7d..a2746e3 100644
--- a/libc/kernel/uapi/linux/gigaset_dev.h
+++ b/libc/kernel/uapi/linux/dma-heap.h
@@ -16,15 +16,18 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef GIGASET_INTERFACE_H
-#define GIGASET_INTERFACE_H
+#ifndef _UAPI_LINUX_DMABUF_POOL_H
+#define _UAPI_LINUX_DMABUF_POOL_H
 #include <linux/ioctl.h>
-#define GIGASET_IOCTL 0x47
-#define GIGASET_REDIR _IOWR(GIGASET_IOCTL, 0, int)
-#define GIGASET_CONFIG _IOWR(GIGASET_IOCTL, 1, int)
-#define GIGASET_BRKCHARS _IOW(GIGASET_IOCTL, 2, unsigned char[6])
-#define GIGASET_VERSION _IOWR(GIGASET_IOCTL, 3, unsigned[4])
-#define GIGVER_DRIVER 0
-#define GIGVER_COMPAT 1
-#define GIGVER_FWBASE 2
+#include <linux/types.h>
+#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE)
+#define DMA_HEAP_VALID_HEAP_FLAGS (0)
+struct dma_heap_allocation_data {
+  __u64 len;
+  __u32 fd;
+  __u32 fd_flags;
+  __u64 heap_flags;
+};
+#define DMA_HEAP_IOC_MAGIC 'H'
+#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0, struct dma_heap_allocation_data)
 #endif
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 8f2e668..428da63 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -46,6 +46,7 @@
 #define PT_LOPROC 0x70000000
 #define PT_HIPROC 0x7fffffff
 #define PT_GNU_EH_FRAME 0x6474e550
+#define PT_GNU_PROPERTY 0x6474e553
 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
 #define PN_XNUM 0xffff
 #define ET_NONE 0
@@ -363,6 +364,7 @@
 #define NT_MIPS_DSP 0x800
 #define NT_MIPS_FP_MODE 0x801
 #define NT_MIPS_MSA 0x802
+#define NT_GNU_PROPERTY_TYPE_0 5
 typedef struct elf32_note {
   Elf32_Word n_namesz;
   Elf32_Word n_descsz;
@@ -373,4 +375,6 @@
   Elf64_Word n_descsz;
   Elf64_Word n_type;
 } Elf64_Nhdr;
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0)
 #endif
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index cc951d1..9f8678a 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -207,6 +207,13 @@
   ETH_SS_TUNABLES,
   ETH_SS_PHY_STATS,
   ETH_SS_PHY_TUNABLES,
+  ETH_SS_LINK_MODES,
+  ETH_SS_MSG_CLASSES,
+  ETH_SS_WOL_MODES,
+  ETH_SS_SOF_TIMESTAMPING,
+  ETH_SS_TS_TX_TYPES,
+  ETH_SS_TS_RX_FILTERS,
+  ETH_SS_COUNT
 };
 struct ethtool_gstrings {
   __u32 cmd;
@@ -452,12 +459,14 @@
   ETHTOOL_FEC_OFF_BIT,
   ETHTOOL_FEC_RS_BIT,
   ETHTOOL_FEC_BASER_BIT,
+  ETHTOOL_FEC_LLRS_BIT,
 };
 #define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT)
 #define ETHTOOL_FEC_AUTO (1 << ETHTOOL_FEC_AUTO_BIT)
 #define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT)
 #define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT)
 #define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT)
+#define ETHTOOL_FEC_LLRS (1 << ETHTOOL_FEC_LLRS_BIT)
 #define ETHTOOL_GSET 0x00000001
 #define ETHTOOL_SSET 0x00000002
 #define ETHTOOL_GDRVINFO 0x00000003
@@ -615,6 +624,7 @@
   ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 71,
   ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT = 72,
   ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT = 73,
+  ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 74,
   __ETHTOOL_LINK_MODE_MASK_NBITS
 };
 #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) (1UL << (ETHTOOL_LINK_MODE_ ##base_name ##_BIT))
@@ -699,6 +709,17 @@
 #define DUPLEX_HALF 0x00
 #define DUPLEX_FULL 0x01
 #define DUPLEX_UNKNOWN 0xff
+#define MASTER_SLAVE_CFG_UNSUPPORTED 0
+#define MASTER_SLAVE_CFG_UNKNOWN 1
+#define MASTER_SLAVE_CFG_MASTER_PREFERRED 2
+#define MASTER_SLAVE_CFG_SLAVE_PREFERRED 3
+#define MASTER_SLAVE_CFG_MASTER_FORCE 4
+#define MASTER_SLAVE_CFG_SLAVE_FORCE 5
+#define MASTER_SLAVE_STATE_UNSUPPORTED 0
+#define MASTER_SLAVE_STATE_UNKNOWN 1
+#define MASTER_SLAVE_STATE_MASTER 2
+#define MASTER_SLAVE_STATE_SLAVE 3
+#define MASTER_SLAVE_STATE_ERR 4
 #define PORT_TP 0x00
 #define PORT_AUI 0x01
 #define PORT_MII 0x02
@@ -726,6 +747,7 @@
 #define WAKE_MAGIC (1 << 5)
 #define WAKE_MAGICSECURE (1 << 6)
 #define WAKE_FILTER (1 << 7)
+#define WOL_MODE_COUNT 8
 #define TCP_V4_FLOW 0x01
 #define UDP_V4_FLOW 0x02
 #define SCTP_V4_FLOW 0x03
@@ -797,7 +819,9 @@
   __u8 eth_tp_mdix_ctrl;
   __s8 link_mode_masks_nwords;
   __u8 transceiver;
-  __u8 reserved1[3];
+  __u8 master_slave_cfg;
+  __u8 master_slave_state;
+  __u8 reserved1[1];
   __u32 reserved[7];
   __u32 link_mode_masks[0];
 };
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
new file mode 100644
index 0000000..868d3c6
--- /dev/null
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -0,0 +1,418 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_ETHTOOL_NETLINK_H_
+#define _UAPI_LINUX_ETHTOOL_NETLINK_H_
+#include <linux/ethtool.h>
+enum {
+  ETHTOOL_MSG_USER_NONE,
+  ETHTOOL_MSG_STRSET_GET,
+  ETHTOOL_MSG_LINKINFO_GET,
+  ETHTOOL_MSG_LINKINFO_SET,
+  ETHTOOL_MSG_LINKMODES_GET,
+  ETHTOOL_MSG_LINKMODES_SET,
+  ETHTOOL_MSG_LINKSTATE_GET,
+  ETHTOOL_MSG_DEBUG_GET,
+  ETHTOOL_MSG_DEBUG_SET,
+  ETHTOOL_MSG_WOL_GET,
+  ETHTOOL_MSG_WOL_SET,
+  ETHTOOL_MSG_FEATURES_GET,
+  ETHTOOL_MSG_FEATURES_SET,
+  ETHTOOL_MSG_PRIVFLAGS_GET,
+  ETHTOOL_MSG_PRIVFLAGS_SET,
+  ETHTOOL_MSG_RINGS_GET,
+  ETHTOOL_MSG_RINGS_SET,
+  ETHTOOL_MSG_CHANNELS_GET,
+  ETHTOOL_MSG_CHANNELS_SET,
+  ETHTOOL_MSG_COALESCE_GET,
+  ETHTOOL_MSG_COALESCE_SET,
+  ETHTOOL_MSG_PAUSE_GET,
+  ETHTOOL_MSG_PAUSE_SET,
+  ETHTOOL_MSG_EEE_GET,
+  ETHTOOL_MSG_EEE_SET,
+  ETHTOOL_MSG_TSINFO_GET,
+  ETHTOOL_MSG_CABLE_TEST_ACT,
+  ETHTOOL_MSG_CABLE_TEST_TDR_ACT,
+  __ETHTOOL_MSG_USER_CNT,
+  ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1
+};
+enum {
+  ETHTOOL_MSG_KERNEL_NONE,
+  ETHTOOL_MSG_STRSET_GET_REPLY,
+  ETHTOOL_MSG_LINKINFO_GET_REPLY,
+  ETHTOOL_MSG_LINKINFO_NTF,
+  ETHTOOL_MSG_LINKMODES_GET_REPLY,
+  ETHTOOL_MSG_LINKMODES_NTF,
+  ETHTOOL_MSG_LINKSTATE_GET_REPLY,
+  ETHTOOL_MSG_DEBUG_GET_REPLY,
+  ETHTOOL_MSG_DEBUG_NTF,
+  ETHTOOL_MSG_WOL_GET_REPLY,
+  ETHTOOL_MSG_WOL_NTF,
+  ETHTOOL_MSG_FEATURES_GET_REPLY,
+  ETHTOOL_MSG_FEATURES_SET_REPLY,
+  ETHTOOL_MSG_FEATURES_NTF,
+  ETHTOOL_MSG_PRIVFLAGS_GET_REPLY,
+  ETHTOOL_MSG_PRIVFLAGS_NTF,
+  ETHTOOL_MSG_RINGS_GET_REPLY,
+  ETHTOOL_MSG_RINGS_NTF,
+  ETHTOOL_MSG_CHANNELS_GET_REPLY,
+  ETHTOOL_MSG_CHANNELS_NTF,
+  ETHTOOL_MSG_COALESCE_GET_REPLY,
+  ETHTOOL_MSG_COALESCE_NTF,
+  ETHTOOL_MSG_PAUSE_GET_REPLY,
+  ETHTOOL_MSG_PAUSE_NTF,
+  ETHTOOL_MSG_EEE_GET_REPLY,
+  ETHTOOL_MSG_EEE_NTF,
+  ETHTOOL_MSG_TSINFO_GET_REPLY,
+  ETHTOOL_MSG_CABLE_TEST_NTF,
+  ETHTOOL_MSG_CABLE_TEST_TDR_NTF,
+  __ETHTOOL_MSG_KERNEL_CNT,
+  ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1
+};
+#define ETHTOOL_FLAG_COMPACT_BITSETS (1 << 0)
+#define ETHTOOL_FLAG_OMIT_REPLY (1 << 1)
+#define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | ETHTOOL_FLAG_OMIT_REPLY)
+enum {
+  ETHTOOL_A_HEADER_UNSPEC,
+  ETHTOOL_A_HEADER_DEV_INDEX,
+  ETHTOOL_A_HEADER_DEV_NAME,
+  ETHTOOL_A_HEADER_FLAGS,
+  __ETHTOOL_A_HEADER_CNT,
+  ETHTOOL_A_HEADER_MAX = __ETHTOOL_A_HEADER_CNT - 1
+};
+enum {
+  ETHTOOL_A_BITSET_BIT_UNSPEC,
+  ETHTOOL_A_BITSET_BIT_INDEX,
+  ETHTOOL_A_BITSET_BIT_NAME,
+  ETHTOOL_A_BITSET_BIT_VALUE,
+  __ETHTOOL_A_BITSET_BIT_CNT,
+  ETHTOOL_A_BITSET_BIT_MAX = __ETHTOOL_A_BITSET_BIT_CNT - 1
+};
+enum {
+  ETHTOOL_A_BITSET_BITS_UNSPEC,
+  ETHTOOL_A_BITSET_BITS_BIT,
+  __ETHTOOL_A_BITSET_BITS_CNT,
+  ETHTOOL_A_BITSET_BITS_MAX = __ETHTOOL_A_BITSET_BITS_CNT - 1
+};
+enum {
+  ETHTOOL_A_BITSET_UNSPEC,
+  ETHTOOL_A_BITSET_NOMASK,
+  ETHTOOL_A_BITSET_SIZE,
+  ETHTOOL_A_BITSET_BITS,
+  ETHTOOL_A_BITSET_VALUE,
+  ETHTOOL_A_BITSET_MASK,
+  __ETHTOOL_A_BITSET_CNT,
+  ETHTOOL_A_BITSET_MAX = __ETHTOOL_A_BITSET_CNT - 1
+};
+enum {
+  ETHTOOL_A_STRING_UNSPEC,
+  ETHTOOL_A_STRING_INDEX,
+  ETHTOOL_A_STRING_VALUE,
+  __ETHTOOL_A_STRING_CNT,
+  ETHTOOL_A_STRING_MAX = __ETHTOOL_A_STRING_CNT - 1
+};
+enum {
+  ETHTOOL_A_STRINGS_UNSPEC,
+  ETHTOOL_A_STRINGS_STRING,
+  __ETHTOOL_A_STRINGS_CNT,
+  ETHTOOL_A_STRINGS_MAX = __ETHTOOL_A_STRINGS_CNT - 1
+};
+enum {
+  ETHTOOL_A_STRINGSET_UNSPEC,
+  ETHTOOL_A_STRINGSET_ID,
+  ETHTOOL_A_STRINGSET_COUNT,
+  ETHTOOL_A_STRINGSET_STRINGS,
+  __ETHTOOL_A_STRINGSET_CNT,
+  ETHTOOL_A_STRINGSET_MAX = __ETHTOOL_A_STRINGSET_CNT - 1
+};
+enum {
+  ETHTOOL_A_STRINGSETS_UNSPEC,
+  ETHTOOL_A_STRINGSETS_STRINGSET,
+  __ETHTOOL_A_STRINGSETS_CNT,
+  ETHTOOL_A_STRINGSETS_MAX = __ETHTOOL_A_STRINGSETS_CNT - 1
+};
+enum {
+  ETHTOOL_A_STRSET_UNSPEC,
+  ETHTOOL_A_STRSET_HEADER,
+  ETHTOOL_A_STRSET_STRINGSETS,
+  ETHTOOL_A_STRSET_COUNTS_ONLY,
+  __ETHTOOL_A_STRSET_CNT,
+  ETHTOOL_A_STRSET_MAX = __ETHTOOL_A_STRSET_CNT - 1
+};
+enum {
+  ETHTOOL_A_LINKINFO_UNSPEC,
+  ETHTOOL_A_LINKINFO_HEADER,
+  ETHTOOL_A_LINKINFO_PORT,
+  ETHTOOL_A_LINKINFO_PHYADDR,
+  ETHTOOL_A_LINKINFO_TP_MDIX,
+  ETHTOOL_A_LINKINFO_TP_MDIX_CTRL,
+  ETHTOOL_A_LINKINFO_TRANSCEIVER,
+  __ETHTOOL_A_LINKINFO_CNT,
+  ETHTOOL_A_LINKINFO_MAX = __ETHTOOL_A_LINKINFO_CNT - 1
+};
+enum {
+  ETHTOOL_A_LINKMODES_UNSPEC,
+  ETHTOOL_A_LINKMODES_HEADER,
+  ETHTOOL_A_LINKMODES_AUTONEG,
+  ETHTOOL_A_LINKMODES_OURS,
+  ETHTOOL_A_LINKMODES_PEER,
+  ETHTOOL_A_LINKMODES_SPEED,
+  ETHTOOL_A_LINKMODES_DUPLEX,
+  ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG,
+  ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE,
+  __ETHTOOL_A_LINKMODES_CNT,
+  ETHTOOL_A_LINKMODES_MAX = __ETHTOOL_A_LINKMODES_CNT - 1
+};
+enum {
+  ETHTOOL_A_LINKSTATE_UNSPEC,
+  ETHTOOL_A_LINKSTATE_HEADER,
+  ETHTOOL_A_LINKSTATE_LINK,
+  ETHTOOL_A_LINKSTATE_SQI,
+  ETHTOOL_A_LINKSTATE_SQI_MAX,
+  __ETHTOOL_A_LINKSTATE_CNT,
+  ETHTOOL_A_LINKSTATE_MAX = __ETHTOOL_A_LINKSTATE_CNT - 1
+};
+enum {
+  ETHTOOL_A_DEBUG_UNSPEC,
+  ETHTOOL_A_DEBUG_HEADER,
+  ETHTOOL_A_DEBUG_MSGMASK,
+  __ETHTOOL_A_DEBUG_CNT,
+  ETHTOOL_A_DEBUG_MAX = __ETHTOOL_A_DEBUG_CNT - 1
+};
+enum {
+  ETHTOOL_A_WOL_UNSPEC,
+  ETHTOOL_A_WOL_HEADER,
+  ETHTOOL_A_WOL_MODES,
+  ETHTOOL_A_WOL_SOPASS,
+  __ETHTOOL_A_WOL_CNT,
+  ETHTOOL_A_WOL_MAX = __ETHTOOL_A_WOL_CNT - 1
+};
+enum {
+  ETHTOOL_A_FEATURES_UNSPEC,
+  ETHTOOL_A_FEATURES_HEADER,
+  ETHTOOL_A_FEATURES_HW,
+  ETHTOOL_A_FEATURES_WANTED,
+  ETHTOOL_A_FEATURES_ACTIVE,
+  ETHTOOL_A_FEATURES_NOCHANGE,
+  __ETHTOOL_A_FEATURES_CNT,
+  ETHTOOL_A_FEATURES_MAX = __ETHTOOL_A_FEATURES_CNT - 1
+};
+enum {
+  ETHTOOL_A_PRIVFLAGS_UNSPEC,
+  ETHTOOL_A_PRIVFLAGS_HEADER,
+  ETHTOOL_A_PRIVFLAGS_FLAGS,
+  __ETHTOOL_A_PRIVFLAGS_CNT,
+  ETHTOOL_A_PRIVFLAGS_MAX = __ETHTOOL_A_PRIVFLAGS_CNT - 1
+};
+enum {
+  ETHTOOL_A_RINGS_UNSPEC,
+  ETHTOOL_A_RINGS_HEADER,
+  ETHTOOL_A_RINGS_RX_MAX,
+  ETHTOOL_A_RINGS_RX_MINI_MAX,
+  ETHTOOL_A_RINGS_RX_JUMBO_MAX,
+  ETHTOOL_A_RINGS_TX_MAX,
+  ETHTOOL_A_RINGS_RX,
+  ETHTOOL_A_RINGS_RX_MINI,
+  ETHTOOL_A_RINGS_RX_JUMBO,
+  ETHTOOL_A_RINGS_TX,
+  __ETHTOOL_A_RINGS_CNT,
+  ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CHANNELS_UNSPEC,
+  ETHTOOL_A_CHANNELS_HEADER,
+  ETHTOOL_A_CHANNELS_RX_MAX,
+  ETHTOOL_A_CHANNELS_TX_MAX,
+  ETHTOOL_A_CHANNELS_OTHER_MAX,
+  ETHTOOL_A_CHANNELS_COMBINED_MAX,
+  ETHTOOL_A_CHANNELS_RX_COUNT,
+  ETHTOOL_A_CHANNELS_TX_COUNT,
+  ETHTOOL_A_CHANNELS_OTHER_COUNT,
+  ETHTOOL_A_CHANNELS_COMBINED_COUNT,
+  __ETHTOOL_A_CHANNELS_CNT,
+  ETHTOOL_A_CHANNELS_MAX = (__ETHTOOL_A_CHANNELS_CNT - 1)
+};
+enum {
+  ETHTOOL_A_COALESCE_UNSPEC,
+  ETHTOOL_A_COALESCE_HEADER,
+  ETHTOOL_A_COALESCE_RX_USECS,
+  ETHTOOL_A_COALESCE_RX_MAX_FRAMES,
+  ETHTOOL_A_COALESCE_RX_USECS_IRQ,
+  ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ,
+  ETHTOOL_A_COALESCE_TX_USECS,
+  ETHTOOL_A_COALESCE_TX_MAX_FRAMES,
+  ETHTOOL_A_COALESCE_TX_USECS_IRQ,
+  ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ,
+  ETHTOOL_A_COALESCE_STATS_BLOCK_USECS,
+  ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX,
+  ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX,
+  ETHTOOL_A_COALESCE_PKT_RATE_LOW,
+  ETHTOOL_A_COALESCE_RX_USECS_LOW,
+  ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW,
+  ETHTOOL_A_COALESCE_TX_USECS_LOW,
+  ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW,
+  ETHTOOL_A_COALESCE_PKT_RATE_HIGH,
+  ETHTOOL_A_COALESCE_RX_USECS_HIGH,
+  ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH,
+  ETHTOOL_A_COALESCE_TX_USECS_HIGH,
+  ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH,
+  ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL,
+  __ETHTOOL_A_COALESCE_CNT,
+  ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1)
+};
+enum {
+  ETHTOOL_A_PAUSE_UNSPEC,
+  ETHTOOL_A_PAUSE_HEADER,
+  ETHTOOL_A_PAUSE_AUTONEG,
+  ETHTOOL_A_PAUSE_RX,
+  ETHTOOL_A_PAUSE_TX,
+  __ETHTOOL_A_PAUSE_CNT,
+  ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1)
+};
+enum {
+  ETHTOOL_A_EEE_UNSPEC,
+  ETHTOOL_A_EEE_HEADER,
+  ETHTOOL_A_EEE_MODES_OURS,
+  ETHTOOL_A_EEE_MODES_PEER,
+  ETHTOOL_A_EEE_ACTIVE,
+  ETHTOOL_A_EEE_ENABLED,
+  ETHTOOL_A_EEE_TX_LPI_ENABLED,
+  ETHTOOL_A_EEE_TX_LPI_TIMER,
+  __ETHTOOL_A_EEE_CNT,
+  ETHTOOL_A_EEE_MAX = (__ETHTOOL_A_EEE_CNT - 1)
+};
+enum {
+  ETHTOOL_A_TSINFO_UNSPEC,
+  ETHTOOL_A_TSINFO_HEADER,
+  ETHTOOL_A_TSINFO_TIMESTAMPING,
+  ETHTOOL_A_TSINFO_TX_TYPES,
+  ETHTOOL_A_TSINFO_RX_FILTERS,
+  ETHTOOL_A_TSINFO_PHC_INDEX,
+  __ETHTOOL_A_TSINFO_CNT,
+  ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_TEST_UNSPEC,
+  ETHTOOL_A_CABLE_TEST_HEADER,
+  __ETHTOOL_A_CABLE_TEST_CNT,
+  ETHTOOL_A_CABLE_TEST_MAX = __ETHTOOL_A_CABLE_TEST_CNT - 1
+};
+enum {
+  ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC,
+  ETHTOOL_A_CABLE_RESULT_CODE_OK,
+  ETHTOOL_A_CABLE_RESULT_CODE_OPEN,
+  ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT,
+  ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT,
+};
+enum {
+  ETHTOOL_A_CABLE_PAIR_A,
+  ETHTOOL_A_CABLE_PAIR_B,
+  ETHTOOL_A_CABLE_PAIR_C,
+  ETHTOOL_A_CABLE_PAIR_D,
+};
+enum {
+  ETHTOOL_A_CABLE_RESULT_UNSPEC,
+  ETHTOOL_A_CABLE_RESULT_PAIR,
+  ETHTOOL_A_CABLE_RESULT_CODE,
+  __ETHTOOL_A_CABLE_RESULT_CNT,
+  ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC,
+  ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR,
+  ETHTOOL_A_CABLE_FAULT_LENGTH_CM,
+  __ETHTOOL_A_CABLE_FAULT_LENGTH_CNT,
+  ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC,
+  ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED,
+  ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED
+};
+enum {
+  ETHTOOL_A_CABLE_NEST_UNSPEC,
+  ETHTOOL_A_CABLE_NEST_RESULT,
+  ETHTOOL_A_CABLE_NEST_FAULT_LENGTH,
+  __ETHTOOL_A_CABLE_NEST_CNT,
+  ETHTOOL_A_CABLE_NEST_MAX = (__ETHTOOL_A_CABLE_NEST_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_TEST_NTF_UNSPEC,
+  ETHTOOL_A_CABLE_TEST_NTF_HEADER,
+  ETHTOOL_A_CABLE_TEST_NTF_STATUS,
+  ETHTOOL_A_CABLE_TEST_NTF_NEST,
+  __ETHTOOL_A_CABLE_TEST_NTF_CNT,
+  ETHTOOL_A_CABLE_TEST_NTF_MAX = (__ETHTOOL_A_CABLE_TEST_NTF_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC,
+  ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST,
+  ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST,
+  ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP,
+  ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR,
+  __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT,
+  ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX = __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT - 1
+};
+enum {
+  ETHTOOL_A_CABLE_TEST_TDR_UNSPEC,
+  ETHTOOL_A_CABLE_TEST_TDR_HEADER,
+  ETHTOOL_A_CABLE_TEST_TDR_CFG,
+  __ETHTOOL_A_CABLE_TEST_TDR_CNT,
+  ETHTOOL_A_CABLE_TEST_TDR_MAX = __ETHTOOL_A_CABLE_TEST_TDR_CNT - 1
+};
+enum {
+  ETHTOOL_A_CABLE_AMPLITUDE_UNSPEC,
+  ETHTOOL_A_CABLE_AMPLITUDE_PAIR,
+  ETHTOOL_A_CABLE_AMPLITUDE_mV,
+  __ETHTOOL_A_CABLE_AMPLITUDE_CNT,
+  ETHTOOL_A_CABLE_AMPLITUDE_MAX = (__ETHTOOL_A_CABLE_AMPLITUDE_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_PULSE_UNSPEC,
+  ETHTOOL_A_CABLE_PULSE_mV,
+  __ETHTOOL_A_CABLE_PULSE_CNT,
+  ETHTOOL_A_CABLE_PULSE_MAX = (__ETHTOOL_A_CABLE_PULSE_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_STEP_UNSPEC,
+  ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE,
+  ETHTOOL_A_CABLE_STEP_LAST_DISTANCE,
+  ETHTOOL_A_CABLE_STEP_STEP_DISTANCE,
+  __ETHTOOL_A_CABLE_STEP_CNT,
+  ETHTOOL_A_CABLE_STEP_MAX = (__ETHTOOL_A_CABLE_STEP_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_TDR_NEST_UNSPEC,
+  ETHTOOL_A_CABLE_TDR_NEST_STEP,
+  ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE,
+  ETHTOOL_A_CABLE_TDR_NEST_PULSE,
+  __ETHTOOL_A_CABLE_TDR_NEST_CNT,
+  ETHTOOL_A_CABLE_TDR_NEST_MAX = (__ETHTOOL_A_CABLE_TDR_NEST_CNT - 1)
+};
+enum {
+  ETHTOOL_A_CABLE_TEST_TDR_NTF_UNSPEC,
+  ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER,
+  ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS,
+  ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST,
+  __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT,
+  ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1
+};
+#define ETHTOOL_GENL_NAME "ethtool"
+#define ETHTOOL_GENL_VERSION 1
+#define ETHTOOL_MCGRP_MONITOR_NAME "monitor"
+#endif
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index 8b4494f..8f9bea6 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -36,8 +36,9 @@
 #define FAN_OPEN_PERM 0x00010000
 #define FAN_ACCESS_PERM 0x00020000
 #define FAN_OPEN_EXEC_PERM 0x00040000
-#define FAN_ONDIR 0x40000000
+#define FAN_DIR_MODIFY 0x00080000
 #define FAN_EVENT_ON_CHILD 0x08000000
+#define FAN_ONDIR 0x40000000
 #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
 #define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO)
 #define FAN_CLOEXEC 0x00000001
@@ -77,6 +78,7 @@
   __s32 pid;
 };
 #define FAN_EVENT_INFO_TYPE_FID 1
+#define FAN_EVENT_INFO_TYPE_DFID_NAME 2
 struct fanotify_event_info_header {
   __u8 info_type;
   __u8 pad;
diff --git a/libc/kernel/uapi/linux/fb.h b/libc/kernel/uapi/linux/fb.h
index 38da042..a0ef0c4 100644
--- a/libc/kernel/uapi/linux/fb.h
+++ b/libc/kernel/uapi/linux/fb.h
@@ -182,6 +182,7 @@
 #define FB_ACTIVATE_ALL 64
 #define FB_ACTIVATE_FORCE 128
 #define FB_ACTIVATE_INV_MODE 256
+#define FB_ACTIVATE_KD_TEXT 512
 #define FB_ACCELF_TEXT 1
 #define FB_SYNC_HOR_HIGH_ACT 1
 #define FB_SYNC_VERT_HIGH_ACT 2
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index d0f19c8..a46726b 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -19,6 +19,7 @@
 #ifndef _UAPI_LINUX_FCNTL_H
 #define _UAPI_LINUX_FCNTL_H
 #include <asm/fcntl.h>
+#include <linux/openat2.h>
 #define F_SETLEASE (F_LINUX_SPECIFIC_BASE + 0)
 #define F_GETLEASE (F_LINUX_SPECIFIC_BASE + 1)
 #define F_CANCELLK (F_LINUX_SPECIFIC_BASE + 5)
@@ -53,6 +54,7 @@
 #define DN_MULTISHOT 0x80000000
 #define AT_FDCWD - 100
 #define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_EACCESS 0x200
 #define AT_REMOVEDIR 0x200
 #define AT_SYMLINK_FOLLOW 0x400
 #define AT_NO_AUTOMOUNT 0x800
diff --git a/libc/kernel/uapi/linux/fd.h b/libc/kernel/uapi/linux/fd.h
index f3c2d50..4d72d69 100644
--- a/libc/kernel/uapi/linux/fd.h
+++ b/libc/kernel/uapi/linux/fd.h
@@ -84,7 +84,8 @@
 #define FD_SILENT_DCL_CLEAR 0x4
 #define FD_INVERTED_DCL 0x80
   char read_track;
-  short autodetect[8];
+#define FD_AUTODETECT_SIZE 8
+  short autodetect[FD_AUTODETECT_SIZE];
   int checkfreq;
   int native_format;
 };
@@ -181,10 +182,18 @@
   long phys_length;
   int buffer_length;
   unsigned char rate;
+#define FD_RAW_CMD_SIZE 16
+#define FD_RAW_REPLY_SIZE 16
+#define FD_RAW_CMD_FULLSIZE (FD_RAW_CMD_SIZE + 1 + FD_RAW_REPLY_SIZE)
   unsigned char cmd_count;
-  unsigned char cmd[16];
-  unsigned char reply_count;
-  unsigned char reply[16];
+  union {
+    struct {
+      unsigned char cmd[FD_RAW_CMD_SIZE];
+      unsigned char reply_count;
+      unsigned char reply[FD_RAW_REPLY_SIZE];
+    };
+    unsigned char fullcmd[FD_RAW_CMD_FULLSIZE];
+  };
   int track;
   int resultcode;
   int reserved1;
diff --git a/libc/kernel/uapi/linux/fdreg.h b/libc/kernel/uapi/linux/fdreg.h
index 5280a59..2aeaf9a 100644
--- a/libc/kernel/uapi/linux/fdreg.h
+++ b/libc/kernel/uapi/linux/fdreg.h
@@ -18,16 +18,15 @@
  ****************************************************************************/
 #ifndef _LINUX_FDREG_H
 #define _LINUX_FDREG_H
-#ifdef FDPATCHES
-#define FD_IOPORT fdc_state[fdc].address
-#else
-#define FD_IOPORT 0x3f0
-#endif
-#define FD_STATUS (4 + FD_IOPORT)
-#define FD_DATA (5 + FD_IOPORT)
-#define FD_DOR (2 + FD_IOPORT)
-#define FD_DIR (7 + FD_IOPORT)
-#define FD_DCR (7 + FD_IOPORT)
+#define FD_SRA 0
+#define FD_SRB 1
+#define FD_DOR 2
+#define FD_TDR 3
+#define FD_DSR 4
+#define FD_STATUS 4
+#define FD_DATA 5
+#define FD_DIR 7
+#define FD_DCR 7
 #define STATUS_BUSYMASK 0x0F
 #define STATUS_BUSY 0x10
 #define STATUS_DMA 0x20
diff --git a/libc/kernel/uapi/linux/fiemap.h b/libc/kernel/uapi/linux/fiemap.h
index 77c3cc5..4310786 100644
--- a/libc/kernel/uapi/linux/fiemap.h
+++ b/libc/kernel/uapi/linux/fiemap.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _LINUX_FIEMAP_H
-#define _LINUX_FIEMAP_H
+#ifndef _UAPI_LINUX_FIEMAP_H
+#define _UAPI_LINUX_FIEMAP_H
 #include <linux/types.h>
 struct fiemap_extent {
   __u64 fe_logical;
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 1dd1602..0601768 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -177,6 +177,7 @@
 #define FS_EA_INODE_FL 0x00200000
 #define FS_EOFBLOCKS_FL 0x00400000
 #define FS_NOCOW_FL 0x00800000
+#define FS_DAX_FL 0x02000000
 #define FS_INLINE_DATA_FL 0x10000000
 #define FS_PROJINHERIT_FL 0x20000000
 #define FS_CASEFOLD_FL 0x40000000
diff --git a/libc/kernel/uapi/linux/fscrypt.h b/libc/kernel/uapi/linux/fscrypt.h
index f91ce85..33ed9c6 100644
--- a/libc/kernel/uapi/linux/fscrypt.h
+++ b/libc/kernel/uapi/linux/fscrypt.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_FSCRYPT_H
 #define _UAPI_LINUX_FSCRYPT_H
+#include <linux/ioctl.h>
 #include <linux/types.h>
 #define FSCRYPT_POLICY_FLAGS_PAD_4 0x00
 #define FSCRYPT_POLICY_FLAGS_PAD_8 0x01
@@ -26,7 +27,8 @@
 #define FSCRYPT_POLICY_FLAGS_PAD_MASK 0x03
 #define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04
 #define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 0x08
-#define FSCRYPT_POLICY_FLAGS_VALID 0x0F
+#define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 0x10
+#define FSCRYPT_POLICY_FLAGS_VALID 0x1F
 #define FSCRYPT_MODE_AES_256_XTS 1
 #define FSCRYPT_MODE_AES_256_CTS 4
 #define FSCRYPT_MODE_AES_128_CBC 5
@@ -80,10 +82,16 @@
     __u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE];
   } u;
 };
+struct fscrypt_provisioning_key_payload {
+  __u32 type;
+  __u32 __reserved;
+  __u8 raw[];
+};
 struct fscrypt_add_key_arg {
   struct fscrypt_key_specifier key_spec;
   __u32 raw_size;
-  __u32 __reserved[8];
+  __u32 key_id;
+  __u32 __reserved[7];
 #define __FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED 0x00000001
   __u32 __flags;
   __u8 raw[];
@@ -115,6 +123,7 @@
 #define FS_IOC_REMOVE_ENCRYPTION_KEY _IOWR('f', 24, struct fscrypt_remove_key_arg)
 #define FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS _IOWR('f', 25, struct fscrypt_remove_key_arg)
 #define FS_IOC_GET_ENCRYPTION_KEY_STATUS _IOWR('f', 26, struct fscrypt_get_key_status_arg)
+#define FS_IOC_GET_ENCRYPTION_NONCE _IOR('f', 27, __u8[16])
 #define FS_KEY_DESCRIPTOR_SIZE FSCRYPT_KEY_DESCRIPTOR_SIZE
 #define FS_POLICY_FLAGS_PAD_4 FSCRYPT_POLICY_FLAGS_PAD_4
 #define FS_POLICY_FLAGS_PAD_8 FSCRYPT_POLICY_FLAGS_PAD_8
diff --git a/libc/kernel/uapi/linux/genetlink.h b/libc/kernel/uapi/linux/genetlink.h
index a6e3760..2cef95e 100644
--- a/libc/kernel/uapi/linux/genetlink.h
+++ b/libc/kernel/uapi/linux/genetlink.h
@@ -49,6 +49,7 @@
   CTRL_CMD_NEWMCAST_GRP,
   CTRL_CMD_DELMCAST_GRP,
   CTRL_CMD_GETMCAST_GRP,
+  CTRL_CMD_GETPOLICY,
   __CTRL_CMD_MAX,
 };
 #define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
@@ -61,6 +62,7 @@
   CTRL_ATTR_MAXATTR,
   CTRL_ATTR_OPS,
   CTRL_ATTR_MCAST_GROUPS,
+  CTRL_ATTR_POLICY,
   __CTRL_ATTR_MAX,
 };
 #define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/gfs2_ondisk.h b/libc/kernel/uapi/linux/gfs2_ondisk.h
index 7d03ba5..a8fb59e 100644
--- a/libc/kernel/uapi/linux/gfs2_ondisk.h
+++ b/libc/kernel/uapi/linux/gfs2_ondisk.h
@@ -117,6 +117,11 @@
 #define GFS2_RGF_DATAONLY 0x00000004
 #define GFS2_RGF_NOALLOC 0x00000008
 #define GFS2_RGF_TRIMMED 0x00000010
+struct gfs2_inode_lvb {
+  __be32 ri_magic;
+  __be32 __pad;
+  __be64 ri_generation_deleted;
+};
 struct gfs2_rgrp_lvb {
   __be32 rl_magic;
   __be32 rl_flags;
diff --git a/libc/kernel/uapi/linux/gpio.h b/libc/kernel/uapi/linux/gpio.h
index 773f409..7e0ce7d 100644
--- a/libc/kernel/uapi/linux/gpio.h
+++ b/libc/kernel/uapi/linux/gpio.h
@@ -40,6 +40,17 @@
   char consumer[32];
 };
 #define GPIOHANDLES_MAX 64
+enum {
+  GPIOLINE_CHANGED_REQUESTED = 1,
+  GPIOLINE_CHANGED_RELEASED,
+  GPIOLINE_CHANGED_CONFIG,
+};
+struct gpioline_info_changed {
+  struct gpioline_info info;
+  __u64 timestamp;
+  __u32 event_type;
+  __u32 padding[5];
+};
 #define GPIOHANDLE_REQUEST_INPUT (1UL << 0)
 #define GPIOHANDLE_REQUEST_OUTPUT (1UL << 1)
 #define GPIOHANDLE_REQUEST_ACTIVE_LOW (1UL << 2)
@@ -85,6 +96,8 @@
 };
 #define GPIO_GET_CHIPINFO_IOCTL _IOR(0xB4, 0x01, struct gpiochip_info)
 #define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info)
+#define GPIO_GET_LINEINFO_WATCH_IOCTL _IOWR(0xB4, 0x0b, struct gpioline_info)
+#define GPIO_GET_LINEINFO_UNWATCH_IOCTL _IOWR(0xB4, 0x0c, __u32)
 #define GPIO_GET_LINEHANDLE_IOCTL _IOWR(0xB4, 0x03, struct gpiohandle_request)
 #define GPIO_GET_LINEEVENT_IOCTL _IOWR(0xB4, 0x04, struct gpioevent_request)
 #endif
diff --git a/libc/kernel/uapi/linux/hdlc/ioctl.h b/libc/kernel/uapi/linux/hdlc/ioctl.h
index 67b4d13..3c727c5 100644
--- a/libc/kernel/uapi/linux/hdlc/ioctl.h
+++ b/libc/kernel/uapi/linux/hdlc/ioctl.h
@@ -79,5 +79,13 @@
   unsigned int interval;
   unsigned int timeout;
 } cisco_proto;
+typedef struct {
+  unsigned short dce;
+  unsigned int modulo;
+  unsigned int window;
+  unsigned int t1;
+  unsigned int t2;
+  unsigned int n2;
+} x25_hdlc_proto;
 #endif
 #endif
diff --git a/libc/kernel/uapi/linux/hidraw.h b/libc/kernel/uapi/linux/hidraw.h
index 3ce49e1..ab7ed1c 100644
--- a/libc/kernel/uapi/linux/hidraw.h
+++ b/libc/kernel/uapi/linux/hidraw.h
@@ -36,6 +36,7 @@
 #define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
 #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x06, len)
 #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE | _IOC_READ, 'H', 0x07, len)
+#define HIDIOCGRAWUNIQ(len) _IOC(_IOC_READ, 'H', 0x08, len)
 #define HIDRAW_FIRST_MINOR 0
 #define HIDRAW_MAX_DEVICES 64
 #define HIDRAW_BUFFER_SIZE 64
diff --git a/libc/kernel/uapi/linux/hyperv.h b/libc/kernel/uapi/linux/hyperv.h
index fb114ad..daa8fc7 100644
--- a/libc/kernel/uapi/linux/hyperv.h
+++ b/libc/kernel/uapi/linux/hyperv.h
@@ -70,8 +70,8 @@
 };
 struct hv_fcopy_hdr {
   __u32 operation;
-  uuid_le service_id0;
-  uuid_le service_id1;
+  __u8 service_id0[16];
+  __u8 service_id1[16];
 } __attribute__((packed));
 #define OVER_WRITE 0x1
 #define CREATE_PATH 0x2
diff --git a/libc/kernel/uapi/linux/idxd.h b/libc/kernel/uapi/linux/idxd.h
new file mode 100644
index 0000000..3c8492e
--- /dev/null
+++ b/libc/kernel/uapi/linux/idxd.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _USR_IDXD_H_
+#define _USR_IDXD_H_
+#include <stdint.h>
+#define IDXD_OP_FLAG_FENCE 0x0001
+#define IDXD_OP_FLAG_BOF 0x0002
+#define IDXD_OP_FLAG_CRAV 0x0004
+#define IDXD_OP_FLAG_RCR 0x0008
+#define IDXD_OP_FLAG_RCI 0x0010
+#define IDXD_OP_FLAG_CRSTS 0x0020
+#define IDXD_OP_FLAG_CR 0x0080
+#define IDXD_OP_FLAG_CC 0x0100
+#define IDXD_OP_FLAG_ADDR1_TCS 0x0200
+#define IDXD_OP_FLAG_ADDR2_TCS 0x0400
+#define IDXD_OP_FLAG_ADDR3_TCS 0x0800
+#define IDXD_OP_FLAG_CR_TCS 0x1000
+#define IDXD_OP_FLAG_STORD 0x2000
+#define IDXD_OP_FLAG_DRDBK 0x4000
+#define IDXD_OP_FLAG_DSTS 0x8000
+enum dsa_opcode {
+  DSA_OPCODE_NOOP = 0,
+  DSA_OPCODE_BATCH,
+  DSA_OPCODE_DRAIN,
+  DSA_OPCODE_MEMMOVE,
+  DSA_OPCODE_MEMFILL,
+  DSA_OPCODE_COMPARE,
+  DSA_OPCODE_COMPVAL,
+  DSA_OPCODE_CR_DELTA,
+  DSA_OPCODE_AP_DELTA,
+  DSA_OPCODE_DUALCAST,
+  DSA_OPCODE_CRCGEN = 0x10,
+  DSA_OPCODE_COPY_CRC,
+  DSA_OPCODE_DIF_CHECK,
+  DSA_OPCODE_DIF_INS,
+  DSA_OPCODE_DIF_STRP,
+  DSA_OPCODE_DIF_UPDT,
+  DSA_OPCODE_CFLUSH = 0x20,
+};
+enum dsa_completion_status {
+  DSA_COMP_NONE = 0,
+  DSA_COMP_SUCCESS,
+  DSA_COMP_SUCCESS_PRED,
+  DSA_COMP_PAGE_FAULT_NOBOF,
+  DSA_COMP_PAGE_FAULT_IR,
+  DSA_COMP_BATCH_FAIL,
+  DSA_COMP_BATCH_PAGE_FAULT,
+  DSA_COMP_DR_OFFSET_NOINC,
+  DSA_COMP_DR_OFFSET_ERANGE,
+  DSA_COMP_DIF_ERR,
+  DSA_COMP_BAD_OPCODE = 0x10,
+  DSA_COMP_INVALID_FLAGS,
+  DSA_COMP_NOZERO_RESERVE,
+  DSA_COMP_XFER_ERANGE,
+  DSA_COMP_DESC_CNT_ERANGE,
+  DSA_COMP_DR_ERANGE,
+  DSA_COMP_OVERLAP_BUFFERS,
+  DSA_COMP_DCAST_ERR,
+  DSA_COMP_DESCLIST_ALIGN,
+  DSA_COMP_INT_HANDLE_INVAL,
+  DSA_COMP_CRA_XLAT,
+  DSA_COMP_CRA_ALIGN,
+  DSA_COMP_ADDR_ALIGN,
+  DSA_COMP_PRIV_BAD,
+  DSA_COMP_TRAFFIC_CLASS_CONF,
+  DSA_COMP_PFAULT_RDBA,
+  DSA_COMP_HW_ERR1,
+  DSA_COMP_HW_ERR_DRB,
+  DSA_COMP_TRANSLATION_FAIL,
+};
+#define DSA_COMP_STATUS_MASK 0x7f
+#define DSA_COMP_STATUS_WRITE 0x80
+struct dsa_hw_desc {
+  uint32_t pasid : 20;
+  uint32_t rsvd : 11;
+  uint32_t priv : 1;
+  uint32_t flags : 24;
+  uint32_t opcode : 8;
+  uint64_t completion_addr;
+  union {
+    uint64_t src_addr;
+    uint64_t rdback_addr;
+    uint64_t pattern;
+    uint64_t desc_list_addr;
+  };
+  union {
+    uint64_t dst_addr;
+    uint64_t rdback_addr2;
+    uint64_t src2_addr;
+    uint64_t comp_pattern;
+  };
+  union {
+    uint32_t xfer_size;
+    uint32_t desc_count;
+  };
+  uint16_t int_handle;
+  uint16_t rsvd1;
+  union {
+    uint8_t expected_res;
+    struct {
+      uint64_t delta_addr;
+      uint32_t max_delta_size;
+      uint32_t delt_rsvd;
+      uint8_t expected_res_mask;
+    };
+    uint32_t delta_rec_size;
+    uint64_t dest2;
+    struct {
+      uint32_t crc_seed;
+      uint32_t crc_rsvd;
+      uint64_t seed_addr;
+    };
+    struct {
+      uint8_t src_dif_flags;
+      uint8_t dif_chk_res;
+      uint8_t dif_chk_flags;
+      uint8_t dif_chk_res2[5];
+      uint32_t chk_ref_tag_seed;
+      uint16_t chk_app_tag_mask;
+      uint16_t chk_app_tag_seed;
+    };
+    struct {
+      uint8_t dif_ins_res;
+      uint8_t dest_dif_flag;
+      uint8_t dif_ins_flags;
+      uint8_t dif_ins_res2[13];
+      uint32_t ins_ref_tag_seed;
+      uint16_t ins_app_tag_mask;
+      uint16_t ins_app_tag_seed;
+    };
+    struct {
+      uint8_t src_upd_flags;
+      uint8_t upd_dest_flags;
+      uint8_t dif_upd_flags;
+      uint8_t dif_upd_res[5];
+      uint32_t src_ref_tag_seed;
+      uint16_t src_app_tag_mask;
+      uint16_t src_app_tag_seed;
+      uint32_t dest_ref_tag_seed;
+      uint16_t dest_app_tag_mask;
+      uint16_t dest_app_tag_seed;
+    };
+    uint8_t op_specific[24];
+  };
+} __attribute__((packed));
+struct dsa_raw_desc {
+  uint64_t field[8];
+} __attribute__((packed));
+struct dsa_completion_record {
+  volatile uint8_t status;
+  union {
+    uint8_t result;
+    uint8_t dif_status;
+  };
+  uint16_t rsvd;
+  uint32_t bytes_completed;
+  uint64_t fault_addr;
+  union {
+    uint16_t delta_rec_size;
+    uint16_t crc_val;
+    struct {
+      uint32_t dif_chk_ref_tag;
+      uint16_t dif_chk_app_tag_mask;
+      uint16_t dif_chk_app_tag;
+    };
+    struct {
+      uint64_t dif_ins_res;
+      uint32_t dif_ins_ref_tag;
+      uint16_t dif_ins_app_tag_mask;
+      uint16_t dif_ins_app_tag;
+    };
+    struct {
+      uint32_t dif_upd_src_ref_tag;
+      uint16_t dif_upd_src_app_tag_mask;
+      uint16_t dif_upd_src_app_tag;
+      uint32_t dif_upd_dest_ref_tag;
+      uint16_t dif_upd_dest_app_tag_mask;
+      uint16_t dif_upd_dest_app_tag;
+    };
+    uint8_t op_specific[16];
+  };
+} __attribute__((packed));
+struct dsa_raw_completion_record {
+  uint64_t field[4];
+} __attribute__((packed));
+#endif
diff --git a/libc/kernel/uapi/linux/if.h b/libc/kernel/uapi/linux/if.h
index 12967f7..63c77eb 100644
--- a/libc/kernel/uapi/linux/if.h
+++ b/libc/kernel/uapi/linux/if.h
@@ -114,6 +114,7 @@
 enum {
   IF_LINK_MODE_DEFAULT,
   IF_LINK_MODE_DORMANT,
+  IF_LINK_MODE_TESTING,
 };
 #if __UAPI_DEF_IF_IFMAP
 struct ifmap {
@@ -134,6 +135,7 @@
     fr_proto __user * fr;
     fr_proto_pvc __user * fr_pvc;
     fr_proto_pvc_info __user * fr_pvc_info;
+    x25_hdlc_proto __user * x25;
     sync_serial_settings __user * sync;
     te1_settings __user * te1;
   } ifs_ifsu;
diff --git a/libc/kernel/uapi/linux/if_bonding.h b/libc/kernel/uapi/linux/if_bonding.h
index a1fa959..0079f30 100644
--- a/libc/kernel/uapi/linux/if_bonding.h
+++ b/libc/kernel/uapi/linux/if_bonding.h
@@ -50,6 +50,14 @@
 #define BOND_XMIT_POLICY_LAYER23 2
 #define BOND_XMIT_POLICY_ENCAP23 3
 #define BOND_XMIT_POLICY_ENCAP34 4
+#define LACP_STATE_LACP_ACTIVITY 0x1
+#define LACP_STATE_LACP_TIMEOUT 0x2
+#define LACP_STATE_AGGREGATION 0x4
+#define LACP_STATE_SYNCHRONIZATION 0x8
+#define LACP_STATE_COLLECTING 0x10
+#define LACP_STATE_DISTRIBUTING 0x20
+#define LACP_STATE_DEFAULTED 0x40
+#define LACP_STATE_EXPIRED 0x80
 typedef struct ifbond {
   __s32 bond_mode;
   __s32 num_slaves;
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 03cc1c4..2c72ddf 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -106,6 +106,7 @@
   IFLA_BRIDGE_MODE,
   IFLA_BRIDGE_VLAN_INFO,
   IFLA_BRIDGE_VLAN_TUNNEL_INFO,
+  IFLA_BRIDGE_MRP,
   __IFLA_BRIDGE_MAX,
 };
 #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
@@ -115,6 +116,7 @@
 #define BRIDGE_VLAN_INFO_RANGE_BEGIN (1 << 3)
 #define BRIDGE_VLAN_INFO_RANGE_END (1 << 4)
 #define BRIDGE_VLAN_INFO_BRENTRY (1 << 5)
+#define BRIDGE_VLAN_INFO_ONLY_OPTS (1 << 6)
 struct bridge_vlan_info {
   __u16 flags;
   __u16 vid;
@@ -137,6 +139,137 @@
   __u32 pad2;
 };
 enum {
+  IFLA_BRIDGE_MRP_UNSPEC,
+  IFLA_BRIDGE_MRP_INSTANCE,
+  IFLA_BRIDGE_MRP_PORT_STATE,
+  IFLA_BRIDGE_MRP_PORT_ROLE,
+  IFLA_BRIDGE_MRP_RING_STATE,
+  IFLA_BRIDGE_MRP_RING_ROLE,
+  IFLA_BRIDGE_MRP_START_TEST,
+  __IFLA_BRIDGE_MRP_MAX,
+};
+#define IFLA_BRIDGE_MRP_MAX (__IFLA_BRIDGE_MRP_MAX - 1)
+enum {
+  IFLA_BRIDGE_MRP_INSTANCE_UNSPEC,
+  IFLA_BRIDGE_MRP_INSTANCE_RING_ID,
+  IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX,
+  IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX,
+  IFLA_BRIDGE_MRP_INSTANCE_PRIO,
+  __IFLA_BRIDGE_MRP_INSTANCE_MAX,
+};
+#define IFLA_BRIDGE_MRP_INSTANCE_MAX (__IFLA_BRIDGE_MRP_INSTANCE_MAX - 1)
+enum {
+  IFLA_BRIDGE_MRP_PORT_STATE_UNSPEC,
+  IFLA_BRIDGE_MRP_PORT_STATE_STATE,
+  __IFLA_BRIDGE_MRP_PORT_STATE_MAX,
+};
+#define IFLA_BRIDGE_MRP_PORT_STATE_MAX (__IFLA_BRIDGE_MRP_PORT_STATE_MAX - 1)
+enum {
+  IFLA_BRIDGE_MRP_PORT_ROLE_UNSPEC,
+  IFLA_BRIDGE_MRP_PORT_ROLE_ROLE,
+  __IFLA_BRIDGE_MRP_PORT_ROLE_MAX,
+};
+#define IFLA_BRIDGE_MRP_PORT_ROLE_MAX (__IFLA_BRIDGE_MRP_PORT_ROLE_MAX - 1)
+enum {
+  IFLA_BRIDGE_MRP_RING_STATE_UNSPEC,
+  IFLA_BRIDGE_MRP_RING_STATE_RING_ID,
+  IFLA_BRIDGE_MRP_RING_STATE_STATE,
+  __IFLA_BRIDGE_MRP_RING_STATE_MAX,
+};
+#define IFLA_BRIDGE_MRP_RING_STATE_MAX (__IFLA_BRIDGE_MRP_RING_STATE_MAX - 1)
+enum {
+  IFLA_BRIDGE_MRP_RING_ROLE_UNSPEC,
+  IFLA_BRIDGE_MRP_RING_ROLE_RING_ID,
+  IFLA_BRIDGE_MRP_RING_ROLE_ROLE,
+  __IFLA_BRIDGE_MRP_RING_ROLE_MAX,
+};
+#define IFLA_BRIDGE_MRP_RING_ROLE_MAX (__IFLA_BRIDGE_MRP_RING_ROLE_MAX - 1)
+enum {
+  IFLA_BRIDGE_MRP_START_TEST_UNSPEC,
+  IFLA_BRIDGE_MRP_START_TEST_RING_ID,
+  IFLA_BRIDGE_MRP_START_TEST_INTERVAL,
+  IFLA_BRIDGE_MRP_START_TEST_MAX_MISS,
+  IFLA_BRIDGE_MRP_START_TEST_PERIOD,
+  IFLA_BRIDGE_MRP_START_TEST_MONITOR,
+  __IFLA_BRIDGE_MRP_START_TEST_MAX,
+};
+#define IFLA_BRIDGE_MRP_START_TEST_MAX (__IFLA_BRIDGE_MRP_START_TEST_MAX - 1)
+struct br_mrp_instance {
+  __u32 ring_id;
+  __u32 p_ifindex;
+  __u32 s_ifindex;
+  __u16 prio;
+};
+struct br_mrp_ring_state {
+  __u32 ring_id;
+  __u32 ring_state;
+};
+struct br_mrp_ring_role {
+  __u32 ring_id;
+  __u32 ring_role;
+};
+struct br_mrp_start_test {
+  __u32 ring_id;
+  __u32 interval;
+  __u32 max_miss;
+  __u32 period;
+  __u32 monitor;
+};
+struct bridge_stp_xstats {
+  __u64 transition_blk;
+  __u64 transition_fwd;
+  __u64 rx_bpdu;
+  __u64 tx_bpdu;
+  __u64 rx_tcn;
+  __u64 tx_tcn;
+};
+struct br_vlan_msg {
+  __u8 family;
+  __u8 reserved1;
+  __u16 reserved2;
+  __u32 ifindex;
+};
+enum {
+  BRIDGE_VLANDB_DUMP_UNSPEC,
+  BRIDGE_VLANDB_DUMP_FLAGS,
+  __BRIDGE_VLANDB_DUMP_MAX,
+};
+#define BRIDGE_VLANDB_DUMP_MAX (__BRIDGE_VLANDB_DUMP_MAX - 1)
+#define BRIDGE_VLANDB_DUMPF_STATS (1 << 0)
+enum {
+  BRIDGE_VLANDB_UNSPEC,
+  BRIDGE_VLANDB_ENTRY,
+  __BRIDGE_VLANDB_MAX,
+};
+#define BRIDGE_VLANDB_MAX (__BRIDGE_VLANDB_MAX - 1)
+enum {
+  BRIDGE_VLANDB_ENTRY_UNSPEC,
+  BRIDGE_VLANDB_ENTRY_INFO,
+  BRIDGE_VLANDB_ENTRY_RANGE,
+  BRIDGE_VLANDB_ENTRY_STATE,
+  BRIDGE_VLANDB_ENTRY_TUNNEL_INFO,
+  BRIDGE_VLANDB_ENTRY_STATS,
+  __BRIDGE_VLANDB_ENTRY_MAX,
+};
+#define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
+enum {
+  BRIDGE_VLANDB_TINFO_UNSPEC,
+  BRIDGE_VLANDB_TINFO_ID,
+  BRIDGE_VLANDB_TINFO_CMD,
+  __BRIDGE_VLANDB_TINFO_MAX,
+};
+#define BRIDGE_VLANDB_TINFO_MAX (__BRIDGE_VLANDB_TINFO_MAX - 1)
+enum {
+  BRIDGE_VLANDB_STATS_UNSPEC,
+  BRIDGE_VLANDB_STATS_RX_BYTES,
+  BRIDGE_VLANDB_STATS_RX_PACKETS,
+  BRIDGE_VLANDB_STATS_TX_BYTES,
+  BRIDGE_VLANDB_STATS_TX_PACKETS,
+  BRIDGE_VLANDB_STATS_PAD,
+  __BRIDGE_VLANDB_STATS_MAX,
+};
+#define BRIDGE_VLANDB_STATS_MAX (__BRIDGE_VLANDB_STATS_MAX - 1)
+enum {
   MDBA_UNSPEC,
   MDBA_MDB,
   MDBA_ROUTER,
@@ -212,6 +345,7 @@
   BRIDGE_XSTATS_VLAN,
   BRIDGE_XSTATS_MCAST,
   BRIDGE_XSTATS_PAD,
+  BRIDGE_XSTATS_STP,
   __BRIDGE_XSTATS_MAX
 };
 #define BRIDGE_XSTATS_MAX (__BRIDGE_XSTATS_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index dd2dedb..c3e0718 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -73,6 +73,7 @@
 #define ETH_P_PREAUTH 0x88C7
 #define ETH_P_TIPC 0x88CA
 #define ETH_P_LLDP 0x88CC
+#define ETH_P_MRP 0x88E3
 #define ETH_P_MACSEC 0x88E5
 #define ETH_P_8021AH 0x88E7
 #define ETH_P_MVRP 0x88F5
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 7843fb5..b248a6b 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -146,6 +146,7 @@
   IFLA_MAX_MTU,
   IFLA_PROP_LIST,
   IFLA_ALT_IFNAME,
+  IFLA_PERM_ADDRESS,
   __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
@@ -271,6 +272,7 @@
   IFLA_BRPORT_NEIGH_SUPPRESS,
   IFLA_BRPORT_ISOLATED,
   IFLA_BRPORT_BACKUP_PORT,
+  IFLA_BRPORT_MRP_RING_OPEN,
   __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -367,6 +369,7 @@
   IFLA_MACSEC_REPLAY_PROTECT,
   IFLA_MACSEC_VALIDATION,
   IFLA_MACSEC_PAD,
+  IFLA_MACSEC_OFFLOAD,
   __IFLA_MACSEC_MAX,
 };
 #define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
@@ -384,6 +387,13 @@
   __MACSEC_VALIDATE_END,
   MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
 };
+enum macsec_offload {
+  MACSEC_OFFLOAD_OFF = 0,
+  MACSEC_OFFLOAD_PHY = 1,
+  MACSEC_OFFLOAD_MAC = 2,
+  __MACSEC_OFFLOAD_END,
+  MACSEC_OFFLOAD_MAX = __MACSEC_OFFLOAD_END - 1,
+};
 enum {
   IFLA_IPVLAN_UNSPEC,
   IFLA_IPVLAN_MODE,
@@ -470,6 +480,15 @@
   GENEVE_DF_MAX = __GENEVE_DF_END - 1,
 };
 enum {
+  IFLA_BAREUDP_UNSPEC,
+  IFLA_BAREUDP_PORT,
+  IFLA_BAREUDP_ETHERTYPE,
+  IFLA_BAREUDP_SRCPORT_MIN,
+  IFLA_BAREUDP_MULTIPROTO_MODE,
+  __IFLA_BAREUDP_MAX
+};
+#define IFLA_BAREUDP_MAX (__IFLA_BAREUDP_MAX - 1)
+enum {
   IFLA_PPP_UNSPEC,
   IFLA_PPP_DEV_FD,
   __IFLA_PPP_MAX
@@ -747,8 +766,9 @@
 #define XDP_FLAGS_SKB_MODE (1U << 1)
 #define XDP_FLAGS_DRV_MODE (1U << 2)
 #define XDP_FLAGS_HW_MODE (1U << 3)
+#define XDP_FLAGS_REPLACE (1U << 4)
 #define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE)
-#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_MODES)
+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_MODES | XDP_FLAGS_REPLACE)
 enum {
   XDP_ATTACHED_NONE = 0,
   XDP_ATTACHED_DRV,
@@ -765,6 +785,7 @@
   IFLA_XDP_DRV_PROG_ID,
   IFLA_XDP_SKB_PROG_ID,
   IFLA_XDP_HW_PROG_ID,
+  IFLA_XDP_EXPECTED_FD,
   __IFLA_XDP_MAX,
 };
 #define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_macsec.h b/libc/kernel/uapi/linux/if_macsec.h
index a58f531..e60d767 100644
--- a/libc/kernel/uapi/linux/if_macsec.h
+++ b/libc/kernel/uapi/linux/if_macsec.h
@@ -25,6 +25,8 @@
 #define MACSEC_KEYID_LEN 16
 #define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL
 #define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL
+#define MACSEC_CIPHER_ID_GCM_AES_XPN_128 0x0080C20001000003ULL
+#define MACSEC_CIPHER_ID_GCM_AES_XPN_256 0x0080C20001000004ULL
 #define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL
 #define MACSEC_DEFAULT_CIPHER_ALT MACSEC_CIPHER_ID_GCM_AES_128
 #define MACSEC_MIN_ICV_LEN 8
@@ -40,6 +42,7 @@
   MACSEC_ATTR_RXSC_LIST,
   MACSEC_ATTR_TXSC_STATS,
   MACSEC_ATTR_SECY_STATS,
+  MACSEC_ATTR_OFFLOAD,
   __MACSEC_ATTR_END,
   NUM_MACSEC_ATTR = __MACSEC_ATTR_END,
   MACSEC_ATTR_MAX = __MACSEC_ATTR_END - 1,
@@ -84,10 +87,20 @@
   MACSEC_SA_ATTR_KEYID,
   MACSEC_SA_ATTR_STATS,
   MACSEC_SA_ATTR_PAD,
+  MACSEC_SA_ATTR_SSCI,
+  MACSEC_SA_ATTR_SALT,
   __MACSEC_SA_ATTR_END,
   NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END,
   MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END - 1,
 };
+enum macsec_offload_attrs {
+  MACSEC_OFFLOAD_ATTR_UNSPEC,
+  MACSEC_OFFLOAD_ATTR_TYPE,
+  MACSEC_OFFLOAD_ATTR_PAD,
+  __MACSEC_OFFLOAD_ATTR_END,
+  NUM_MACSEC_OFFLOAD_ATTR = __MACSEC_OFFLOAD_ATTR_END,
+  MACSEC_OFFLOAD_ATTR_MAX = __MACSEC_OFFLOAD_ATTR_END - 1,
+};
 enum macsec_nl_commands {
   MACSEC_CMD_GET_TXSC,
   MACSEC_CMD_ADD_RXSC,
@@ -99,6 +112,7 @@
   MACSEC_CMD_ADD_RXSA,
   MACSEC_CMD_DEL_RXSA,
   MACSEC_CMD_UPD_RXSA,
+  MACSEC_CMD_UPD_OFFLOAD,
 };
 enum macsec_rxsc_stats_attr {
   MACSEC_RXSC_STATS_ATTR_UNSPEC,
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index f1dab00..99b54cc 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -74,8 +74,12 @@
 #define IPPROTO_UDPLITE IPPROTO_UDPLITE
   IPPROTO_MPLS = 137,
 #define IPPROTO_MPLS IPPROTO_MPLS
+  IPPROTO_ETHERNET = 143,
+#define IPPROTO_ETHERNET IPPROTO_ETHERNET
   IPPROTO_RAW = 255,
 #define IPPROTO_RAW IPPROTO_RAW
+  IPPROTO_MPTCP = 262,
+#define IPPROTO_MPTCP IPPROTO_MPTCP
   IPPROTO_MAX
 };
 #endif
diff --git a/libc/kernel/uapi/linux/incrementalfs.h b/libc/kernel/uapi/linux/incrementalfs.h
new file mode 100644
index 0000000..cfaee52
--- /dev/null
+++ b/libc/kernel/uapi/linux/incrementalfs.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_INCREMENTALFS_H
+#define _UAPI_LINUX_INCREMENTALFS_H
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/xattr.h>
+#define INCFS_NAME "incremental-fs"
+#define INCFS_MAGIC_NUMBER (0x5346434e49ul)
+#define INCFS_DATA_FILE_BLOCK_SIZE 4096
+#define INCFS_HEADER_VER 1
+#define INCFS_MAX_HASH_SIZE 32
+#define INCFS_MAX_FILE_ATTR_SIZE 512
+#define INCFS_PENDING_READS_FILENAME ".pending_reads"
+#define INCFS_LOG_FILENAME ".log"
+#define INCFS_XATTR_ID_NAME (XATTR_USER_PREFIX "incfs.id")
+#define INCFS_XATTR_SIZE_NAME (XATTR_USER_PREFIX "incfs.size")
+#define INCFS_XATTR_METADATA_NAME (XATTR_USER_PREFIX "incfs.metadata")
+#define INCFS_MAX_SIGNATURE_SIZE 8096
+#define INCFS_SIGNATURE_VERSION 2
+#define INCFS_SIGNATURE_SECTIONS 2
+#define INCFS_IOCTL_BASE_CODE 'g'
+#define INCFS_IOC_CREATE_FILE _IOWR(INCFS_IOCTL_BASE_CODE, 30, struct incfs_new_file_args)
+#define INCFS_IOC_READ_FILE_SIGNATURE _IOR(INCFS_IOCTL_BASE_CODE, 31, struct incfs_get_file_sig_args)
+#define INCFS_IOC_FILL_BLOCKS _IOR(INCFS_IOCTL_BASE_CODE, 32, struct incfs_fill_blocks)
+#define INCFS_IOC_PERMIT_FILL _IOW(INCFS_IOCTL_BASE_CODE, 33, struct incfs_permit_fill)
+#define INCFS_IOC_GET_FILLED_BLOCKS _IOR(INCFS_IOCTL_BASE_CODE, 34, struct incfs_get_filled_blocks_args)
+enum incfs_compression_alg {
+  COMPRESSION_NONE = 0,
+  COMPRESSION_LZ4 = 1
+};
+enum incfs_block_flags {
+  INCFS_BLOCK_FLAGS_NONE = 0,
+  INCFS_BLOCK_FLAGS_HASH = 1,
+};
+typedef struct {
+  __u8 bytes[16];
+} incfs_uuid_t __attribute__((aligned(8)));
+struct incfs_pending_read_info {
+  incfs_uuid_t file_id;
+  __aligned_u64 timestamp_us;
+  __u32 block_index;
+  __u32 serial_number;
+};
+struct incfs_fill_block {
+  __u32 block_index;
+  __u32 data_len;
+  __aligned_u64 data;
+  __u8 compression;
+  __u8 flags;
+  __u16 reserved1;
+  __u32 reserved2;
+  __aligned_u64 reserved3;
+};
+struct incfs_fill_blocks {
+  __u64 count;
+  __aligned_u64 fill_blocks;
+};
+struct incfs_permit_fill {
+  __u32 file_descriptor;
+};
+enum incfs_hash_tree_algorithm {
+  INCFS_HASH_TREE_NONE = 0,
+  INCFS_HASH_TREE_SHA256 = 1
+};
+struct incfs_new_file_args {
+  incfs_uuid_t file_id;
+  __aligned_u64 size;
+  __u16 mode;
+  __u16 reserved1;
+  __u32 reserved2;
+  __aligned_u64 directory_path;
+  __aligned_u64 file_name;
+  __aligned_u64 file_attr;
+  __u32 file_attr_len;
+  __u32 reserved4;
+  __aligned_u64 signature_info;
+  __aligned_u64 signature_size;
+  __aligned_u64 reserved6;
+};
+struct incfs_get_file_sig_args {
+  __aligned_u64 file_signature;
+  __u32 file_signature_buf_size;
+  __u32 file_signature_len_out;
+};
+struct incfs_filled_range {
+  __u32 begin;
+  __u32 end;
+};
+struct incfs_get_filled_blocks_args {
+  __aligned_u64 range_buffer;
+  __u32 range_buffer_size;
+  __u32 start_index;
+  __u32 end_index;
+  __u32 total_blocks_out;
+  __u32 data_blocks_out;
+  __u32 range_buffer_size_out;
+  __u32 index_out;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/inet_diag.h b/libc/kernel/uapi/linux/inet_diag.h
index 5df55ef..1c3c128 100644
--- a/libc/kernel/uapi/linux/inet_diag.h
+++ b/libc/kernel/uapi/linux/inet_diag.h
@@ -59,8 +59,10 @@
 enum {
   INET_DIAG_REQ_NONE,
   INET_DIAG_REQ_BYTECODE,
+  INET_DIAG_REQ_SK_BPF_STORAGES,
+  __INET_DIAG_REQ_MAX,
 };
-#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
+#define INET_DIAG_REQ_MAX (__INET_DIAG_REQ_MAX - 1)
 struct inet_diag_bc_op {
   unsigned char code;
   unsigned char yes;
@@ -80,6 +82,7 @@
   INET_DIAG_BC_MARK_COND,
   INET_DIAG_BC_S_EQ,
   INET_DIAG_BC_D_EQ,
+  INET_DIAG_BC_CGROUP_COND,
 };
 struct inet_diag_hostcond {
   __u8 family;
@@ -124,6 +127,8 @@
   INET_DIAG_CLASS_ID,
   INET_DIAG_MD5SIG,
   INET_DIAG_ULP_INFO,
+  INET_DIAG_SK_BPF_STORAGES,
+  INET_DIAG_CGROUP_ID,
   __INET_DIAG_MAX,
 };
 #define INET_DIAG_MAX (__INET_DIAG_MAX - 1)
@@ -131,6 +136,7 @@
   INET_ULP_INFO_UNSPEC,
   INET_ULP_INFO_NAME,
   INET_ULP_INFO_TLS,
+  INET_ULP_INFO_MPTCP,
   __INET_ULP_INFO_MAX,
 };
 #define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index ee0e92f..1275b26 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -572,6 +572,7 @@
 #define KEY_DATA 0x277
 #define KEY_ONSCREEN_KEYBOARD 0x278
 #define KEY_PRIVACY_SCREEN_TOGGLE 0x279
+#define KEY_SELECTIVE_SCREENSHOT 0x27a
 #define KEY_MACRO1 0x290
 #define KEY_MACRO2 0x291
 #define KEY_MACRO3 0x292
@@ -733,10 +734,8 @@
 #define SW_LINEIN_INSERT 0x0d
 #define SW_MUTE_DEVICE 0x0e
 #define SW_PEN_INSERTED 0x0f
-#define SW_HPHL_OVERCURRENT 0x10
-#define SW_HPHR_OVERCURRENT 0x11
-#define SW_UNSUPPORT_INSERT 0x12
-#define SW_MAX 0x20
+#define SW_MACHINE_COVER 0x10
+#define SW_MAX 0x10
 #define SW_CNT (SW_MAX + 1)
 #define MSC_SERIAL 0x00
 #define MSC_PULSELED 0x01
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 0639a80..9912405 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -29,7 +29,10 @@
     __u64 off;
     __u64 addr2;
   };
-  __u64 addr;
+  union {
+    __u64 addr;
+    __u64 splice_off_in;
+  };
   __u32 len;
   union {
     __kernel_rwf_t rw_flags;
@@ -40,21 +43,44 @@
     __u32 timeout_flags;
     __u32 accept_flags;
     __u32 cancel_flags;
+    __u32 open_flags;
+    __u32 statx_flags;
+    __u32 fadvise_advice;
+    __u32 splice_flags;
   };
   __u64 user_data;
   union {
-    __u16 buf_index;
+    struct {
+      union {
+        __u16 buf_index;
+        __u16 buf_group;
+      } __attribute__((packed));
+      __u16 personality;
+      __s32 splice_fd_in;
+    };
     __u64 __pad2[3];
   };
 };
-#define IOSQE_FIXED_FILE (1U << 0)
-#define IOSQE_IO_DRAIN (1U << 1)
-#define IOSQE_IO_LINK (1U << 2)
-#define IOSQE_IO_HARDLINK (1U << 3)
+enum {
+  IOSQE_FIXED_FILE_BIT,
+  IOSQE_IO_DRAIN_BIT,
+  IOSQE_IO_LINK_BIT,
+  IOSQE_IO_HARDLINK_BIT,
+  IOSQE_ASYNC_BIT,
+  IOSQE_BUFFER_SELECT_BIT,
+};
+#define IOSQE_FIXED_FILE (1U << IOSQE_FIXED_FILE_BIT)
+#define IOSQE_IO_DRAIN (1U << IOSQE_IO_DRAIN_BIT)
+#define IOSQE_IO_LINK (1U << IOSQE_IO_LINK_BIT)
+#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 IORING_SETUP_IOPOLL (1U << 0)
 #define IORING_SETUP_SQPOLL (1U << 1)
 #define IORING_SETUP_SQ_AFF (1U << 2)
 #define IORING_SETUP_CQSIZE (1U << 3)
+#define IORING_SETUP_CLAMP (1U << 4)
+#define IORING_SETUP_ATTACH_WQ (1U << 5)
 enum {
   IORING_OP_NOP,
   IORING_OP_READV,
@@ -73,15 +99,37 @@
   IORING_OP_ASYNC_CANCEL,
   IORING_OP_LINK_TIMEOUT,
   IORING_OP_CONNECT,
+  IORING_OP_FALLOCATE,
+  IORING_OP_OPENAT,
+  IORING_OP_CLOSE,
+  IORING_OP_FILES_UPDATE,
+  IORING_OP_STATX,
+  IORING_OP_READ,
+  IORING_OP_WRITE,
+  IORING_OP_FADVISE,
+  IORING_OP_MADVISE,
+  IORING_OP_SEND,
+  IORING_OP_RECV,
+  IORING_OP_OPENAT2,
+  IORING_OP_EPOLL_CTL,
+  IORING_OP_SPLICE,
+  IORING_OP_PROVIDE_BUFFERS,
+  IORING_OP_REMOVE_BUFFERS,
+  IORING_OP_TEE,
   IORING_OP_LAST,
 };
 #define IORING_FSYNC_DATASYNC (1U << 0)
 #define IORING_TIMEOUT_ABS (1U << 0)
+#define SPLICE_F_FD_IN_FIXED (1U << 31)
 struct io_uring_cqe {
   __u64 user_data;
   __s32 res;
   __u32 flags;
 };
+#define IORING_CQE_F_BUFFER (1U << 0)
+enum {
+  IORING_CQE_BUFFER_SHIFT = 16,
+};
 #define IORING_OFF_SQ_RING 0ULL
 #define IORING_OFF_CQ_RING 0x8000000ULL
 #define IORING_OFF_SQES 0x10000000ULL
@@ -97,6 +145,7 @@
   __u64 resv2;
 };
 #define IORING_SQ_NEED_WAKEUP (1U << 0)
+#define IORING_SQ_CQ_OVERFLOW (1U << 1)
 struct io_cqring_offsets {
   __u32 head;
   __u32 tail;
@@ -104,8 +153,11 @@
   __u32 ring_entries;
   __u32 overflow;
   __u32 cqes;
-  __u64 resv[2];
+  __u32 flags;
+  __u32 resv1;
+  __u64 resv2;
 };
+#define IORING_CQ_EVENTFD_DISABLED (1U << 0)
 #define IORING_ENTER_GETEVENTS (1U << 0)
 #define IORING_ENTER_SQ_WAKEUP (1U << 1)
 struct io_uring_params {
@@ -115,13 +167,17 @@
   __u32 sq_thread_cpu;
   __u32 sq_thread_idle;
   __u32 features;
-  __u32 resv[4];
+  __u32 wq_fd;
+  __u32 resv[3];
   struct io_sqring_offsets sq_off;
   struct io_cqring_offsets cq_off;
 };
 #define IORING_FEAT_SINGLE_MMAP (1U << 0)
 #define IORING_FEAT_NODROP (1U << 1)
 #define IORING_FEAT_SUBMIT_STABLE (1U << 2)
+#define IORING_FEAT_RW_CUR_POS (1U << 3)
+#define IORING_FEAT_CUR_PERSONALITY (1U << 4)
+#define IORING_FEAT_FAST_POLL (1U << 5)
 #define IORING_REGISTER_BUFFERS 0
 #define IORING_UNREGISTER_BUFFERS 1
 #define IORING_REGISTER_FILES 2
@@ -129,9 +185,27 @@
 #define IORING_REGISTER_EVENTFD 4
 #define IORING_UNREGISTER_EVENTFD 5
 #define IORING_REGISTER_FILES_UPDATE 6
+#define IORING_REGISTER_EVENTFD_ASYNC 7
+#define IORING_REGISTER_PROBE 8
+#define IORING_REGISTER_PERSONALITY 9
+#define IORING_UNREGISTER_PERSONALITY 10
 struct io_uring_files_update {
   __u32 offset;
   __u32 resv;
   __aligned_u64 fds;
 };
+#define IO_URING_OP_SUPPORTED (1U << 0)
+struct io_uring_probe_op {
+  __u8 op;
+  __u8 resv;
+  __u16 flags;
+  __u32 resv2;
+};
+struct io_uring_probe {
+  __u8 last_op;
+  __u8 ops_len;
+  __u16 resv;
+  __u32 resv2[3];
+  struct io_uring_probe_op ops[0];
+};
 #endif
diff --git a/libc/kernel/uapi/linux/iommu.h b/libc/kernel/uapi/linux/iommu.h
index 54452c3..172be9c 100644
--- a/libc/kernel/uapi/linux/iommu.h
+++ b/libc/kernel/uapi/linux/iommu.h
@@ -133,6 +133,7 @@
   __u32 pat;
   __u32 emt;
 };
+#define IOMMU_SVA_VTD_GPASID_MTS_MASK (IOMMU_SVA_VTD_GPASID_CD | IOMMU_SVA_VTD_GPASID_EMTE | IOMMU_SVA_VTD_GPASID_PCD | IOMMU_SVA_VTD_GPASID_PWT)
 struct iommu_gpasid_bind_data {
 #define IOMMU_GPASID_BIND_VERSION_1 1
   __u32 version;
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index ff345a6..7cd6cb0 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -43,6 +43,7 @@
 #define IPV6_SRCRT_STRICT 0x01
 #define IPV6_SRCRT_TYPE_0 0
 #define IPV6_SRCRT_TYPE_2 2
+#define IPV6_SRCRT_TYPE_3 3
 #define IPV6_SRCRT_TYPE_4 4
 struct ipv6_rt_hdr {
   __u8 nexthdr;
@@ -141,6 +142,7 @@
   DEVCONF_DISABLE_POLICY,
   DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
   DEVCONF_NDISC_TCLASS,
+  DEVCONF_RPL_SEG_ENABLED,
   DEVCONF_MAX
 };
 #endif
diff --git a/libc/kernel/uapi/linux/keyctl.h b/libc/kernel/uapi/linux/keyctl.h
index e3fef38..01ea576 100644
--- a/libc/kernel/uapi/linux/keyctl.h
+++ b/libc/kernel/uapi/linux/keyctl.h
@@ -68,6 +68,7 @@
 #define KEYCTL_RESTRICT_KEYRING 29
 #define KEYCTL_MOVE 30
 #define KEYCTL_CAPABILITIES 31
+#define KEYCTL_WATCH_KEY 32
 struct keyctl_dh_params {
   union {
 #ifndef __cplusplus
@@ -117,4 +118,5 @@
 #define KEYCTL_CAPS0_MOVE 0x80
 #define KEYCTL_CAPS1_NS_KEYRING_NAME 0x01
 #define KEYCTL_CAPS1_NS_KEY_TAG 0x02
+#define KEYCTL_CAPS1_NOTIFICATIONS 0x04
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 8b09f00..d9f7bfc 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -267,6 +267,12 @@
   __u32 n_devices;
   __u32 n_success;
 };
+struct kfd_ioctl_alloc_queue_gws_args {
+  __u32 queue_id;
+  __u32 num_gws;
+  __u32 first_gws;
+  __u32 pad;
+};
 struct kfd_ioctl_get_dmabuf_info_args {
   __u64 size;
   __u64 metadata_ptr;
@@ -319,6 +325,7 @@
 #define AMDKFD_IOC_GET_QUEUE_WAVE_STATE AMDKFD_IOWR(0x1B, struct kfd_ioctl_get_queue_wave_state_args)
 #define AMDKFD_IOC_GET_DMABUF_INFO AMDKFD_IOWR(0x1C, struct kfd_ioctl_get_dmabuf_info_args)
 #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_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x1E
+#define AMDKFD_COMMAND_END 0x1F
 #endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index b865936..7e13990 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -137,10 +137,13 @@
 struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC 1
 #define KVM_EXIT_HYPERV_HCALL 2
+#define KVM_EXIT_HYPERV_SYNDBG 3
   __u32 type;
+  __u32 pad1;
   union {
     struct {
       __u32 msr;
+      __u32 pad2;
       __u64 control;
       __u64 evt_page;
       __u64 msg_page;
@@ -150,6 +153,15 @@
       __u64 result;
       __u64 params[2];
     } hcall;
+    struct {
+      __u32 msr;
+      __u32 pad2;
+      __u64 control;
+      __u64 status;
+      __u64 send_page;
+      __u64 recv_page;
+      __u64 pending_page;
+    } syndbg;
   } u;
 };
 #define KVM_S390_GET_SKEYS_NONE 1
@@ -355,11 +367,16 @@
   __u32 size;
   __u32 op;
   __u64 buf;
-  __u8 ar;
-  __u8 reserved[31];
+  union {
+    __u8 ar;
+    __u32 sida_offset;
+    __u8 reserved[32];
+  };
 };
 #define KVM_S390_MEMOP_LOGICAL_READ 0
 #define KVM_S390_MEMOP_LOGICAL_WRITE 1
+#define KVM_S390_MEMOP_SIDA_READ 2
+#define KVM_S390_MEMOP_SIDA_WRITE 3
 #define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
 #define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
 struct kvm_interrupt {
@@ -788,6 +805,11 @@
 #define KVM_CAP_PPC_GUEST_DEBUG_SSTEP 176
 #define KVM_CAP_ARM_NISV_TO_USER 177
 #define KVM_CAP_ARM_INJECT_EXT_DABT 178
+#define KVM_CAP_S390_VCPU_RESETS 179
+#define KVM_CAP_S390_PROTECTED 180
+#define KVM_CAP_PPC_SECURE_GUEST 181
+#define KVM_CAP_HALT_POLL 182
+#define KVM_CAP_ASYNC_PF_INT 183
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -1110,6 +1132,35 @@
 #define KVM_CLEAR_DIRTY_LOG _IOWR(KVMIO, 0xc0, struct kvm_clear_dirty_log)
 #define KVM_GET_SUPPORTED_HV_CPUID _IOWR(KVMIO, 0xc1, struct kvm_cpuid2)
 #define KVM_ARM_VCPU_FINALIZE _IOW(KVMIO, 0xc2, int)
+#define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3)
+#define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4)
+struct kvm_s390_pv_sec_parm {
+  __u64 origin;
+  __u64 length;
+};
+struct kvm_s390_pv_unp {
+  __u64 addr;
+  __u64 size;
+  __u64 tweak;
+};
+enum pv_cmd_id {
+  KVM_PV_ENABLE,
+  KVM_PV_DISABLE,
+  KVM_PV_SET_SEC_PARMS,
+  KVM_PV_UNPACK,
+  KVM_PV_VERIFY,
+  KVM_PV_PREP_RESET,
+  KVM_PV_UNSHARE_ALL,
+};
+struct kvm_pv_cmd {
+  __u32 cmd;
+  __u16 rc;
+  __u16 rrc;
+  __u64 data;
+  __u32 flags;
+  __u32 reserved[3];
+};
+#define KVM_S390_PV_COMMAND _IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
 enum sev_cmd_id {
   KVM_SEV_INIT = 0,
   KVM_SEV_ES_INIT,
@@ -1228,4 +1279,6 @@
 };
 #define KVM_HYPERV_CONN_ID_MASK 0x00ffffff
 #define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0)
+#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0)
+#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1)
 #endif
diff --git a/libc/kernel/uapi/linux/loop.h b/libc/kernel/uapi/linux/loop.h
index d5a23b5..56eba91 100644
--- a/libc/kernel/uapi/linux/loop.h
+++ b/libc/kernel/uapi/linux/loop.h
@@ -26,6 +26,9 @@
   LO_FLAGS_PARTSCAN = 8,
   LO_FLAGS_DIRECT_IO = 16,
 };
+#define LOOP_SET_STATUS_SETTABLE_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN)
+#define LOOP_SET_STATUS_CLEARABLE_FLAGS (LO_FLAGS_AUTOCLEAR)
+#define LOOP_CONFIGURE_SETTABLE_FLAGS (LO_FLAGS_READ_ONLY | LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN | LO_FLAGS_DIRECT_IO)
 #include <asm/posix_types.h>
 #include <linux/types.h>
 struct loop_info {
@@ -57,6 +60,12 @@
   __u8 lo_encrypt_key[LO_KEY_SIZE];
   __u64 lo_init[2];
 };
+struct loop_config {
+  __u32 fd;
+  __u32 block_size;
+  struct loop_info64 info;
+  __u64 __reserved[8];
+};
 #define LO_CRYPT_NONE 0
 #define LO_CRYPT_XOR 1
 #define LO_CRYPT_DES 2
@@ -78,6 +87,7 @@
 #define LOOP_SET_CAPACITY 0x4C07
 #define LOOP_SET_DIRECT_IO 0x4C08
 #define LOOP_SET_BLOCK_SIZE 0x4C09
+#define LOOP_CONFIGURE 0x4C0A
 #define LOOP_CTL_ADD 0x4C80
 #define LOOP_CTL_REMOVE 0x4C81
 #define LOOP_CTL_GET_FREE 0x4C82
diff --git a/libc/kernel/uapi/linux/lwtunnel.h b/libc/kernel/uapi/linux/lwtunnel.h
index f1e2ab8..f472150 100644
--- a/libc/kernel/uapi/linux/lwtunnel.h
+++ b/libc/kernel/uapi/linux/lwtunnel.h
@@ -28,6 +28,7 @@
   LWTUNNEL_ENCAP_SEG6,
   LWTUNNEL_ENCAP_BPF,
   LWTUNNEL_ENCAP_SEG6_LOCAL,
+  LWTUNNEL_ENCAP_RPL,
   __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 ca1daea..479ae81 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -68,7 +68,6 @@
 #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
 #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
-#define SDCARDFS_SUPER_MAGIC 0x5dca2df5
 #define SMB_SUPER_MAGIC 0x517B
 #define CGROUP_SUPER_MAGIC 0x27e0eb
 #define CGROUP2_SUPER_MAGIC 0x63677270
@@ -93,10 +92,12 @@
 #define NSFS_MAGIC 0x6e736673
 #define BPF_FS_MAGIC 0xcafe4a11
 #define AAFS_MAGIC 0x5a3c69f0
+#define ZONEFS_MAGIC 0x5a4f4653
 #define UDF_SUPER_MAGIC 0x15013346
 #define BALLOON_KVM_MAGIC 0x13661366
 #define ZSMALLOC_MAGIC 0x58295829
 #define DMA_BUF_MAGIC 0x444d4142
+#define DEVMEM_MAGIC 0x454d444d
 #define Z3FOLD_MAGIC 0x33
 #define PPC_CMM_MAGIC 0xc7571590
 #endif
diff --git a/libc/kernel/uapi/linux/media-bus-format.h b/libc/kernel/uapi/linux/media-bus-format.h
index f0d81d0..9e0ef0f 100644
--- a/libc/kernel/uapi/linux/media-bus-format.h
+++ b/libc/kernel/uapi/linux/media-bus-format.h
@@ -68,6 +68,7 @@
 #define MEDIA_BUS_FMT_VYUY12_2X12 0x201d
 #define MEDIA_BUS_FMT_YUYV12_2X12 0x201e
 #define MEDIA_BUS_FMT_YVYU12_2X12 0x201f
+#define MEDIA_BUS_FMT_Y14_1X14 0x202d
 #define MEDIA_BUS_FMT_UYVY8_1X16 0x200f
 #define MEDIA_BUS_FMT_VYUY8_1X16 0x2010
 #define MEDIA_BUS_FMT_YUYV8_1X16 0x2011
diff --git a/libc/kernel/uapi/linux/mii.h b/libc/kernel/uapi/linux/mii.h
index 3c6c564..a489015 100644
--- a/libc/kernel/uapi/linux/mii.h
+++ b/libc/kernel/uapi/linux/mii.h
@@ -120,11 +120,28 @@
 #define NWAYTEST_RESV1 0x00ff
 #define NWAYTEST_LOOPBACK 0x0100
 #define NWAYTEST_RESV2 0xfe00
+#define ADVERTISE_SGMII 0x0001
+#define LPA_SGMII 0x0001
+#define LPA_SGMII_SPD_MASK 0x0c00
+#define LPA_SGMII_FULL_DUPLEX 0x1000
+#define LPA_SGMII_DPX_SPD_MASK 0x1C00
+#define LPA_SGMII_10 0x0000
+#define LPA_SGMII_10HALF 0x0000
+#define LPA_SGMII_10FULL 0x1000
+#define LPA_SGMII_100 0x0400
+#define LPA_SGMII_100HALF 0x0400
+#define LPA_SGMII_100FULL 0x1400
+#define LPA_SGMII_1000 0x0800
+#define LPA_SGMII_1000HALF 0x0800
+#define LPA_SGMII_1000FULL 0x1800
+#define LPA_SGMII_LINK 0x8000
 #define ADVERTISE_1000FULL 0x0200
 #define ADVERTISE_1000HALF 0x0100
+#define CTL1000_PREFER_MASTER 0x0400
 #define CTL1000_AS_MASTER 0x0800
 #define CTL1000_ENABLE_MASTER 0x1000
 #define LPA_1000MSFAIL 0x8000
+#define LPA_1000MSRES 0x4000
 #define LPA_1000LOCALRXOK 0x2000
 #define LPA_1000REMRXOK 0x1000
 #define LPA_1000FULL 0x0800
diff --git a/libc/kernel/uapi/linux/mman.h b/libc/kernel/uapi/linux/mman.h
index e469374..9cb8776 100644
--- a/libc/kernel/uapi/linux/mman.h
+++ b/libc/kernel/uapi/linux/mman.h
@@ -22,6 +22,7 @@
 #include <asm-generic/hugetlb_encode.h>
 #define MREMAP_MAYMOVE 1
 #define MREMAP_FIXED 2
+#define MREMAP_DONTUNMAP 4
 #define OVERCOMMIT_GUESS 0
 #define OVERCOMMIT_ALWAYS 1
 #define OVERCOMMIT_NEVER 2
diff --git a/libc/kernel/uapi/linux/mmc/ioctl.h b/libc/kernel/uapi/linux/mmc/ioctl.h
index 101eb8c..afea6a5 100644
--- a/libc/kernel/uapi/linux/mmc/ioctl.h
+++ b/libc/kernel/uapi/linux/mmc/ioctl.h
@@ -19,6 +19,7 @@
 #ifndef LINUX_MMC_IOCTL_H
 #define LINUX_MMC_IOCTL_H
 #include <linux/types.h>
+#include <linux/major.h>
 struct mmc_ioc_cmd {
   int write_flag;
   int is_acmd;
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
new file mode 100644
index 0000000..43702f3
--- /dev/null
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_MPTCP_H
+#define _UAPI_MPTCP_H
+#include <linux/const.h>
+#include <linux/types.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)
+#define MPTCP_SUBFLOW_FLAG_JOIN_LOC _BITUL(3)
+#define MPTCP_SUBFLOW_FLAG_BKUP_REM _BITUL(4)
+#define MPTCP_SUBFLOW_FLAG_BKUP_LOC _BITUL(5)
+#define MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED _BITUL(6)
+#define MPTCP_SUBFLOW_FLAG_CONNECTED _BITUL(7)
+#define MPTCP_SUBFLOW_FLAG_MAPVALID _BITUL(8)
+enum {
+  MPTCP_SUBFLOW_ATTR_UNSPEC,
+  MPTCP_SUBFLOW_ATTR_TOKEN_REM,
+  MPTCP_SUBFLOW_ATTR_TOKEN_LOC,
+  MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
+  MPTCP_SUBFLOW_ATTR_MAP_SEQ,
+  MPTCP_SUBFLOW_ATTR_MAP_SFSEQ,
+  MPTCP_SUBFLOW_ATTR_SSN_OFFSET,
+  MPTCP_SUBFLOW_ATTR_MAP_DATALEN,
+  MPTCP_SUBFLOW_ATTR_FLAGS,
+  MPTCP_SUBFLOW_ATTR_ID_REM,
+  MPTCP_SUBFLOW_ATTR_ID_LOC,
+  MPTCP_SUBFLOW_ATTR_PAD,
+  __MPTCP_SUBFLOW_ATTR_MAX
+};
+#define MPTCP_SUBFLOW_ATTR_MAX (__MPTCP_SUBFLOW_ATTR_MAX - 1)
+#define MPTCP_PM_NAME "mptcp_pm"
+#define MPTCP_PM_CMD_GRP_NAME "mptcp_pm_cmds"
+#define MPTCP_PM_VER 0x1
+enum {
+  MPTCP_PM_ATTR_UNSPEC,
+  MPTCP_PM_ATTR_ADDR,
+  MPTCP_PM_ATTR_RCV_ADD_ADDRS,
+  MPTCP_PM_ATTR_SUBFLOWS,
+  __MPTCP_PM_ATTR_MAX
+};
+#define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1)
+enum {
+  MPTCP_PM_ADDR_ATTR_UNSPEC,
+  MPTCP_PM_ADDR_ATTR_FAMILY,
+  MPTCP_PM_ADDR_ATTR_ID,
+  MPTCP_PM_ADDR_ATTR_ADDR4,
+  MPTCP_PM_ADDR_ATTR_ADDR6,
+  MPTCP_PM_ADDR_ATTR_PORT,
+  MPTCP_PM_ADDR_ATTR_FLAGS,
+  MPTCP_PM_ADDR_ATTR_IF_IDX,
+  __MPTCP_PM_ADDR_ATTR_MAX
+};
+#define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1)
+#define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0)
+#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
+#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
+enum {
+  MPTCP_PM_CMD_UNSPEC,
+  MPTCP_PM_CMD_ADD_ADDR,
+  MPTCP_PM_CMD_DEL_ADDR,
+  MPTCP_PM_CMD_GET_ADDR,
+  MPTCP_PM_CMD_FLUSH_ADDRS,
+  MPTCP_PM_CMD_SET_LIMITS,
+  MPTCP_PM_CMD_GET_LIMITS,
+  __MPTCP_PM_CMD_AFTER_LAST
+};
+#endif
diff --git a/libc/kernel/uapi/linux/mrp_bridge.h b/libc/kernel/uapi/linux/mrp_bridge.h
new file mode 100644
index 0000000..cbfc322
--- /dev/null
+++ b/libc/kernel/uapi/linux/mrp_bridge.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_MRP_BRIDGE_H_
+#define _UAPI_LINUX_MRP_BRIDGE_H_
+#include <linux/types.h>
+#include <linux/if_ether.h>
+#define MRP_MAX_FRAME_LENGTH 200
+#define MRP_DEFAULT_PRIO 0x8000
+#define MRP_DOMAIN_UUID_LENGTH 16
+#define MRP_VERSION 1
+#define MRP_FRAME_PRIO 7
+#define MRP_OUI_LENGTH 3
+#define MRP_MANUFACTURE_DATA_LENGTH 2
+enum br_mrp_ring_role_type {
+  BR_MRP_RING_ROLE_DISABLED,
+  BR_MRP_RING_ROLE_MRC,
+  BR_MRP_RING_ROLE_MRM,
+  BR_MRP_RING_ROLE_MRA,
+};
+enum br_mrp_ring_state_type {
+  BR_MRP_RING_STATE_OPEN,
+  BR_MRP_RING_STATE_CLOSED,
+};
+enum br_mrp_port_state_type {
+  BR_MRP_PORT_STATE_DISABLED,
+  BR_MRP_PORT_STATE_BLOCKED,
+  BR_MRP_PORT_STATE_FORWARDING,
+  BR_MRP_PORT_STATE_NOT_CONNECTED,
+};
+enum br_mrp_port_role_type {
+  BR_MRP_PORT_ROLE_PRIMARY,
+  BR_MRP_PORT_ROLE_SECONDARY,
+};
+enum br_mrp_tlv_header_type {
+  BR_MRP_TLV_HEADER_END = 0x0,
+  BR_MRP_TLV_HEADER_COMMON = 0x1,
+  BR_MRP_TLV_HEADER_RING_TEST = 0x2,
+  BR_MRP_TLV_HEADER_RING_TOPO = 0x3,
+  BR_MRP_TLV_HEADER_RING_LINK_DOWN = 0x4,
+  BR_MRP_TLV_HEADER_RING_LINK_UP = 0x5,
+  BR_MRP_TLV_HEADER_OPTION = 0x7f,
+};
+enum br_mrp_sub_tlv_header_type {
+  BR_MRP_SUB_TLV_HEADER_TEST_MGR_NACK = 0x1,
+  BR_MRP_SUB_TLV_HEADER_TEST_PROPAGATE = 0x2,
+  BR_MRP_SUB_TLV_HEADER_TEST_AUTO_MGR = 0x3,
+};
+struct br_mrp_tlv_hdr {
+  __u8 type;
+  __u8 length;
+};
+struct br_mrp_sub_tlv_hdr {
+  __u8 type;
+  __u8 length;
+};
+struct br_mrp_end_hdr {
+  struct br_mrp_tlv_hdr hdr;
+};
+struct br_mrp_common_hdr {
+  __be16 seq_id;
+  __u8 domain[MRP_DOMAIN_UUID_LENGTH];
+};
+struct br_mrp_ring_test_hdr {
+  __be16 prio;
+  __u8 sa[ETH_ALEN];
+  __be16 port_role;
+  __be16 state;
+  __be16 transitions;
+  __be32 timestamp;
+};
+struct br_mrp_ring_topo_hdr {
+  __be16 prio;
+  __u8 sa[ETH_ALEN];
+  __be16 interval;
+};
+struct br_mrp_ring_link_hdr {
+  __u8 sa[ETH_ALEN];
+  __be16 port_role;
+  __be16 interval;
+  __be16 blocked;
+};
+struct br_mrp_sub_opt_hdr {
+  __u8 type;
+  __u8 manufacture_data[MRP_MANUFACTURE_DATA_LENGTH];
+};
+struct br_mrp_test_mgr_nack_hdr {
+  __be16 prio;
+  __u8 sa[ETH_ALEN];
+  __be16 other_prio;
+  __u8 other_sa[ETH_ALEN];
+};
+struct br_mrp_test_prop_hdr {
+  __be16 prio;
+  __u8 sa[ETH_ALEN];
+  __be16 other_prio;
+  __u8 other_sa[ETH_ALEN];
+};
+struct br_mrp_oui_hdr {
+  __u8 oui[MRP_OUI_LENGTH];
+};
+#endif
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
index e47091f..61c8929 100644
--- a/libc/kernel/uapi/linux/ndctl.h
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -158,5 +158,6 @@
 #define NVDIMM_FAMILY_HPE2 2
 #define NVDIMM_FAMILY_MSFT 3
 #define NVDIMM_FAMILY_HYPERV 4
+#define NVDIMM_FAMILY_PAPR 5
 #define ND_IOCTL_CALL _IOWR(ND_IOCTL, ND_CMD_CALL, struct nd_cmd_pkg)
 #endif
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index 4ce4736..eb4babd 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -43,6 +43,7 @@
   NDA_LINK_NETNSID,
   NDA_SRC_VNI,
   NDA_PROTOCOL,
+  NDA_NH_ID,
   __NDA_MAX
 };
 #define NDA_MAX (__NDA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/net_dropmon.h b/libc/kernel/uapi/linux/net_dropmon.h
index a3d9119..01b76cb 100644
--- a/libc/kernel/uapi/linux/net_dropmon.h
+++ b/libc/kernel/uapi/linux/net_dropmon.h
@@ -86,6 +86,7 @@
   NET_DM_ATTR_HW_TRAP_COUNT,
   NET_DM_ATTR_SW_DROPS,
   NET_DM_ATTR_HW_DROPS,
+  NET_DM_ATTR_FLOW_ACTION_COOKIE,
   __NET_DM_ATTR_MAX,
   NET_DM_ATTR_MAX = __NET_DM_ATTR_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 375906a..373d1bb 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -49,6 +49,8 @@
   HWTSTAMP_TX_OFF,
   HWTSTAMP_TX_ON,
   HWTSTAMP_TX_ONESTEP_SYNC,
+  HWTSTAMP_TX_ONESTEP_P2P,
+  __HWTSTAMP_TX_CNT
 };
 enum hwtstamp_rx_filters {
   HWTSTAMP_FILTER_NONE,
@@ -67,6 +69,7 @@
   HWTSTAMP_FILTER_PTP_V2_SYNC,
   HWTSTAMP_FILTER_PTP_V2_DELAY_REQ,
   HWTSTAMP_FILTER_NTP_ALL,
+  __HWTSTAMP_FILTER_CNT
 };
 struct scm_ts_pktinfo {
   __u32 if_index;
diff --git a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
index 43d60ca..3ff6030 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
@@ -64,8 +64,10 @@
   IPS_HELPER = (1 << IPS_HELPER_BIT),
   IPS_OFFLOAD_BIT = 14,
   IPS_OFFLOAD = (1 << IPS_OFFLOAD_BIT),
-  IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK | IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING | IPS_SEQ_ADJUST | IPS_TEMPLATE | IPS_OFFLOAD),
-  __IPS_MAX_BIT = 15,
+  IPS_HW_OFFLOAD_BIT = 15,
+  IPS_HW_OFFLOAD = (1 << IPS_HW_OFFLOAD_BIT),
+  IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK | IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING | IPS_SEQ_ADJUST | IPS_TEMPLATE | IPS_UNTRACKED | IPS_OFFLOAD | IPS_HW_OFFLOAD),
+  __IPS_MAX_BIT = 16,
 };
 enum ip_conntrack_events {
   IPCT_NEW,
diff --git a/libc/kernel/uapi/linux/netfilter/nf_nat.h b/libc/kernel/uapi/linux/netfilter/nf_nat.h
index f01669b..84373ed 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_nat.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_nat.h
@@ -26,8 +26,9 @@
 #define NF_NAT_RANGE_PERSISTENT (1 << 3)
 #define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4)
 #define NF_NAT_RANGE_PROTO_OFFSET (1 << 5)
+#define NF_NAT_RANGE_NETMAP (1 << 6)
 #define NF_NAT_RANGE_PROTO_RANDOM_ALL (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
-#define NF_NAT_RANGE_MASK (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET)
+#define NF_NAT_RANGE_MASK (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | NF_NAT_RANGE_NETMAP)
 struct nf_nat_ipv4_range {
   unsigned int flags;
   __be32 min_ip;
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 2fe11b0..6d3ec0a 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -52,6 +52,7 @@
 #define NFT_REG_MAX (__NFT_REG_MAX - 1)
 #define NFT_REG_SIZE 16
 #define NFT_REG32_SIZE 4
+#define NFT_REG32_COUNT (NFT_REG32_15 - NFT_REG32_00 + 1)
 enum nft_verdicts {
   NFT_CONTINUE = - 1,
   NFT_BREAK = - 2,
@@ -164,6 +165,7 @@
   NFT_SET_TIMEOUT = 0x10,
   NFT_SET_EVAL = 0x20,
   NFT_SET_OBJECT = 0x40,
+  NFT_SET_CONCAT = 0x80,
 };
 enum nft_set_policies {
   NFT_SET_POL_PERFORMANCE,
@@ -172,9 +174,16 @@
 enum nft_set_desc_attributes {
   NFTA_SET_DESC_UNSPEC,
   NFTA_SET_DESC_SIZE,
+  NFTA_SET_DESC_CONCAT,
   __NFTA_SET_DESC_MAX
 };
 #define NFTA_SET_DESC_MAX (__NFTA_SET_DESC_MAX - 1)
+enum nft_set_field_attributes {
+  NFTA_SET_FIELD_UNSPEC,
+  NFTA_SET_FIELD_LEN,
+  __NFTA_SET_FIELD_MAX
+};
+#define NFTA_SET_FIELD_MAX (__NFTA_SET_FIELD_MAX - 1)
 enum nft_set_attributes {
   NFTA_SET_UNSPEC,
   NFTA_SET_TABLE,
@@ -193,6 +202,7 @@
   NFTA_SET_PAD,
   NFTA_SET_OBJ_TYPE,
   NFTA_SET_HANDLE,
+  NFTA_SET_EXPR,
   __NFTA_SET_MAX
 };
 #define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
@@ -210,6 +220,7 @@
   NFTA_SET_ELEM_EXPR,
   NFTA_SET_ELEM_PAD,
   NFTA_SET_ELEM_OBJREF,
+  NFTA_SET_ELEM_KEY_END,
   __NFTA_SET_ELEM_MAX
 };
 #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
@@ -256,6 +267,11 @@
   __NFTA_IMMEDIATE_MAX
 };
 #define NFTA_IMMEDIATE_MAX (__NFTA_IMMEDIATE_MAX - 1)
+enum nft_bitwise_ops {
+  NFT_BITWISE_BOOL,
+  NFT_BITWISE_LSHIFT,
+  NFT_BITWISE_RSHIFT,
+};
 enum nft_bitwise_attributes {
   NFTA_BITWISE_UNSPEC,
   NFTA_BITWISE_SREG,
@@ -263,6 +279,8 @@
   NFTA_BITWISE_LEN,
   NFTA_BITWISE_MASK,
   NFTA_BITWISE_XOR,
+  NFTA_BITWISE_OP,
+  NFTA_BITWISE_DATA,
   __NFTA_BITWISE_MAX
 };
 #define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1)
@@ -425,6 +443,8 @@
   NFT_META_TIME_NS,
   NFT_META_TIME_DAY,
   NFT_META_TIME_HOUR,
+  NFT_META_SDIF,
+  NFT_META_SDIFNAME,
 };
 enum nft_rt_keys {
   NFT_RT_CLASSID,
@@ -784,6 +804,11 @@
   __NFTA_OBJ_MAX
 };
 #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1)
+enum nft_flowtable_flags {
+  NFT_FLOWTABLE_HW_OFFLOAD = 0x1,
+  NFT_FLOWTABLE_COUNTER = 0x2,
+  NFT_FLOWTABLE_MASK = (NFT_FLOWTABLE_HW_OFFLOAD | NFT_FLOWTABLE_COUNTER)
+};
 enum nft_flowtable_attributes {
   NFTA_FLOWTABLE_UNSPEC,
   NFTA_FLOWTABLE_TABLE,
@@ -915,6 +940,7 @@
   NFTA_TUNNEL_KEY_OPTS_UNSPEC,
   NFTA_TUNNEL_KEY_OPTS_VXLAN,
   NFTA_TUNNEL_KEY_OPTS_ERSPAN,
+  NFTA_TUNNEL_KEY_OPTS_GENEVE,
   __NFTA_TUNNEL_KEY_OPTS_MAX
 };
 #define NFTA_TUNNEL_KEY_OPTS_MAX (__NFTA_TUNNEL_KEY_OPTS_MAX - 1)
@@ -933,6 +959,14 @@
   __NFTA_TUNNEL_KEY_ERSPAN_MAX
 };
 #define NFTA_TUNNEL_KEY_ERSPAN_MAX (__NFTA_TUNNEL_KEY_ERSPAN_MAX - 1)
+enum nft_tunnel_opts_geneve_attributes {
+  NFTA_TUNNEL_KEY_GENEVE_UNSPEC,
+  NFTA_TUNNEL_KEY_GENEVE_CLASS,
+  NFTA_TUNNEL_KEY_GENEVE_TYPE,
+  NFTA_TUNNEL_KEY_GENEVE_DATA,
+  __NFTA_TUNNEL_KEY_GENEVE_MAX
+};
+#define NFTA_TUNNEL_KEY_GENEVE_MAX (__NFTA_TUNNEL_KEY_GENEVE_MAX - 1)
 enum nft_tunnel_flags {
   NFT_TUNNEL_F_ZERO_CSUM_TX = (1 << 0),
   NFT_TUNNEL_F_DONT_FRAGMENT = (1 << 1),
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
index 4981fc1..8e48f80 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_conntrack.h
@@ -66,6 +66,7 @@
   CTA_LABELS,
   CTA_LABELS_MASK,
   CTA_SYNPROXY,
+  CTA_FILTER,
   __CTA_MAX
 };
 #define CTA_MAX (__CTA_MAX - 1)
@@ -265,4 +266,11 @@
   __CTA_STATS_EXP_MAX,
 };
 #define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1)
+enum ctattr_filter {
+  CTA_FILTER_UNSPEC,
+  CTA_FILTER_ORIG_FLAGS,
+  CTA_FILTER_REPLY_FLAGS,
+  __CTA_FILTER_MAX
+};
+#define CTA_FILTER_MAX (__CTA_FILTER_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/xt_IDLETIMER.h b/libc/kernel/uapi/linux/netfilter/xt_IDLETIMER.h
index e1f0e33..a59ae09 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_IDLETIMER.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_IDLETIMER.h
@@ -20,6 +20,7 @@
 #define _XT_IDLETIMER_H
 #include <linux/types.h>
 #define MAX_IDLETIMER_LABEL_SIZE 28
+#define XT_IDLETIMER_ALARM 0x01
 #define NLMSG_MAX_SIZE 64
 #define NL_EVENT_TYPE_INACTIVE 0
 #define NL_EVENT_TYPE_ACTIVE 1
@@ -29,4 +30,11 @@
   __u8 send_nl_msg;
   struct idletimer_tg * timer __attribute__((aligned(8)));
 };
+struct idletimer_tg_info_v1 {
+  __u32 timeout;
+  char label[MAX_IDLETIMER_LABEL_SIZE];
+  __u8 send_nl_msg;
+  __u8 timer_type;
+  struct idletimer_tg * timer __attribute__((aligned(8)));
+};
 #endif
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index 4c0fd1f..acbf884 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -159,4 +159,38 @@
   __u32 value;
   __u32 selector;
 };
+enum netlink_attribute_type {
+  NL_ATTR_TYPE_INVALID,
+  NL_ATTR_TYPE_FLAG,
+  NL_ATTR_TYPE_U8,
+  NL_ATTR_TYPE_U16,
+  NL_ATTR_TYPE_U32,
+  NL_ATTR_TYPE_U64,
+  NL_ATTR_TYPE_S8,
+  NL_ATTR_TYPE_S16,
+  NL_ATTR_TYPE_S32,
+  NL_ATTR_TYPE_S64,
+  NL_ATTR_TYPE_BINARY,
+  NL_ATTR_TYPE_STRING,
+  NL_ATTR_TYPE_NUL_STRING,
+  NL_ATTR_TYPE_NESTED,
+  NL_ATTR_TYPE_NESTED_ARRAY,
+  NL_ATTR_TYPE_BITFIELD32,
+};
+enum netlink_policy_type_attr {
+  NL_POLICY_TYPE_ATTR_UNSPEC,
+  NL_POLICY_TYPE_ATTR_TYPE,
+  NL_POLICY_TYPE_ATTR_MIN_VALUE_S,
+  NL_POLICY_TYPE_ATTR_MAX_VALUE_S,
+  NL_POLICY_TYPE_ATTR_MIN_VALUE_U,
+  NL_POLICY_TYPE_ATTR_MAX_VALUE_U,
+  NL_POLICY_TYPE_ATTR_MIN_LENGTH,
+  NL_POLICY_TYPE_ATTR_MAX_LENGTH,
+  NL_POLICY_TYPE_ATTR_POLICY_IDX,
+  NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
+  NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
+  NL_POLICY_TYPE_ATTR_PAD,
+  __NL_POLICY_TYPE_ATTR_MAX,
+  NL_POLICY_TYPE_ATTR_MAX = __NL_POLICY_TYPE_ATTR_MAX - 1
+};
 #endif
diff --git a/libc/kernel/uapi/linux/nexthop.h b/libc/kernel/uapi/linux/nexthop.h
index a2a959f..f99a074 100644
--- a/libc/kernel/uapi/linux/nexthop.h
+++ b/libc/kernel/uapi/linux/nexthop.h
@@ -49,6 +49,7 @@
   NHA_ENCAP,
   NHA_GROUPS,
   NHA_MASTER,
+  NHA_FDB,
   __NHA_MAX,
 };
 #define NHA_MAX (__NHA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 9292571..75d51c9 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -174,6 +174,9 @@
   NL80211_CMD_NOTIFY_RADAR,
   NL80211_CMD_UPDATE_OWE_INFO,
   NL80211_CMD_PROBE_MESH_LINK,
+  NL80211_CMD_SET_TID_CONFIG,
+  NL80211_CMD_UNPROT_BEACON,
+  NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -473,6 +476,17 @@
   NL80211_ATTR_WIPHY_EDMG_CHANNELS,
   NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
   NL80211_ATTR_VLAN_ID,
+  NL80211_ATTR_HE_BSS_COLOR,
+  NL80211_ATTR_IFTYPE_AKM_SUITES,
+  NL80211_ATTR_TID_CONFIG,
+  NL80211_ATTR_CONTROL_PORT_NO_PREAUTH,
+  NL80211_ATTR_PMK_LIFETIME,
+  NL80211_ATTR_PMK_REAUTH_THRESHOLD,
+  NL80211_ATTR_RECEIVE_MULTICAST,
+  NL80211_ATTR_WIPHY_FREQ_OFFSET,
+  NL80211_ATTR_CENTER_FREQ1_OFFSET,
+  NL80211_ATTR_SCAN_FREQ_KHZ,
+  NL80211_ATTR_HE_6GHZ_CAPABILITY,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -706,6 +720,7 @@
   NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
   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_AFTER_LAST,
   NL80211_BAND_IFTYPE_ATTR_MAX = __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST - 1
 };
@@ -755,6 +770,8 @@
   NL80211_FREQUENCY_ATTR_NO_20MHZ,
   NL80211_FREQUENCY_ATTR_NO_10MHZ,
   NL80211_FREQUENCY_ATTR_WMM,
+  NL80211_FREQUENCY_ATTR_NO_HE,
+  NL80211_FREQUENCY_ATTR_OFFSET,
   __NL80211_FREQUENCY_ATTR_AFTER_LAST,
   NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
 };
@@ -822,6 +839,7 @@
   NL80211_RRF_NO_HT40PLUS = 1 << 14,
   NL80211_RRF_NO_80MHZ = 1 << 15,
   NL80211_RRF_NO_160MHZ = 1 << 16,
+  NL80211_RRF_NO_HE = 1 << 17,
 };
 #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
 #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
@@ -996,6 +1014,7 @@
   NL80211_BSS_PARENT_TSF,
   NL80211_BSS_PARENT_BSSID,
   NL80211_BSS_CHAIN_SIGNAL,
+  NL80211_BSS_FREQUENCY_OFFSET,
   __NL80211_BSS_AFTER_LAST,
   NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
 };
@@ -1050,6 +1069,7 @@
   NL80211_KEY_TYPE,
   NL80211_KEY_DEFAULT_TYPES,
   NL80211_KEY_MODE,
+  NL80211_KEY_DEFAULT_BEACON,
   __NL80211_KEY_AFTER_LAST,
   NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
 };
@@ -1107,6 +1127,33 @@
   NL80211_TX_POWER_LIMITED,
   NL80211_TX_POWER_FIXED,
 };
+enum nl80211_tid_config {
+  NL80211_TID_CONFIG_ENABLE,
+  NL80211_TID_CONFIG_DISABLE,
+};
+enum nl80211_tx_rate_setting {
+  NL80211_TX_RATE_AUTOMATIC,
+  NL80211_TX_RATE_LIMITED,
+  NL80211_TX_RATE_FIXED,
+};
+enum nl80211_tid_config_attr {
+  __NL80211_TID_CONFIG_ATTR_INVALID,
+  NL80211_TID_CONFIG_ATTR_PAD,
+  NL80211_TID_CONFIG_ATTR_VIF_SUPP,
+  NL80211_TID_CONFIG_ATTR_PEER_SUPP,
+  NL80211_TID_CONFIG_ATTR_OVERRIDE,
+  NL80211_TID_CONFIG_ATTR_TIDS,
+  NL80211_TID_CONFIG_ATTR_NOACK,
+  NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
+  NL80211_TID_CONFIG_ATTR_RETRY_LONG,
+  NL80211_TID_CONFIG_ATTR_AMPDU_CTRL,
+  NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL,
+  NL80211_TID_CONFIG_ATTR_AMSDU_CTRL,
+  NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE,
+  NL80211_TID_CONFIG_ATTR_TX_RATE,
+  __NL80211_TID_CONFIG_ATTR_AFTER_LAST,
+  NL80211_TID_CONFIG_ATTR_MAX = __NL80211_TID_CONFIG_ATTR_AFTER_LAST - 1
+};
 enum nl80211_packet_pattern_attr {
   __NL80211_PKTPAT_INVALID,
   NL80211_PKTPAT_MASK,
@@ -1233,12 +1280,15 @@
 };
 #define NL80211_KCK_LEN 16
 #define NL80211_KEK_LEN 16
+#define NL80211_KCK_EXT_LEN 24
+#define NL80211_KEK_EXT_LEN 32
 #define NL80211_REPLAY_CTR_LEN 8
 enum nl80211_rekey_data {
   __NL80211_REKEY_DATA_INVALID,
   NL80211_REKEY_DATA_KEK,
   NL80211_REKEY_DATA_KCK,
   NL80211_REKEY_DATA_REPLAY_CTR,
+  NL80211_REKEY_DATA_AKM,
   NUM_NL80211_REKEY_DATA,
   MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1
 };
@@ -1345,6 +1395,14 @@
   NL80211_EXT_FEATURE_SAE_OFFLOAD,
   NL80211_EXT_FEATURE_VLAN_OFFLOAD,
   NL80211_EXT_FEATURE_AQL,
+  NL80211_EXT_FEATURE_BEACON_PROTECTION,
+  NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH,
+  NL80211_EXT_FEATURE_PROTECTED_TWT,
+  NL80211_EXT_FEATURE_DEL_IBSS_STA,
+  NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS,
+  NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT,
+  NL80211_EXT_FEATURE_SCAN_FREQ_KHZ,
+  NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
@@ -1378,6 +1436,7 @@
   NL80211_SCAN_FLAG_HIGH_ACCURACY = 1 << 10,
   NL80211_SCAN_FLAG_RANDOM_SN = 1 << 11,
   NL80211_SCAN_FLAG_MIN_PREQ_CONTENT = 1 << 12,
+  NL80211_SCAN_FLAG_FREQ_KHZ = 1 << 13,
 };
 enum nl80211_acl_policy {
   NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED,
@@ -1535,6 +1594,7 @@
   NL80211_PREAMBLE_HT,
   NL80211_PREAMBLE_VHT,
   NL80211_PREAMBLE_DMG,
+  NL80211_PREAMBLE_HE,
 };
 enum nl80211_peer_measurement_type {
   NL80211_PMSR_TYPE_INVALID,
@@ -1595,6 +1655,8 @@
   NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
   NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
   NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
+  NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED,
+  NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED,
   NUM_NL80211_PMSR_FTM_CAPA_ATTR,
   NL80211_PMSR_FTM_CAPA_ATTR_MAX = NUM_NL80211_PMSR_FTM_CAPA_ATTR - 1
 };
@@ -1609,6 +1671,8 @@
   NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES,
   NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI,
   NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
+  NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
+  NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
   NUM_NL80211_PMSR_FTM_REQ_ATTR,
   NL80211_PMSR_FTM_REQ_ATTR_MAX = NUM_NL80211_PMSR_FTM_REQ_ATTR - 1
 };
@@ -1655,4 +1719,19 @@
   __NL80211_HE_OBSS_PD_ATTR_LAST,
   NL80211_HE_OBSS_PD_ATTR_MAX = __NL80211_HE_OBSS_PD_ATTR_LAST - 1,
 };
+enum nl80211_bss_color_attributes {
+  __NL80211_HE_BSS_COLOR_ATTR_INVALID,
+  NL80211_HE_BSS_COLOR_ATTR_COLOR,
+  NL80211_HE_BSS_COLOR_ATTR_DISABLED,
+  NL80211_HE_BSS_COLOR_ATTR_PARTIAL,
+  __NL80211_HE_BSS_COLOR_ATTR_LAST,
+  NL80211_HE_BSS_COLOR_ATTR_MAX = __NL80211_HE_BSS_COLOR_ATTR_LAST - 1,
+};
+enum nl80211_iftype_akm_attributes {
+  __NL80211_IFTYPE_AKM_ATTR_INVALID,
+  NL80211_IFTYPE_AKM_ATTR_IFTYPES,
+  NL80211_IFTYPE_AKM_ATTR_SUITES,
+  __NL80211_IFTYPE_AKM_ATTR_LAST,
+  NL80211_IFTYPE_AKM_ATTR_MAX = __NL80211_IFTYPE_AKM_ATTR_LAST - 1,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/hysdn_if.h b/libc/kernel/uapi/linux/openat2.h
similarity index 72%
copy from libc/kernel/uapi/linux/hysdn_if.h
copy to libc/kernel/uapi/linux/openat2.h
index 2aac1d0..27136af 100644
--- a/libc/kernel/uapi/linux/hysdn_if.h
+++ b/libc/kernel/uapi/linux/openat2.h
@@ -16,16 +16,17 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define ERR_NONE 0
-#define ERR_ALREADY_BOOT 1000
-#define EPOF_BAD_MAGIC 1001
-#define ERR_BOARD_DPRAM 1002
-#define EPOF_INTERNAL 1003
-#define EPOF_BAD_IMG_SIZE 1004
-#define ERR_BOOTIMG_FAIL 1005
-#define ERR_BOOTSEQ_FAIL 1006
-#define ERR_POF_TIMEOUT 1007
-#define ERR_NOT_BOOTED 1008
-#define ERR_CONF_LONG 1009
-#define ERR_INV_CHAN 1010
-#define ERR_ASYNC_TIME 1011
+#ifndef _UAPI_LINUX_OPENAT2_H
+#define _UAPI_LINUX_OPENAT2_H
+#include <linux/types.h>
+struct open_how {
+  __u64 flags;
+  __u64 mode;
+  __u64 resolve;
+};
+#define RESOLVE_NO_XDEV 0x01
+#define RESOLVE_NO_MAGICLINKS 0x02
+#define RESOLVE_NO_SYMLINKS 0x04
+#define RESOLVE_BENEATH 0x08
+#define RESOLVE_IN_ROOT 0x10
+#endif
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 99a987d..5dba4e6 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -366,6 +366,12 @@
   __be32 mpls_lse;
   __be16 mpls_ethertype;
 };
+struct ovs_action_add_mpls {
+  __be32 mpls_lse;
+  __be16 mpls_ethertype;
+  __u16 tun_flags;
+};
+#define OVS_MPLS_L3_TUNNEL_FLAG_MASK (1 << 0)
 struct ovs_action_push_vlan {
   __be16 vlan_tpid;
   __be16 vlan_tci;
@@ -439,6 +445,8 @@
   OVS_ACTION_ATTR_METER,
   OVS_ACTION_ATTR_CLONE,
   OVS_ACTION_ATTR_CHECK_PKT_LEN,
+  OVS_ACTION_ATTR_ADD_MPLS,
+  OVS_ACTION_ATTR_DEC_TTL,
   __OVS_ACTION_ATTR_MAX,
 };
 #define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1)
@@ -502,4 +510,9 @@
   __u32 limit;
   __u32 count;
 };
+enum ovs_dec_ttl_attr {
+  OVS_DEC_TTL_ATTR_UNSPEC,
+  OVS_DEC_TTL_ATTR_ACTION,
+  __OVS_DEC_TTL_ATTR_MAX
+};
 #endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index 5501de0..f502b80 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -514,6 +514,7 @@
 #define PCI_EXP_SLTCTL_PWR_OFF 0x0400
 #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_ABP 0x0001
 #define PCI_EXP_SLTSTA_PFD 0x0002
@@ -577,9 +578,11 @@
 #define PCI_EXP_LNKCTL2_TLS_32_0GT 0x0005
 #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_SLTCAP2_IBPD 0x00000001
 #define PCI_EXP_SLTCTL2 56
 #define PCI_EXP_SLTSTA2 58
 #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
diff --git a/libc/kernel/uapi/linux/pcitest.h b/libc/kernel/uapi/linux/pcitest.h
index c6112d0..98248bd 100644
--- a/libc/kernel/uapi/linux/pcitest.h
+++ b/libc/kernel/uapi/linux/pcitest.h
@@ -27,4 +27,10 @@
 #define PCITEST_MSIX _IOW('P', 0x7, int)
 #define PCITEST_SET_IRQTYPE _IOW('P', 0x8, int)
 #define PCITEST_GET_IRQTYPE _IO('P', 0x9)
+#define PCITEST_CLEAR_IRQ _IO('P', 0x10)
+#define PCITEST_FLAGS_USE_DMA 0x00000001
+struct pci_endpoint_test_xfer_param {
+  unsigned long size;
+  unsigned char flags;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 4e9e32c..b996adb 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -100,7 +100,8 @@
   PERF_SAMPLE_REGS_INTR = 1U << 18,
   PERF_SAMPLE_PHYS_ADDR = 1U << 19,
   PERF_SAMPLE_AUX = 1U << 20,
-  PERF_SAMPLE_MAX = 1U << 21,
+  PERF_SAMPLE_CGROUP = 1U << 21,
+  PERF_SAMPLE_MAX = 1U << 22,
   __PERF_SAMPLE_CALLCHAIN_EARLY = 1ULL << 63,
 };
 enum perf_branch_sample_type_shift {
@@ -121,6 +122,7 @@
   PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14,
   PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15,
   PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16,
+  PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 17,
   PERF_SAMPLE_BRANCH_MAX_SHIFT
 };
 enum perf_branch_sample_type {
@@ -141,6 +143,7 @@
   PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT,
   PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT,
   PERF_SAMPLE_BRANCH_TYPE_SAVE = 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT,
+  PERF_SAMPLE_BRANCH_HW_INDEX = 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
   PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
 };
 enum {
@@ -200,7 +203,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, __reserved_1 : 32;
+  __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, __reserved_1 : 31;
   union {
     __u32 wakeup_events;
     __u32 wakeup_watermark;
@@ -332,6 +335,7 @@
   PERF_RECORD_NAMESPACES = 16,
   PERF_RECORD_KSYMBOL = 17,
   PERF_RECORD_BPF_EVENT = 18,
+  PERF_RECORD_CGROUP = 19,
   PERF_RECORD_MAX,
 };
 enum perf_record_ksymbol_type {
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index dd096d9..a5e8149 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -30,9 +30,13 @@
   TCA_ACT_PAD,
   TCA_ACT_COOKIE,
   TCA_ACT_FLAGS,
+  TCA_ACT_HW_STATS,
+  TCA_ACT_USED_HW_STATS,
   __TCA_ACT_MAX
 };
 #define TCA_ACT_FLAGS_NO_PERCPU_STATS 1
+#define TCA_ACT_HW_STATS_IMMEDIATE (1 << 0)
+#define TCA_ACT_HW_STATS_DELAYED (1 << 1)
 #define TCA_ACT_MAX __TCA_ACT_MAX
 #define TCA_OLD_COMPAT (TCA_ACT_MAX + 1)
 #define TCA_ACT_MAX_PRIO 32
@@ -99,6 +103,7 @@
   TCA_ID_CTINFO,
   TCA_ID_MPLS,
   TCA_ID_CT,
+  TCA_ID_GATE,
   __TCA_ID_MAX = 255
 };
 #define TCA_ID_MAX __TCA_ID_MAX
@@ -446,6 +451,7 @@
   TCA_FLOWER_KEY_CT_MARK_MASK,
   TCA_FLOWER_KEY_CT_LABELS,
   TCA_FLOWER_KEY_CT_LABELS_MASK,
+  TCA_FLOWER_KEY_MPLS_OPTS,
   __TCA_FLOWER_MAX,
 };
 #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
@@ -487,6 +493,22 @@
 };
 #define TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX (__TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX - 1)
 enum {
+  TCA_FLOWER_KEY_MPLS_OPTS_UNSPEC,
+  TCA_FLOWER_KEY_MPLS_OPTS_LSE,
+  __TCA_FLOWER_KEY_MPLS_OPTS_MAX,
+};
+#define TCA_FLOWER_KEY_MPLS_OPTS_MAX (__TCA_FLOWER_KEY_MPLS_OPTS_MAX - 1)
+enum {
+  TCA_FLOWER_KEY_MPLS_OPT_LSE_UNSPEC,
+  TCA_FLOWER_KEY_MPLS_OPT_LSE_DEPTH,
+  TCA_FLOWER_KEY_MPLS_OPT_LSE_TTL,
+  TCA_FLOWER_KEY_MPLS_OPT_LSE_BOS,
+  TCA_FLOWER_KEY_MPLS_OPT_LSE_TC,
+  TCA_FLOWER_KEY_MPLS_OPT_LSE_LABEL,
+  __TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX,
+};
+#define TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX (__TCA_FLOWER_KEY_MPLS_OPT_LSE_MAX - 1)
+enum {
   TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
   TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
 };
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index c965928..9579583 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -167,6 +167,7 @@
   TCA_RED_PARMS,
   TCA_RED_STAB,
   TCA_RED_MAX_P,
+  TCA_RED_FLAGS,
   __TCA_RED_MAX,
 };
 #define TCA_RED_MAX (__TCA_RED_MAX - 1)
@@ -181,7 +182,9 @@
 #define TC_RED_ECN 1
 #define TC_RED_HARDDROP 2
 #define TC_RED_ADAPTATIVE 4
+#define TC_RED_NODROP 8
 };
+#define TC_RED_HISTORIC_FLAGS (TC_RED_ECN | TC_RED_HARDDROP | TC_RED_ADAPTATIVE)
 struct tc_red_xstats {
   __u32 early;
   __u32 pdrop;
@@ -665,6 +668,9 @@
   TCA_FQ_ORPHAN_MASK,
   TCA_FQ_LOW_RATE_THRESHOLD,
   TCA_FQ_CE_THRESHOLD,
+  TCA_FQ_TIMER_SLACK,
+  TCA_FQ_HORIZON,
+  TCA_FQ_HORIZON_DROP,
   __TCA_FQ_MAX
 };
 #define TCA_FQ_MAX (__TCA_FQ_MAX - 1)
@@ -682,6 +688,8 @@
   __u32 throttled_flows;
   __u32 unthrottle_latency_ns;
   __u64 ce_mark;
+  __u64 horizon_drops;
+  __u64 horizon_caps;
 };
 enum {
   TCA_HHF_UNSPEC,
@@ -725,6 +733,34 @@
   __u32 maxq;
   __u32 ecn_mark;
 };
+enum {
+  TCA_FQ_PIE_UNSPEC,
+  TCA_FQ_PIE_LIMIT,
+  TCA_FQ_PIE_FLOWS,
+  TCA_FQ_PIE_TARGET,
+  TCA_FQ_PIE_TUPDATE,
+  TCA_FQ_PIE_ALPHA,
+  TCA_FQ_PIE_BETA,
+  TCA_FQ_PIE_QUANTUM,
+  TCA_FQ_PIE_MEMORY_LIMIT,
+  TCA_FQ_PIE_ECN_PROB,
+  TCA_FQ_PIE_ECN,
+  TCA_FQ_PIE_BYTEMODE,
+  TCA_FQ_PIE_DQ_RATE_ESTIMATOR,
+  __TCA_FQ_PIE_MAX
+};
+#define TCA_FQ_PIE_MAX (__TCA_FQ_PIE_MAX - 1)
+struct tc_fq_pie_xstats {
+  __u32 packets_in;
+  __u32 dropped;
+  __u32 overlimit;
+  __u32 overmemory;
+  __u32 ecn_mark;
+  __u32 new_flow_count;
+  __u32 new_flows_len;
+  __u32 old_flows_len;
+  __u32 memory_usage;
+};
 struct tc_cbs_qopt {
   __u8 offload;
   __u8 _pad[3];
@@ -879,8 +915,8 @@
   __TCA_TAPRIO_SCHED_MAX,
 };
 #define TCA_TAPRIO_SCHED_MAX (__TCA_TAPRIO_SCHED_MAX - 1)
-#define TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST BIT(0)
-#define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD BIT(1)
+#define TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST _BITUL(0)
+#define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD _BITUL(1)
 enum {
   TCA_TAPRIO_ATTR_UNSPEC,
   TCA_TAPRIO_ATTR_PRIOMAP,
@@ -897,4 +933,16 @@
   __TCA_TAPRIO_ATTR_MAX,
 };
 #define TCA_TAPRIO_ATTR_MAX (__TCA_TAPRIO_ATTR_MAX - 1)
+#define TCQ_ETS_MAX_BANDS 16
+enum {
+  TCA_ETS_UNSPEC,
+  TCA_ETS_NBANDS,
+  TCA_ETS_NSTRICT,
+  TCA_ETS_QUANTA,
+  TCA_ETS_QUANTA_BAND,
+  TCA_ETS_PRIOMAP,
+  TCA_ETS_PRIOMAP_BAND,
+  __TCA_ETS_MAX,
+};
+#define TCA_ETS_MAX (__TCA_ETS_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 6e3426c..c8118da 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -153,6 +153,8 @@
 #define PR_SET_TAGGED_ADDR_CTRL 55
 #define PR_GET_TAGGED_ADDR_CTRL 56
 #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
+#define PR_SET_IO_FLUSHER 57
+#define PR_GET_IO_FLUSHER 58
 #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 d90956b..1f8b325 100644
--- a/libc/kernel/uapi/linux/psample.h
+++ b/libc/kernel/uapi/linux/psample.h
@@ -26,6 +26,7 @@
   PSAMPLE_ATTR_GROUP_SEQ,
   PSAMPLE_ATTR_SAMPLE_RATE,
   PSAMPLE_ATTR_DATA,
+  PSAMPLE_ATTR_TUNNEL,
   PSAMPLE_ATTR_GROUP_REFCOUNT,
   __PSAMPLE_ATTR_MAX
 };
@@ -35,6 +36,26 @@
   PSAMPLE_CMD_NEW_GROUP,
   PSAMPLE_CMD_DEL_GROUP,
 };
+enum psample_tunnel_key_attr {
+  PSAMPLE_TUNNEL_KEY_ATTR_ID,
+  PSAMPLE_TUNNEL_KEY_ATTR_IPV4_SRC,
+  PSAMPLE_TUNNEL_KEY_ATTR_IPV4_DST,
+  PSAMPLE_TUNNEL_KEY_ATTR_TOS,
+  PSAMPLE_TUNNEL_KEY_ATTR_TTL,
+  PSAMPLE_TUNNEL_KEY_ATTR_DONT_FRAGMENT,
+  PSAMPLE_TUNNEL_KEY_ATTR_CSUM,
+  PSAMPLE_TUNNEL_KEY_ATTR_OAM,
+  PSAMPLE_TUNNEL_KEY_ATTR_GENEVE_OPTS,
+  PSAMPLE_TUNNEL_KEY_ATTR_TP_SRC,
+  PSAMPLE_TUNNEL_KEY_ATTR_TP_DST,
+  PSAMPLE_TUNNEL_KEY_ATTR_VXLAN_OPTS,
+  PSAMPLE_TUNNEL_KEY_ATTR_IPV6_SRC,
+  PSAMPLE_TUNNEL_KEY_ATTR_IPV6_DST,
+  PSAMPLE_TUNNEL_KEY_ATTR_PAD,
+  PSAMPLE_TUNNEL_KEY_ATTR_ERSPAN_OPTS,
+  PSAMPLE_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE,
+  __PSAMPLE_TUNNEL_KEY_ATTR_MAX
+};
 #define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
 #define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
 #define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
diff --git a/libc/kernel/uapi/linux/psp-sev.h b/libc/kernel/uapi/linux/psp-sev.h
index fcdb102..6c4f73d 100644
--- a/libc/kernel/uapi/linux/psp-sev.h
+++ b/libc/kernel/uapi/linux/psp-sev.h
@@ -67,6 +67,7 @@
   __u8 build;
   __u32 guest_count;
 } __packed;
+#define SEV_STATUS_FLAGS_CONFIG_ES 0x0100
 struct sev_user_data_pek_csr {
   __u64 address;
   __u32 length;
diff --git a/libc/kernel/uapi/linux/ptp_clock.h b/libc/kernel/uapi/linux/ptp_clock.h
index 8618101..3d0dc24 100644
--- a/libc/kernel/uapi/linux/ptp_clock.h
+++ b/libc/kernel/uapi/linux/ptp_clock.h
@@ -43,7 +43,8 @@
   int pps;
   int n_pins;
   int cross_timestamping;
-  int rsv[13];
+  int adjust_phase;
+  int rsv[12];
 };
 struct ptp_extts_request {
   unsigned int index;
diff --git a/libc/kernel/uapi/linux/random.h b/libc/kernel/uapi/linux/random.h
index 3a5fbfd..2d3cfef 100644
--- a/libc/kernel/uapi/linux/random.h
+++ b/libc/kernel/uapi/linux/random.h
@@ -35,4 +35,5 @@
 };
 #define GRND_NONBLOCK 0x0001
 #define GRND_RANDOM 0x0002
+#define GRND_INSECURE 0x0004
 #endif
diff --git a/libc/kernel/uapi/linux/rds.h b/libc/kernel/uapi/linux/rds.h
index 537aab5..bc29233 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -32,10 +32,11 @@
 #define SO_RDS_TRANSPORT 8
 #define SO_RDS_MSG_RXPATH_LATENCY 10
 #define RDS_TRANS_IB 0
-#define RDS_TRANS_IWARP 1
+#define RDS_TRANS_GAP 1
 #define RDS_TRANS_TCP 2
 #define RDS_TRANS_COUNT 3
 #define RDS_TRANS_NONE (~0)
+#define RDS_TRANS_IWARP RDS_TRANS_GAP
 #define SIOCRDSSETTOS (SIOCPROTOPRIVATE)
 #define SIOCRDSGETTOS (SIOCPROTOPRIVATE + 1)
 typedef __u8 rds_tos_t;
diff --git a/libc/kernel/uapi/linux/gigaset_dev.h b/libc/kernel/uapi/linux/rpl.h
similarity index 60%
copy from libc/kernel/uapi/linux/gigaset_dev.h
copy to libc/kernel/uapi/linux/rpl.h
index 5741d7d..4437731 100644
--- a/libc/kernel/uapi/linux/gigaset_dev.h
+++ b/libc/kernel/uapi/linux/rpl.h
@@ -16,15 +16,28 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef GIGASET_INTERFACE_H
-#define GIGASET_INTERFACE_H
-#include <linux/ioctl.h>
-#define GIGASET_IOCTL 0x47
-#define GIGASET_REDIR _IOWR(GIGASET_IOCTL, 0, int)
-#define GIGASET_CONFIG _IOWR(GIGASET_IOCTL, 1, int)
-#define GIGASET_BRKCHARS _IOW(GIGASET_IOCTL, 2, unsigned char[6])
-#define GIGASET_VERSION _IOWR(GIGASET_IOCTL, 3, unsigned[4])
-#define GIGVER_DRIVER 0
-#define GIGVER_COMPAT 1
-#define GIGVER_FWBASE 2
+#ifndef _UAPI_LINUX_RPL_H
+#define _UAPI_LINUX_RPL_H
+#include <asm/byteorder.h>
+#include <linux/types.h>
+#include <linux/in6.h>
+struct ipv6_rpl_sr_hdr {
+  __u8 nexthdr;
+  __u8 hdrlen;
+  __u8 type;
+  __u8 segments_left;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+  __u32 cmpre : 4, cmpri : 4, reserved : 4, pad : 4, reserved1 : 16;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+  __u32 reserved : 20, pad : 4, cmpri : 4, cmpre : 4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+  union {
+    struct in6_addr addr[0];
+    __u8 data[0];
+  } segments;
+} __attribute__((packed));
+#define rpl_segaddr segments.addr
+#define rpl_segdata segments.data
 #endif
diff --git a/libc/kernel/uapi/linux/hysdn_if.h b/libc/kernel/uapi/linux/rpl_iptunnel.h
similarity index 72%
rename from libc/kernel/uapi/linux/hysdn_if.h
rename to libc/kernel/uapi/linux/rpl_iptunnel.h
index 2aac1d0..c61725d 100644
--- a/libc/kernel/uapi/linux/hysdn_if.h
+++ b/libc/kernel/uapi/linux/rpl_iptunnel.h
@@ -16,16 +16,13 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define ERR_NONE 0
-#define ERR_ALREADY_BOOT 1000
-#define EPOF_BAD_MAGIC 1001
-#define ERR_BOARD_DPRAM 1002
-#define EPOF_INTERNAL 1003
-#define EPOF_BAD_IMG_SIZE 1004
-#define ERR_BOOTIMG_FAIL 1005
-#define ERR_BOOTSEQ_FAIL 1006
-#define ERR_POF_TIMEOUT 1007
-#define ERR_NOT_BOOTED 1008
-#define ERR_CONF_LONG 1009
-#define ERR_INV_CHAN 1010
-#define ERR_ASYNC_TIME 1011
+#ifndef _UAPI_LINUX_RPL_IPTUNNEL_H
+#define _UAPI_LINUX_RPL_IPTUNNEL_H
+enum {
+  RPL_IPTUNNEL_UNSPEC,
+  RPL_IPTUNNEL_SRH,
+  __RPL_IPTUNNEL_MAX,
+};
+#define RPL_IPTUNNEL_MAX (__RPL_IPTUNNEL_MAX - 1)
+#define RPL_IPTUNNEL_SRH_SIZE(srh) (((srh)->hdrlen + 1) << 3)
+#endif
diff --git a/libc/kernel/uapi/linux/rtc.h b/libc/kernel/uapi/linux/rtc.h
index a047293..8e70eba 100644
--- a/libc/kernel/uapi/linux/rtc.h
+++ b/libc/kernel/uapi/linux/rtc.h
@@ -18,6 +18,8 @@
  ****************************************************************************/
 #ifndef _UAPI_LINUX_RTC_H_
 #define _UAPI_LINUX_RTC_H_
+#include <linux/const.h>
+#include <linux/ioctl.h>
 struct rtc_time {
   int tm_sec;
   int tm_min;
@@ -63,7 +65,12 @@
 #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_VL_READ _IOR('p', 0x13, int)
+#define RTC_VL_DATA_INVALID _BITUL(0)
+#define RTC_VL_BACKUP_LOW _BITUL(1)
+#define RTC_VL_BACKUP_EMPTY _BITUL(2)
+#define RTC_VL_ACCURACY_LOW _BITUL(3)
+#define RTC_VL_BACKUP_SWITCH _BITUL(4)
+#define RTC_VL_READ _IOR('p', 0x13, unsigned int)
 #define RTC_VL_CLR _IO('p', 0x14)
 #define RTC_IRQF 0x80
 #define RTC_PF 0x40
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index 14366de..f7be4a5 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -151,6 +151,12 @@
 #define RTM_DELLINKPROP RTM_DELLINKPROP
   RTM_GETLINKPROP,
 #define RTM_GETLINKPROP RTM_GETLINKPROP
+  RTM_NEWVLAN = 112,
+#define RTM_NEWNVLAN RTM_NEWVLAN
+  RTM_DELVLAN,
+#define RTM_DELVLAN RTM_DELVLAN
+  RTM_GETVLAN,
+#define RTM_GETVLAN RTM_GETVLAN
   __RTM_MAX,
 #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -230,6 +236,8 @@
 #define RTM_F_PREFIX 0x800
 #define RTM_F_LOOKUP_TABLE 0x1000
 #define RTM_F_FIB_MATCH 0x2000
+#define RTM_F_OFFLOAD 0x4000
+#define RTM_F_TRAP 0x8000
 enum rt_class_t {
   RT_TABLE_UNSPEC = 0,
   RT_TABLE_COMPAT = 252,
@@ -436,9 +444,11 @@
   TCA_HW_OFFLOAD,
   TCA_INGRESS_BLOCK,
   TCA_EGRESS_BLOCK,
+  TCA_DUMP_FLAGS,
   __TCA_MAX
 };
 #define TCA_MAX (__TCA_MAX - 1)
+#define TCA_DUMP_FLAGS_TERSE (1 << 0)
 #define TCA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
 #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct tcmsg))
 struct nduseroptmsg {
@@ -537,6 +547,8 @@
 #define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
   RTNLGRP_NEXTHOP,
 #define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
+  RTNLGRP_BRVLAN,
+#define RTNLGRP_BRVLAN RTNLGRP_BRVLAN
   __RTNLGRP_MAX
 };
 #define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/sched.h b/libc/kernel/uapi/linux/sched.h
index b8f39dd..f9c00df 100644
--- a/libc/kernel/uapi/linux/sched.h
+++ b/libc/kernel/uapi/linux/sched.h
@@ -45,6 +45,8 @@
 #define CLONE_NEWNET 0x40000000
 #define CLONE_IO 0x80000000
 #define CLONE_CLEAR_SIGHAND 0x100000000ULL
+#define CLONE_INTO_CGROUP 0x200000000ULL
+#define CLONE_NEWTIME 0x00000080
 #ifndef __ASSEMBLY__
 struct clone_args {
   __aligned_u64 flags;
@@ -57,10 +59,12 @@
   __aligned_u64 tls;
   __aligned_u64 set_tid;
   __aligned_u64 set_tid_size;
+  __aligned_u64 cgroup;
 };
 #endif
 #define CLONE_ARGS_SIZE_VER0 64
 #define CLONE_ARGS_SIZE_VER1 80
+#define CLONE_ARGS_SIZE_VER2 88
 #define SCHED_NORMAL 0
 #define SCHED_FIFO 1
 #define SCHED_RR 2
diff --git a/libc/kernel/uapi/linux/seccomp.h b/libc/kernel/uapi/linux/seccomp.h
index 6f7cbbe..d535f50 100644
--- a/libc/kernel/uapi/linux/seccomp.h
+++ b/libc/kernel/uapi/linux/seccomp.h
@@ -31,6 +31,7 @@
 #define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
 #define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
 #define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3)
+#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
 #define SECCOMP_RET_KILL_PROCESS 0x80000000U
 #define SECCOMP_RET_KILL_THREAD 0x00000000U
 #define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
diff --git a/libc/kernel/uapi/linux/serio.h b/libc/kernel/uapi/linux/serio.h
index 5ef9de4..605a4e4 100644
--- a/libc/kernel/uapi/linux/serio.h
+++ b/libc/kernel/uapi/linux/serio.h
@@ -18,12 +18,13 @@
  ****************************************************************************/
 #ifndef _UAPI_SERIO_H
 #define _UAPI_SERIO_H
+#include <linux/const.h>
 #include <linux/ioctl.h>
 #define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
-#define SERIO_TIMEOUT BIT(0)
-#define SERIO_PARITY BIT(1)
-#define SERIO_FRAME BIT(2)
-#define SERIO_OOB_DATA BIT(3)
+#define SERIO_TIMEOUT _BITUL(0)
+#define SERIO_PARITY _BITUL(1)
+#define SERIO_FRAME _BITUL(2)
+#define SERIO_OOB_DATA _BITUL(3)
 #define SERIO_XT 0x00
 #define SERIO_8042 0x01
 #define SERIO_RS232 0x02
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 3ec299a..c114544 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -252,6 +252,8 @@
   LINUX_MIB_TCPRCVQDROP,
   LINUX_MIB_TCPWQUEUETOOBIG,
   LINUX_MIB_TCPFASTOPENPASSIVEALTKEY,
+  LINUX_MIB_TCPTIMEOUTREHASH,
+  LINUX_MIB_TCPDUPLICATEDATAREHASH,
   __LINUX_MIB_MAX
 };
 enum {
diff --git a/libc/kernel/uapi/linux/sock_diag.h b/libc/kernel/uapi/linux/sock_diag.h
index 0182597..a4e40d9 100644
--- a/libc/kernel/uapi/linux/sock_diag.h
+++ b/libc/kernel/uapi/linux/sock_diag.h
@@ -46,4 +46,24 @@
   __SKNLGRP_MAX,
 };
 #define SKNLGRP_MAX (__SKNLGRP_MAX - 1)
+enum {
+  SK_DIAG_BPF_STORAGE_REQ_NONE,
+  SK_DIAG_BPF_STORAGE_REQ_MAP_FD,
+  __SK_DIAG_BPF_STORAGE_REQ_MAX,
+};
+#define SK_DIAG_BPF_STORAGE_REQ_MAX (__SK_DIAG_BPF_STORAGE_REQ_MAX - 1)
+enum {
+  SK_DIAG_BPF_STORAGE_REP_NONE,
+  SK_DIAG_BPF_STORAGE,
+  __SK_DIAG_BPF_STORAGE_REP_MAX,
+};
+#define SK_DIAB_BPF_STORAGE_REP_MAX (__SK_DIAG_BPF_STORAGE_REP_MAX - 1)
+enum {
+  SK_DIAG_BPF_STORAGE_NONE,
+  SK_DIAG_BPF_STORAGE_PAD,
+  SK_DIAG_BPF_STORAGE_MAP_ID,
+  SK_DIAG_BPF_STORAGE_MAP_VALUE,
+  __SK_DIAG_BPF_STORAGE_MAX,
+};
+#define SK_DIAG_BPF_STORAGE_MAX (__SK_DIAG_BPF_STORAGE_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/spi/spidev.h b/libc/kernel/uapi/linux/spi/spidev.h
index 343285b..dede0f0 100644
--- a/libc/kernel/uapi/linux/spi/spidev.h
+++ b/libc/kernel/uapi/linux/spi/spidev.h
@@ -36,6 +36,10 @@
 #define SPI_TX_QUAD 0x200
 #define SPI_RX_DUAL 0x400
 #define SPI_RX_QUAD 0x800
+#define SPI_CS_WORD 0x1000
+#define SPI_TX_OCTAL 0x2000
+#define SPI_RX_OCTAL 0x4000
+#define SPI_3WIRE_HIZ 0x8000
 #define SPI_IOC_MAGIC 'k'
 struct spi_ioc_transfer {
   __u64 tx_buf;
diff --git a/libc/kernel/uapi/linux/stat.h b/libc/kernel/uapi/linux/stat.h
index 98fdbea..919763e 100644
--- a/libc/kernel/uapi/linux/stat.h
+++ b/libc/kernel/uapi/linux/stat.h
@@ -77,7 +77,9 @@
   __u32 stx_rdev_minor;
   __u32 stx_dev_major;
   __u32 stx_dev_minor;
-  __u64 __spare2[14];
+  __u64 stx_mnt_id;
+  __u64 __spare2;
+  __u64 __spare3[12];
 };
 #define STATX_TYPE 0x00000001U
 #define STATX_MODE 0x00000002U
@@ -92,13 +94,16 @@
 #define STATX_BLOCKS 0x00000400U
 #define STATX_BASIC_STATS 0x000007ffU
 #define STATX_BTIME 0x00000800U
-#define STATX_ALL 0x00000fffU
+#define STATX_MNT_ID 0x00001000U
 #define STATX__RESERVED 0x80000000U
+#define STATX_ALL 0x00000fffU
 #define STATX_ATTR_COMPRESSED 0x00000004
 #define STATX_ATTR_IMMUTABLE 0x00000010
 #define STATX_ATTR_APPEND 0x00000020
 #define STATX_ATTR_NODUMP 0x00000040
 #define STATX_ATTR_ENCRYPTED 0x00000800
 #define STATX_ATTR_AUTOMOUNT 0x00001000
+#define STATX_ATTR_MOUNT_ROOT 0x00002000
 #define STATX_ATTR_VERITY 0x00100000
+#define STATX_ATTR_DAX 0x00002000
 #endif
diff --git a/libc/kernel/uapi/linux/swab.h b/libc/kernel/uapi/linux/swab.h
index da949db..e96085e 100644
--- a/libc/kernel/uapi/linux/swab.h
+++ b/libc/kernel/uapi/linux/swab.h
@@ -20,6 +20,7 @@
 #define _UAPI_LINUX_SWAB_H
 #include <linux/types.h>
 #include <linux/compiler.h>
+#include <asm/bitsperlong.h>
 #include <asm/swab.h>
 #define ___constant_swab16(x) ((__u16) ((((__u16) (x) & (__u16) 0x00ffU) << 8) | (((__u16) (x) & (__u16) 0xff00U) >> 8)))
 #define ___constant_swab32(x) ((__u32) ((((__u32) (x) & (__u32) 0x000000ffUL) << 24) | (((__u32) (x) & (__u32) 0x0000ff00UL) << 8) | (((__u32) (x) & (__u32) 0x00ff0000UL) >> 8) | (((__u32) (x) & (__u32) 0xff000000UL) >> 24)))
@@ -53,6 +54,9 @@
 #define __swab16(x) (__u16) __builtin_bswap16((__u16) (x))
 #define __swab32(x) (__u32) __builtin_bswap32((__u32) (x))
 #define __swab64(x) (__u64) __builtin_bswap64((__u64) (x))
+#if __BITS_PER_LONG == 64
+#else
+#endif
 #define __swahw32(x) (__builtin_constant_p((__u32) (x)) ? ___constant_swahw32(x) : __fswahw32(x))
 #define __swahb32(x) (__builtin_constant_p((__u32) (x)) ? ___constant_swahb32(x) : __fswahb32(x))
 static __always_inline __u16 __swab16p(const __u16 * p) {
diff --git a/libc/kernel/uapi/linux/switchtec_ioctl.h b/libc/kernel/uapi/linux/switchtec_ioctl.h
index 2143148..204839d 100644
--- a/libc/kernel/uapi/linux/switchtec_ioctl.h
+++ b/libc/kernel/uapi/linux/switchtec_ioctl.h
@@ -32,7 +32,15 @@
 #define SWITCHTEC_IOCTL_PART_VENDOR5 10
 #define SWITCHTEC_IOCTL_PART_VENDOR6 11
 #define SWITCHTEC_IOCTL_PART_VENDOR7 12
-#define SWITCHTEC_IOCTL_NUM_PARTITIONS 13
+#define SWITCHTEC_IOCTL_PART_BL2_0 13
+#define SWITCHTEC_IOCTL_PART_BL2_1 14
+#define SWITCHTEC_IOCTL_PART_MAP_0 15
+#define SWITCHTEC_IOCTL_PART_MAP_1 16
+#define SWITCHTEC_IOCTL_PART_KEY_0 17
+#define SWITCHTEC_IOCTL_PART_KEY_1 18
+#define SWITCHTEC_NUM_PARTITIONS_GEN3 13
+#define SWITCHTEC_NUM_PARTITIONS_GEN4 19
+#define SWITCHTEC_IOCTL_NUM_PARTITIONS SWITCHTEC_NUM_PARTITIONS_GEN3
 struct switchtec_ioctl_flash_info {
   __u64 flash_length;
   __u32 num_partitions;
@@ -92,7 +100,9 @@
 #define SWITCHTEC_IOCTL_EVENT_CREDIT_TIMEOUT 27
 #define SWITCHTEC_IOCTL_EVENT_LINK_STATE 28
 #define SWITCHTEC_IOCTL_EVENT_GFMS 29
-#define SWITCHTEC_IOCTL_MAX_EVENTS 30
+#define SWITCHTEC_IOCTL_EVENT_INTERCOMM_REQ_NOTIFY 30
+#define SWITCHTEC_IOCTL_EVENT_UEC 31
+#define SWITCHTEC_IOCTL_MAX_EVENTS 32
 #define SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX - 1
 #define SWITCHTEC_IOCTL_EVENT_IDX_ALL - 2
 #define SWITCHTEC_IOCTL_EVENT_FLAG_CLEAR (1 << 0)
diff --git a/libc/kernel/uapi/linux/taskstats.h b/libc/kernel/uapi/linux/taskstats.h
index dc7791d..5f9d0cc 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 9
+#define TASKSTATS_VERSION 10
 #define TS_COMM_LEN 32
 struct taskstats {
   __u16 version;
@@ -68,6 +68,7 @@
   __u64 freepages_delay_total;
   __u64 thrashing_count;
   __u64 thrashing_delay_total;
+  __u64 ac_btime64;
 };
 enum {
   TASKSTATS_CMD_UNSPEC = 0,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_gate.h b/libc/kernel/uapi/linux/tc_act/tc_gate.h
new file mode 100644
index 0000000..f0a6412
--- /dev/null
+++ b/libc/kernel/uapi/linux/tc_act/tc_gate.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 __LINUX_TC_GATE_H
+#define __LINUX_TC_GATE_H
+#include <linux/pkt_cls.h>
+struct tc_gate {
+  tc_gen;
+};
+enum {
+  TCA_GATE_ENTRY_UNSPEC,
+  TCA_GATE_ENTRY_INDEX,
+  TCA_GATE_ENTRY_GATE,
+  TCA_GATE_ENTRY_INTERVAL,
+  TCA_GATE_ENTRY_IPV,
+  TCA_GATE_ENTRY_MAX_OCTETS,
+  __TCA_GATE_ENTRY_MAX,
+};
+#define TCA_GATE_ENTRY_MAX (__TCA_GATE_ENTRY_MAX - 1)
+enum {
+  TCA_GATE_ONE_ENTRY_UNSPEC,
+  TCA_GATE_ONE_ENTRY,
+  __TCA_GATE_ONE_ENTRY_MAX,
+};
+#define TCA_GATE_ONE_ENTRY_MAX (__TCA_GATE_ONE_ENTRY_MAX - 1)
+enum {
+  TCA_GATE_UNSPEC,
+  TCA_GATE_TM,
+  TCA_GATE_PARMS,
+  TCA_GATE_PAD,
+  TCA_GATE_PRIORITY,
+  TCA_GATE_ENTRY_LIST,
+  TCA_GATE_BASE_TIME,
+  TCA_GATE_CYCLE_TIME,
+  TCA_GATE_CYCLE_TIME_EXT,
+  TCA_GATE_FLAGS,
+  TCA_GATE_CLOCKID,
+  __TCA_GATE_MAX,
+};
+#define TCA_GATE_MAX (__TCA_GATE_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 823583d..e38e462 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -217,15 +217,18 @@
   TCP_NLA_DSACK_DUPS,
   TCP_NLA_REORD_SEEN,
   TCP_NLA_SRTT,
+  TCP_NLA_TIMEOUT_REHASH,
+  TCP_NLA_BYTES_NOTSENT,
 };
 #define TCP_MD5SIG_MAXKEYLEN 80
-#define TCP_MD5SIG_FLAG_PREFIX 1
+#define TCP_MD5SIG_FLAG_PREFIX 0x1
+#define TCP_MD5SIG_FLAG_IFINDEX 0x2
 struct tcp_md5sig {
   struct sockaddr_storage tcpm_addr;
   __u8 tcpm_flags;
   __u8 tcpm_prefixlen;
   __u16 tcpm_keylen;
-  __u32 __tcpm_pad;
+  int tcpm_ifindex;
   __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
 };
 struct tcp_diag_md5sig {
@@ -239,5 +242,7 @@
   __u64 address;
   __u32 length;
   __u32 recv_skip_hint;
+  __u32 inq;
+  __s32 err;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/tee.h b/libc/kernel/uapi/linux/tee.h
index e13c231..f23e000 100644
--- a/libc/kernel/uapi/linux/tee.h
+++ b/libc/kernel/uapi/linux/tee.h
@@ -29,6 +29,7 @@
 #define TEE_GEN_CAP_PRIVILEGED (1 << 1)
 #define TEE_GEN_CAP_REG_MEM (1 << 2)
 #define TEE_IMPL_ID_OPTEE 1
+#define TEE_IMPL_ID_AMDTEE 2
 #define TEE_OPTEE_CAP_TZ (1 << 0)
 struct tee_ioctl_version_data {
   __u32 impl_id;
@@ -62,6 +63,9 @@
 #define TEE_IOCTL_LOGIN_APPLICATION 4
 #define TEE_IOCTL_LOGIN_USER_APPLICATION 5
 #define TEE_IOCTL_LOGIN_GROUP_APPLICATION 6
+#define TEE_IOCTL_LOGIN_REE_KERNEL_MIN 0x80000000
+#define TEE_IOCTL_LOGIN_REE_KERNEL_MAX 0xBFFFFFFF
+#define TEE_IOCTL_LOGIN_REE_KERNEL 0x80000000
 struct tee_ioctl_param {
   __u64 attr;
   __u64 a;
diff --git a/libc/kernel/uapi/linux/time.h b/libc/kernel/uapi/linux/time.h
index eed430b..df52295 100644
--- a/libc/kernel/uapi/linux/time.h
+++ b/libc/kernel/uapi/linux/time.h
@@ -31,13 +31,6 @@
   __kernel_old_time_t tv_sec;
   __kernel_suseconds_t tv_usec;
 };
-struct timezone {
-  int tz_minuteswest;
-  int tz_dsttime;
-};
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
 struct itimerspec {
   struct timespec it_interval;
   struct timespec it_value;
@@ -46,6 +39,13 @@
   struct timeval it_interval;
   struct timeval it_value;
 };
+struct timezone {
+  int tz_minuteswest;
+  int tz_dsttime;
+};
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
 #define CLOCK_REALTIME 0
 #define CLOCK_MONOTONIC 1
 #define CLOCK_PROCESS_CPUTIME_ID 2
diff --git a/libc/kernel/uapi/linux/tipc_netlink.h b/libc/kernel/uapi/linux/tipc_netlink.h
index 61577fa..10fdf5e 100644
--- a/libc/kernel/uapi/linux/tipc_netlink.h
+++ b/libc/kernel/uapi/linux/tipc_netlink.h
@@ -46,6 +46,7 @@
   TIPC_NL_UDP_GET_REMOTEIP,
   TIPC_NL_KEY_SET,
   TIPC_NL_KEY_FLUSH,
+  TIPC_NL_ADDR_LEGACY_GET,
   __TIPC_NL_CMD_MAX,
   TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
 };
@@ -135,6 +136,7 @@
   TIPC_NLA_NET_ADDR,
   TIPC_NLA_NET_NODEID,
   TIPC_NLA_NET_NODEID_W1,
+  TIPC_NLA_NET_ADDR_LEGACY,
   __TIPC_NLA_NET_MAX,
   TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/udp.h b/libc/kernel/uapi/linux/udp.h
index 278cf6c..802c686 100644
--- a/libc/kernel/uapi/linux/udp.h
+++ b/libc/kernel/uapi/linux/udp.h
@@ -37,4 +37,5 @@
 #define UDP_ENCAP_GTP0 4
 #define UDP_ENCAP_GTP1U 5
 #define UDP_ENCAP_RXRPC 6
+#define TCP_ENCAP_ESPINTCP 7
 #endif
diff --git a/libc/kernel/uapi/linux/gigaset_dev.h b/libc/kernel/uapi/linux/um_timetravel.h
similarity index 68%
copy from libc/kernel/uapi/linux/gigaset_dev.h
copy to libc/kernel/uapi/linux/um_timetravel.h
index 5741d7d..220324f 100644
--- a/libc/kernel/uapi/linux/gigaset_dev.h
+++ b/libc/kernel/uapi/linux/um_timetravel.h
@@ -16,15 +16,23 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef GIGASET_INTERFACE_H
-#define GIGASET_INTERFACE_H
-#include <linux/ioctl.h>
-#define GIGASET_IOCTL 0x47
-#define GIGASET_REDIR _IOWR(GIGASET_IOCTL, 0, int)
-#define GIGASET_CONFIG _IOWR(GIGASET_IOCTL, 1, int)
-#define GIGASET_BRKCHARS _IOW(GIGASET_IOCTL, 2, unsigned char[6])
-#define GIGASET_VERSION _IOWR(GIGASET_IOCTL, 3, unsigned[4])
-#define GIGVER_DRIVER 0
-#define GIGVER_COMPAT 1
-#define GIGVER_FWBASE 2
+#ifndef _UAPI_LINUX_UM_TIMETRAVEL_H
+#define _UAPI_LINUX_UM_TIMETRAVEL_H
+#include <linux/types.h>
+struct um_timetravel_msg {
+  __u32 op;
+  __u32 seq;
+  __u64 time;
+};
+enum um_timetravel_ops {
+  UM_TIMETRAVEL_ACK = 0,
+  UM_TIMETRAVEL_START = 1,
+  UM_TIMETRAVEL_REQUEST = 2,
+  UM_TIMETRAVEL_WAIT = 3,
+  UM_TIMETRAVEL_GET = 4,
+  UM_TIMETRAVEL_UPDATE = 5,
+  UM_TIMETRAVEL_RUN = 6,
+  UM_TIMETRAVEL_FREE_UNTIL = 7,
+  UM_TIMETRAVEL_GET_TOD = 8,
+};
 #endif
diff --git a/libc/kernel/uapi/linux/usb/charger.h b/libc/kernel/uapi/linux/usb/charger.h
index 0810aab..e53f7d6 100644
--- a/libc/kernel/uapi/linux/usb/charger.h
+++ b/libc/kernel/uapi/linux/usb/charger.h
@@ -19,15 +19,15 @@
 #ifndef _UAPI__LINUX_USB_CHARGER_H
 #define _UAPI__LINUX_USB_CHARGER_H
 enum usb_charger_type {
-  UNKNOWN_TYPE,
-  SDP_TYPE,
-  DCP_TYPE,
-  CDP_TYPE,
-  ACA_TYPE,
+  UNKNOWN_TYPE = 0,
+  SDP_TYPE = 1,
+  DCP_TYPE = 2,
+  CDP_TYPE = 3,
+  ACA_TYPE = 4,
 };
 enum usb_charger_state {
-  USB_CHARGER_DEFAULT,
-  USB_CHARGER_PRESENT,
-  USB_CHARGER_ABSENT,
+  USB_CHARGER_DEFAULT = 0,
+  USB_CHARGER_PRESENT = 1,
+  USB_CHARGER_ABSENT = 2,
 };
 #endif
diff --git a/libc/kernel/uapi/linux/usb/raw_gadget.h b/libc/kernel/uapi/linux/usb/raw_gadget.h
new file mode 100644
index 0000000..70d5a26
--- /dev/null
+++ b/libc/kernel/uapi/linux/usb/raw_gadget.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_USB_RAW_GADGET_H
+#define _UAPI__LINUX_USB_RAW_GADGET_H
+#include <asm/ioctl.h>
+#include <linux/types.h>
+#include <linux/usb/ch9.h>
+#define UDC_NAME_LENGTH_MAX 128
+struct usb_raw_init {
+  __u8 driver_name[UDC_NAME_LENGTH_MAX];
+  __u8 device_name[UDC_NAME_LENGTH_MAX];
+  __u8 speed;
+};
+enum usb_raw_event_type {
+  USB_RAW_EVENT_INVALID = 0,
+  USB_RAW_EVENT_CONNECT = 1,
+  USB_RAW_EVENT_CONTROL = 2,
+};
+struct usb_raw_event {
+  __u32 type;
+  __u32 length;
+  __u8 data[0];
+};
+#define USB_RAW_IO_FLAGS_ZERO 0x0001
+#define USB_RAW_IO_FLAGS_MASK 0x0001
+struct usb_raw_ep_io {
+  __u16 ep;
+  __u16 flags;
+  __u32 length;
+  __u8 data[0];
+};
+#define USB_RAW_EPS_NUM_MAX 30
+#define USB_RAW_EP_NAME_MAX 16
+#define USB_RAW_EP_ADDR_ANY 0xff
+struct usb_raw_ep_caps {
+  __u32 type_control : 1;
+  __u32 type_iso : 1;
+  __u32 type_bulk : 1;
+  __u32 type_int : 1;
+  __u32 dir_in : 1;
+  __u32 dir_out : 1;
+};
+struct usb_raw_ep_limits {
+  __u16 maxpacket_limit;
+  __u16 max_streams;
+  __u32 reserved;
+};
+struct usb_raw_ep_info {
+  __u8 name[USB_RAW_EP_NAME_MAX];
+  __u32 addr;
+  struct usb_raw_ep_caps caps;
+  struct usb_raw_ep_limits limits;
+};
+struct usb_raw_eps_info {
+  struct usb_raw_ep_info eps[USB_RAW_EPS_NUM_MAX];
+};
+#define USB_RAW_IOCTL_INIT _IOW('U', 0, struct usb_raw_init)
+#define USB_RAW_IOCTL_RUN _IO('U', 1)
+#define USB_RAW_IOCTL_EVENT_FETCH _IOR('U', 2, struct usb_raw_event)
+#define USB_RAW_IOCTL_EP0_WRITE _IOW('U', 3, struct usb_raw_ep_io)
+#define USB_RAW_IOCTL_EP0_READ _IOWR('U', 4, struct usb_raw_ep_io)
+#define USB_RAW_IOCTL_EP_ENABLE _IOW('U', 5, struct usb_endpoint_descriptor)
+#define USB_RAW_IOCTL_EP_DISABLE _IOW('U', 6, __u32)
+#define USB_RAW_IOCTL_EP_WRITE _IOW('U', 7, struct usb_raw_ep_io)
+#define USB_RAW_IOCTL_EP_READ _IOWR('U', 8, struct usb_raw_ep_io)
+#define USB_RAW_IOCTL_CONFIGURE _IO('U', 9)
+#define USB_RAW_IOCTL_VBUS_DRAW _IOW('U', 10, __u32)
+#define USB_RAW_IOCTL_EPS_INFO _IOR('U', 11, struct usb_raw_eps_info)
+#define USB_RAW_IOCTL_EP0_STALL _IO('U', 12)
+#define USB_RAW_IOCTL_EP_SET_HALT _IOW('U', 13, __u32)
+#define USB_RAW_IOCTL_EP_CLEAR_HALT _IOW('U', 14, __u32)
+#define USB_RAW_IOCTL_EP_SET_WEDGE _IOW('U', 15, __u32)
+#endif
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index ecc6302..e6b776a 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -20,15 +20,16 @@
 #define _LINUX_USERFAULTFD_H
 #include <linux/types.h>
 #define UFFD_API ((__u64) 0xAA)
-#define UFFD_API_FEATURES (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_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_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)
+#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 _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_API (0x3F)
 #define UFFDIO 0xAA
 #define UFFDIO_API _IOWR(UFFDIO, _UFFDIO_API, struct uffdio_api)
@@ -37,6 +38,7 @@
 #define UFFDIO_WAKE _IOR(UFFDIO, _UFFDIO_WAKE, struct uffdio_range)
 #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)
 struct uffd_msg {
   __u8 event;
   __u8 reserved1;
@@ -106,6 +108,7 @@
   __u64 src;
   __u64 len;
 #define UFFDIO_COPY_MODE_DONTWAKE ((__u64) 1 << 0)
+#define UFFDIO_COPY_MODE_WP ((__u64) 1 << 1)
   __u64 mode;
   __s64 copy;
 };
@@ -115,4 +118,10 @@
   __u64 mode;
   __s64 zeropage;
 };
+struct uffdio_writeprotect {
+  struct uffdio_range range;
+#define UFFDIO_WRITEPROTECT_MODE_WP ((__u64) 1 << 0)
+#define UFFDIO_WRITEPROTECT_MODE_DONTWAKE ((__u64) 1 << 1)
+  __u64 mode;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 85f3a8b..d060744 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -110,6 +110,7 @@
 #define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080)
 #define V4L2_CID_USER_MAX217X_BASE (V4L2_CID_USER_BASE + 0x1090)
 #define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x10b0)
+#define V4L2_CID_USER_ATMEL_ISC_BASE (V4L2_CID_USER_BASE + 0x10c0)
 #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
 #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
 #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE + 0)
@@ -366,6 +367,10 @@
   V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13,
   V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14,
   V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15,
+  V4L2_MPEG_VIDEO_H264_LEVEL_5_2 = 16,
+  V4L2_MPEG_VIDEO_H264_LEVEL_6_0 = 17,
+  V4L2_MPEG_VIDEO_H264_LEVEL_6_1 = 18,
+  V4L2_MPEG_VIDEO_H264_LEVEL_6_2 = 19,
 };
 #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE + 360)
 #define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE + 361)
@@ -394,6 +399,7 @@
   V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14,
   V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15,
   V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16,
+  V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH = 17,
 };
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE + 364)
 #define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE + 365)
@@ -775,6 +781,11 @@
 };
 #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 32)
 #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE + 33)
+#define V4L2_CID_CAMERA_ORIENTATION (V4L2_CID_CAMERA_CLASS_BASE + 34)
+#define V4L2_CAMERA_ORIENTATION_FRONT 0
+#define V4L2_CAMERA_ORIENTATION_BACK 1
+#define V4L2_CAMERA_ORIENTATION_EXTERNAL 2
+#define V4L2_CID_CAMERA_SENSOR_ROTATION (V4L2_CID_CAMERA_CLASS_BASE + 35)
 #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
 #define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1)
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 303d167..da81738 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -79,7 +79,14 @@
   struct v4l2_rect r;
   __u32 reserved[8];
 };
+struct v4l2_subdev_capability {
+  __u32 version;
+  __u32 capabilities;
+  __u32 reserved[14];
+};
+#define V4L2_SUBDEV_CAP_RO_SUBDEV BIT(0)
 #define v4l2_subdev_edid v4l2_edid
+#define VIDIOC_SUBDEV_QUERYCAP _IOR('V', 0, struct v4l2_subdev_capability)
 #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_G_FRAME_INTERVAL _IOWR('V', 21, struct v4l2_subdev_frame_interval)
diff --git a/libc/kernel/uapi/linux/vboxguest.h b/libc/kernel/uapi/linux/vboxguest.h
index 2eb80ef..d9dfa9a 100644
--- a/libc/kernel/uapi/linux/vboxguest.h
+++ b/libc/kernel/uapi/linux/vboxguest.h
@@ -53,7 +53,7 @@
 };
 #define VBG_IOCTL_DRIVER_VERSION_INFO _IOWR('V', 0, struct vbg_ioctl_driver_version_info)
 #define VBG_IOCTL_VMMDEV_REQUEST(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 2, s)
-#define VBG_IOCTL_VMMDEV_REQUEST_BIG _IOC(_IOC_READ | _IOC_WRITE, 'V', 3, 0)
+#define VBG_IOCTL_VMMDEV_REQUEST_BIG _IO('V', 3)
 struct vbg_ioctl_hgcm_connect {
   struct vbg_ioctl_hdr hdr;
   union {
@@ -99,7 +99,7 @@
     } in;
   } u;
 };
-#define VBG_IOCTL_LOG(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 9, s)
+#define VBG_IOCTL_LOG(s) _IO('V', 9)
 struct vbg_ioctl_wait_for_events {
   struct vbg_ioctl_hdr hdr;
   union {
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 471dcd7..05b1551 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 328960
+#define LINUX_VERSION_CODE 329728
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index b9e7243..e0bba31 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -101,6 +101,7 @@
 #define VFIO_REGION_TYPE_PCI_VENDOR_MASK (0xffff)
 #define VFIO_REGION_TYPE_GFX (1)
 #define VFIO_REGION_TYPE_CCW (2)
+#define VFIO_REGION_TYPE_MIGRATION (3)
 #define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
 #define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
 #define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
@@ -118,6 +119,24 @@
 #define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2
 };
 #define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD (1)
+#define VFIO_REGION_SUBTYPE_CCW_SCHIB (2)
+#define VFIO_REGION_SUBTYPE_CCW_CRW (3)
+#define VFIO_REGION_SUBTYPE_MIGRATION (1)
+struct vfio_device_migration_info {
+  __u32 device_state;
+#define VFIO_DEVICE_STATE_STOP (0)
+#define VFIO_DEVICE_STATE_RUNNING (1 << 0)
+#define VFIO_DEVICE_STATE_SAVING (1 << 1)
+#define VFIO_DEVICE_STATE_RESUMING (1 << 2)
+#define VFIO_DEVICE_STATE_MASK (VFIO_DEVICE_STATE_RUNNING | VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
+#define VFIO_DEVICE_STATE_VALID(state) (state & VFIO_DEVICE_STATE_RESUMING ? (state & VFIO_DEVICE_STATE_MASK) == VFIO_DEVICE_STATE_RESUMING : 1)
+#define VFIO_DEVICE_STATE_IS_ERROR(state) ((state & VFIO_DEVICE_STATE_MASK) == (VFIO_DEVICE_STATE_SAVING | VFIO_DEVICE_STATE_RESUMING))
+#define VFIO_DEVICE_STATE_SET_ERROR(state) ((state & ~VFIO_DEVICE_STATE_MASK) | VFIO_DEVICE_SATE_SAVING | VFIO_DEVICE_STATE_RESUMING)
+  __u32 reserved;
+  __u64 pending_bytes;
+  __u64 data_offset;
+  __u64 data_size;
+};
 #define VFIO_REGION_INFO_CAP_MSIX_MAPPABLE 3
 #define VFIO_REGION_INFO_CAP_NVLINK2_SSATGT 4
 struct vfio_region_info_cap_nvlink2_ssatgt {
@@ -185,6 +204,7 @@
 };
 enum {
   VFIO_CCW_IO_IRQ_INDEX,
+  VFIO_CCW_CRW_IRQ_INDEX,
   VFIO_CCW_NUM_IRQS
 };
 struct vfio_pci_dependent_device {
@@ -244,6 +264,17 @@
   __s32 fd;
 };
 #define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16)
+struct vfio_device_feature {
+  __u32 argsz;
+  __u32 flags;
+#define VFIO_DEVICE_FEATURE_MASK (0xffff)
+#define VFIO_DEVICE_FEATURE_GET (1 << 16)
+#define VFIO_DEVICE_FEATURE_SET (1 << 17)
+#define VFIO_DEVICE_FEATURE_PROBE (1 << 18)
+  __u8 data[];
+};
+#define VFIO_DEVICE_FEATURE _IO(VFIO_TYPE, VFIO_BASE + 17)
+#define VFIO_DEVICE_FEATURE_PCI_VF_TOKEN (0)
 struct vfio_iommu_type1_info {
   __u32 argsz;
   __u32 flags;
@@ -263,6 +294,13 @@
   __u32 reserved;
   struct vfio_iova_range iova_ranges[];
 };
+#define VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION 2
+struct vfio_iommu_type1_info_cap_migration {
+  struct vfio_info_cap_header header;
+  __u32 flags;
+  __u64 pgsize_bitmap;
+  __u64 max_dirty_bitmap_size;
+};
 #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
 struct vfio_iommu_type1_dma_map {
   __u32 argsz;
@@ -274,15 +312,36 @@
   __u64 size;
 };
 #define VFIO_IOMMU_MAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 13)
+struct vfio_bitmap {
+  __u64 pgsize;
+  __u64 size;
+  __u64 __user * data;
+};
 struct vfio_iommu_type1_dma_unmap {
   __u32 argsz;
   __u32 flags;
+#define VFIO_DMA_UNMAP_FLAG_GET_DIRTY_BITMAP (1 << 0)
   __u64 iova;
   __u64 size;
+  __u8 data[];
 };
 #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14)
 #define VFIO_IOMMU_ENABLE _IO(VFIO_TYPE, VFIO_BASE + 15)
 #define VFIO_IOMMU_DISABLE _IO(VFIO_TYPE, VFIO_BASE + 16)
+struct vfio_iommu_type1_dirty_bitmap {
+  __u32 argsz;
+  __u32 flags;
+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_START (1 << 0)
+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP (1 << 1)
+#define VFIO_IOMMU_DIRTY_PAGES_FLAG_GET_BITMAP (1 << 2)
+  __u8 data[];
+};
+struct vfio_iommu_type1_dirty_bitmap_get {
+  __u64 iova;
+  __u64 size;
+  struct vfio_bitmap bitmap;
+};
+#define VFIO_IOMMU_DIRTY_PAGES _IO(VFIO_TYPE, VFIO_BASE + 17)
 struct vfio_iommu_spapr_tce_ddw_info {
   __u64 pgsizes;
   __u32 max_dynamic_windows_supported;
diff --git a/libc/kernel/uapi/linux/vfio_ccw.h b/libc/kernel/uapi/linux/vfio_ccw.h
index 6ed6830..a6defc5 100644
--- a/libc/kernel/uapi/linux/vfio_ccw.h
+++ b/libc/kernel/uapi/linux/vfio_ccw.h
@@ -34,4 +34,12 @@
   __u32 command;
   __u32 ret_code;
 } __packed;
+struct ccw_schib_region {
+#define SCHIB_AREA_SIZE 52
+  __u8 schib_area[SCHIB_AREA_SIZE];
+} __packed;
+struct ccw_crw_region {
+  __u32 crw;
+  __u32 pad;
+} __packed;
 #endif
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index 9e87e6e..0349fa7 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -21,6 +21,7 @@
 #include <linux/vhost_types.h>
 #include <linux/types.h>
 #include <linux/ioctl.h>
+#define VHOST_FILE_UNBIND - 1
 #define VHOST_VIRTIO 0xAF
 #define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64)
 #define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64)
@@ -53,4 +54,12 @@
 #define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
 #define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64)
 #define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int)
+#define VHOST_VDPA_GET_DEVICE_ID _IOR(VHOST_VIRTIO, 0x70, __u32)
+#define VHOST_VDPA_GET_STATUS _IOR(VHOST_VIRTIO, 0x71, __u8)
+#define VHOST_VDPA_SET_STATUS _IOW(VHOST_VIRTIO, 0x72, __u8)
+#define VHOST_VDPA_GET_CONFIG _IOR(VHOST_VIRTIO, 0x73, struct vhost_vdpa_config)
+#define VHOST_VDPA_SET_CONFIG _IOW(VHOST_VIRTIO, 0x74, struct vhost_vdpa_config)
+#define VHOST_VDPA_SET_VRING_ENABLE _IOW(VHOST_VIRTIO, 0x75, struct vhost_vring_state)
+#define VHOST_VDPA_GET_VRING_NUM _IOR(VHOST_VIRTIO, 0x76, __u16)
+#define VHOST_VDPA_SET_CONFIG_CALL _IOW(VHOST_VIRTIO, 0x77, int)
 #endif
diff --git a/libc/kernel/uapi/linux/vhost_types.h b/libc/kernel/uapi/linux/vhost_types.h
index 646fcdc..1288cf6 100644
--- a/libc/kernel/uapi/linux/vhost_types.h
+++ b/libc/kernel/uapi/linux/vhost_types.h
@@ -89,6 +89,11 @@
   unsigned short vhost_tpgt;
   unsigned short reserved;
 };
+struct vhost_vdpa_config {
+  __u32 off;
+  __u32 len;
+  __u8 buf[0];
+};
 #define VHOST_F_LOG_ALL 26
 #define VHOST_NET_F_VIRTIO_NET_HDR 27
 #endif
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index aaf5a70..d8c7549 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -188,6 +188,7 @@
 #define V4L2_CAP_STREAMING 0x04000000
 #define V4L2_CAP_META_OUTPUT 0x08000000
 #define V4L2_CAP_TOUCH 0x10000000
+#define V4L2_CAP_IO_MC 0x20000000
 #define V4L2_CAP_DEVICE_CAPS 0x80000000
 struct v4l2_pix_format {
   __u32 width;
@@ -248,6 +249,7 @@
 #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ')
 #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ')
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ')
+#define V4L2_PIX_FMT_Y14 v4l2_fourcc('Y', '1', '4', ' ')
 #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')
 #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ')
 #define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B')
@@ -323,6 +325,10 @@
 #define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C')
 #define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C')
 #define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C')
+#define V4L2_PIX_FMT_SBGGR14 v4l2_fourcc('B', 'G', '1', '4')
+#define V4L2_PIX_FMT_SGBRG14 v4l2_fourcc('G', 'B', '1', '4')
+#define V4L2_PIX_FMT_SGRBG14 v4l2_fourcc('G', 'R', '1', '4')
+#define V4L2_PIX_FMT_SRGGB14 v4l2_fourcc('R', 'G', '1', '4')
 #define V4L2_PIX_FMT_SBGGR14P v4l2_fourcc('p', 'B', 'E', 'E')
 #define V4L2_PIX_FMT_SGBRG14P v4l2_fourcc('p', 'G', 'E', 'E')
 #define V4L2_PIX_FMT_SGRBG14P v4l2_fourcc('p', 'g', 'E', 'E')
@@ -415,7 +421,8 @@
   __u32 flags;
   __u8 description[32];
   __u32 pixelformat;
-  __u32 reserved[4];
+  __u32 mbus_code;
+  __u32 reserved[3];
 };
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
 #define V4L2_FMT_FLAG_EMULATED 0x0002
diff --git a/libc/kernel/uapi/linux/virtio_balloon.h b/libc/kernel/uapi/linux/virtio_balloon.h
index 806e757..80affd8 100644
--- a/libc/kernel/uapi/linux/virtio_balloon.h
+++ b/libc/kernel/uapi/linux/virtio_balloon.h
@@ -27,13 +27,17 @@
 #define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2
 #define VIRTIO_BALLOON_F_FREE_PAGE_HINT 3
 #define VIRTIO_BALLOON_F_PAGE_POISON 4
+#define VIRTIO_BALLOON_F_REPORTING 5
 #define VIRTIO_BALLOON_PFN_SHIFT 12
 #define VIRTIO_BALLOON_CMD_ID_STOP 0
 #define VIRTIO_BALLOON_CMD_ID_DONE 1
 struct virtio_balloon_config {
   __u32 num_pages;
   __u32 actual;
-  __u32 free_page_report_cmd_id;
+  union {
+    __u32 free_page_hint_cmd_id;
+    __u32 free_page_report_cmd_id;
+  };
   __u32 poison_val;
 };
 #define VIRTIO_BALLOON_S_SWAP_IN 0
diff --git a/libc/kernel/uapi/linux/virtio_ids.h b/libc/kernel/uapi/linux/virtio_ids.h
index 8e6712a..7b67d76 100644
--- a/libc/kernel/uapi/linux/virtio_ids.h
+++ b/libc/kernel/uapi/linux/virtio_ids.h
@@ -33,6 +33,8 @@
 #define VIRTIO_ID_VSOCK 19
 #define VIRTIO_ID_CRYPTO 20
 #define VIRTIO_ID_IOMMU 23
+#define VIRTIO_ID_MEM 24
 #define VIRTIO_ID_FS 26
 #define VIRTIO_ID_PMEM 27
+#define VIRTIO_ID_MAC80211_HWSIM 29
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_iommu.h b/libc/kernel/uapi/linux/virtio_iommu.h
index b08de57..b156ea3 100644
--- a/libc/kernel/uapi/linux/virtio_iommu.h
+++ b/libc/kernel/uapi/linux/virtio_iommu.h
@@ -26,18 +26,18 @@
 #define VIRTIO_IOMMU_F_PROBE 4
 #define VIRTIO_IOMMU_F_MMIO 5
 struct virtio_iommu_range_64 {
-  __le64 start;
-  __le64 end;
+  __u64 start;
+  __u64 end;
 };
 struct virtio_iommu_range_32 {
-  __le32 start;
-  __le32 end;
+  __u32 start;
+  __u32 end;
 };
 struct virtio_iommu_config {
-  __le64 page_size_mask;
+  __u64 page_size_mask;
   struct virtio_iommu_range_64 input_range;
   struct virtio_iommu_range_32 domain_range;
-  __le32 probe_size;
+  __u32 probe_size;
 };
 #define VIRTIO_IOMMU_T_ATTACH 0x01
 #define VIRTIO_IOMMU_T_DETACH 0x02
diff --git a/libc/kernel/uapi/linux/virtio_mem.h b/libc/kernel/uapi/linux/virtio_mem.h
new file mode 100644
index 0000000..854a2fe
--- /dev/null
+++ b/libc/kernel/uapi/linux/virtio_mem.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 _LINUX_VIRTIO_MEM_H
+#define _LINUX_VIRTIO_MEM_H
+#include <linux/types.h>
+#include <linux/virtio_types.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#define VIRTIO_MEM_F_ACPI_PXM 0
+#define VIRTIO_MEM_REQ_PLUG 0
+#define VIRTIO_MEM_REQ_UNPLUG 1
+#define VIRTIO_MEM_REQ_UNPLUG_ALL 2
+#define VIRTIO_MEM_REQ_STATE 3
+struct virtio_mem_req_plug {
+  __virtio64 addr;
+  __virtio16 nb_blocks;
+  __virtio16 padding[3];
+};
+struct virtio_mem_req_unplug {
+  __virtio64 addr;
+  __virtio16 nb_blocks;
+  __virtio16 padding[3];
+};
+struct virtio_mem_req_state {
+  __virtio64 addr;
+  __virtio16 nb_blocks;
+  __virtio16 padding[3];
+};
+struct virtio_mem_req {
+  __virtio16 type;
+  __virtio16 padding[3];
+  union {
+    struct virtio_mem_req_plug plug;
+    struct virtio_mem_req_unplug unplug;
+    struct virtio_mem_req_state state;
+  } u;
+};
+#define VIRTIO_MEM_RESP_ACK 0
+#define VIRTIO_MEM_RESP_NACK 1
+#define VIRTIO_MEM_RESP_BUSY 2
+#define VIRTIO_MEM_RESP_ERROR 3
+#define VIRTIO_MEM_STATE_PLUGGED 0
+#define VIRTIO_MEM_STATE_UNPLUGGED 1
+#define VIRTIO_MEM_STATE_MIXED 2
+struct virtio_mem_resp_state {
+  __virtio16 state;
+};
+struct virtio_mem_resp {
+  __virtio16 type;
+  __virtio16 padding[3];
+  union {
+    struct virtio_mem_resp_state state;
+  } u;
+};
+struct virtio_mem_config {
+  __u64 block_size;
+  __u16 node_id;
+  __u8 padding[6];
+  __u64 addr;
+  __u64 region_size;
+  __u64 usable_region_size;
+  __u64 plugged_size;
+  __u64 requested_size;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/virtio_net.h b/libc/kernel/uapi/linux/virtio_net.h
index 07afd06..cd53e16 100644
--- a/libc/kernel/uapi/linux/virtio_net.h
+++ b/libc/kernel/uapi/linux/virtio_net.h
@@ -45,6 +45,9 @@
 #define VIRTIO_NET_F_GUEST_ANNOUNCE 21
 #define VIRTIO_NET_F_MQ 22
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23
+#define VIRTIO_NET_F_HASH_REPORT 57
+#define VIRTIO_NET_F_RSS 60
+#define VIRTIO_NET_F_RSC_EXT 61
 #define VIRTIO_NET_F_STANDBY 62
 #define VIRTIO_NET_F_SPEED_DUPLEX 63
 #ifndef VIRTIO_NET_NO_LEGACY
@@ -52,6 +55,15 @@
 #endif
 #define VIRTIO_NET_S_LINK_UP 1
 #define VIRTIO_NET_S_ANNOUNCE 2
+#define VIRTIO_NET_RSS_HASH_TYPE_IPv4 (1 << 0)
+#define VIRTIO_NET_RSS_HASH_TYPE_TCPv4 (1 << 1)
+#define VIRTIO_NET_RSS_HASH_TYPE_UDPv4 (1 << 2)
+#define VIRTIO_NET_RSS_HASH_TYPE_IPv6 (1 << 3)
+#define VIRTIO_NET_RSS_HASH_TYPE_TCPv6 (1 << 4)
+#define VIRTIO_NET_RSS_HASH_TYPE_UDPv6 (1 << 5)
+#define VIRTIO_NET_RSS_HASH_TYPE_IP_EX (1 << 6)
+#define VIRTIO_NET_RSS_HASH_TYPE_TCP_EX (1 << 7)
+#define VIRTIO_NET_RSS_HASH_TYPE_UDP_EX (1 << 8)
 struct virtio_net_config {
   __u8 mac[ETH_ALEN];
   __u16 status;
@@ -59,10 +71,14 @@
   __u16 mtu;
   __u32 speed;
   __u8 duplex;
+  __u8 rss_max_key_size;
+  __le16 rss_max_indirection_table_length;
+  __le32 supported_hash_types;
 } __attribute__((packed));
 struct virtio_net_hdr_v1 {
 #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1
 #define VIRTIO_NET_HDR_F_DATA_VALID 2
+#define VIRTIO_NET_HDR_F_RSC_INFO 4
   __u8 flags;
 #define VIRTIO_NET_HDR_GSO_NONE 0
 #define VIRTIO_NET_HDR_GSO_TCPV4 1
@@ -72,10 +88,38 @@
   __u8 gso_type;
   __virtio16 hdr_len;
   __virtio16 gso_size;
-  __virtio16 csum_start;
-  __virtio16 csum_offset;
+  union {
+    struct {
+      __virtio16 csum_start;
+      __virtio16 csum_offset;
+    };
+    struct {
+      __virtio16 start;
+      __virtio16 offset;
+    } csum;
+    struct {
+      __le16 segments;
+      __le16 dup_acks;
+    } rsc;
+  };
   __virtio16 num_buffers;
 };
+struct virtio_net_hdr_v1_hash {
+  struct virtio_net_hdr_v1 hdr;
+  __le32 hash_value;
+#define VIRTIO_NET_HASH_REPORT_NONE 0
+#define VIRTIO_NET_HASH_REPORT_IPv4 1
+#define VIRTIO_NET_HASH_REPORT_TCPv4 2
+#define VIRTIO_NET_HASH_REPORT_UDPv4 3
+#define VIRTIO_NET_HASH_REPORT_IPv6 4
+#define VIRTIO_NET_HASH_REPORT_TCPv6 5
+#define VIRTIO_NET_HASH_REPORT_UDPv6 6
+#define VIRTIO_NET_HASH_REPORT_IPv6_EX 7
+#define VIRTIO_NET_HASH_REPORT_TCPv6_EX 8
+#define VIRTIO_NET_HASH_REPORT_UDPv6_EX 9
+  __le16 hash_report;
+  __le16 padding;
+};
 #ifndef VIRTIO_NET_NO_LEGACY
 struct virtio_net_hdr {
   __u8 flags;
@@ -116,13 +160,30 @@
 #define VIRTIO_NET_CTRL_VLAN_DEL 1
 #define VIRTIO_NET_CTRL_ANNOUNCE 3
 #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0
+#define VIRTIO_NET_CTRL_MQ 4
 struct virtio_net_ctrl_mq {
   __virtio16 virtqueue_pairs;
 };
-#define VIRTIO_NET_CTRL_MQ 4
 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0
 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1
 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000
+struct virtio_net_rss_config {
+  __le32 hash_types;
+  __le16 indirection_table_mask;
+  __le16 unclassified_queue;
+  __le16 indirection_table[1];
+  __le16 max_tx_vq;
+  __u8 hash_key_length;
+  __u8 hash_key_data[];
+};
+#define VIRTIO_NET_CTRL_MQ_RSS_CONFIG 1
+struct virtio_net_hash_config {
+  __le32 hash_types;
+  __le16 reserved[4];
+  __u8 hash_key_length;
+  __u8 hash_key_data[];
+};
+#define VIRTIO_NET_CTRL_MQ_HASH_CONFIG 2
 #define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
 #define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_ring.h b/libc/kernel/uapi/linux/virtio_ring.h
index ba75940..24cf671 100644
--- a/libc/kernel/uapi/linux/virtio_ring.h
+++ b/libc/kernel/uapi/linux/virtio_ring.h
@@ -34,6 +34,9 @@
 #define VRING_PACKED_EVENT_F_WRAP_CTR 15
 #define VIRTIO_RING_F_INDIRECT_DESC 28
 #define VIRTIO_RING_F_EVENT_IDX 29
+#define VRING_AVAIL_ALIGN_SIZE 2
+#define VRING_USED_ALIGN_SIZE 4
+#define VRING_DESC_ALIGN_SIZE 16
 struct vring_desc {
   __virtio64 addr;
   __virtio32 len;
@@ -49,22 +52,25 @@
   __virtio32 id;
   __virtio32 len;
 };
+typedef struct vring_used_elem __attribute__((aligned(VRING_USED_ALIGN_SIZE))) vring_used_elem_t;
 struct vring_used {
   __virtio16 flags;
   __virtio16 idx;
-  struct vring_used_elem ring[];
+  vring_used_elem_t ring[];
 };
+typedef struct vring_desc __attribute__((aligned(VRING_DESC_ALIGN_SIZE))) vring_desc_t;
+typedef struct vring_avail __attribute__((aligned(VRING_AVAIL_ALIGN_SIZE))) vring_avail_t;
+typedef struct vring_used __attribute__((aligned(VRING_USED_ALIGN_SIZE))) vring_used_t;
 struct vring {
   unsigned int num;
-  struct vring_desc * desc;
-  struct vring_avail * avail;
-  struct vring_used * used;
+  vring_desc_t * desc;
+  vring_avail_t * avail;
+  vring_used_t * used;
 };
-#define VRING_AVAIL_ALIGN_SIZE 2
-#define VRING_USED_ALIGN_SIZE 4
-#define VRING_DESC_ALIGN_SIZE 16
+#ifndef VIRTIO_RING_NO_LEGACY
 #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
 #define vring_avail_event(vr) (* (__virtio16 *) & (vr)->used->ring[(vr)->num])
+#endif
 struct vring_packed_desc_event {
   __le16 off_wrap;
   __le16 flags;
diff --git a/libc/kernel/uapi/linux/vm_sockets.h b/libc/kernel/uapi/linux/vm_sockets.h
index 87e4ba0..3dc4bcf 100644
--- a/libc/kernel/uapi/linux/vm_sockets.h
+++ b/libc/kernel/uapi/linux/vm_sockets.h
@@ -29,7 +29,7 @@
 #define VMADDR_CID_ANY - 1U
 #define VMADDR_PORT_ANY - 1U
 #define VMADDR_CID_HYPERVISOR 0
-#define VMADDR_CID_RESERVED 1
+#define VMADDR_CID_LOCAL 1
 #define VMADDR_CID_HOST 2
 #define VM_SOCKETS_INVALID_VERSION - 1U
 #define VM_SOCKETS_VERSION_EPOCH(_v) (((_v) & 0xFF000000) >> 24)
diff --git a/libc/kernel/uapi/linux/vsoc_shm.h b/libc/kernel/uapi/linux/vsoc_shm.h
deleted file mode 100644
index 467b89b..0000000
--- a/libc/kernel/uapi/linux/vsoc_shm.h
+++ /dev/null
@@ -1,84 +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_VSOC_SHM_H
-#define _UAPI_LINUX_VSOC_SHM_H
-#include <linux/types.h>
-struct fd_scoped_permission {
-  __u32 begin_offset;
-  __u32 end_offset;
-  __u32 owner_offset;
-  __u32 owned_value;
-};
-#define VSOC_REGION_FREE ((__u32) 0)
-struct fd_scoped_permission_arg {
-  struct fd_scoped_permission perm;
-  __s32 managed_region_fd;
-};
-#define VSOC_NODE_FREE ((__u32) 0)
-struct vsoc_signal_table_layout {
-  __u32 num_nodes_lg2;
-  __u32 futex_uaddr_table_offset;
-  __u32 interrupt_signalled_offset;
-};
-#define VSOC_REGION_WHOLE ((__s32) 0)
-#define VSOC_DEVICE_NAME_SZ 16
-struct vsoc_device_region {
-  __u16 current_version;
-  __u16 min_compatible_version;
-  __u32 region_begin_offset;
-  __u32 region_end_offset;
-  __u32 offset_of_region_data;
-  struct vsoc_signal_table_layout guest_to_host_signal_table;
-  struct vsoc_signal_table_layout host_to_guest_signal_table;
-  char device_name[VSOC_DEVICE_NAME_SZ];
-  __u32 managed_by;
-};
-struct vsoc_shm_layout_descriptor {
-  __u16 major_version;
-  __u16 minor_version;
-  __u32 size;
-  __u32 region_count;
-  __u32 vsoc_region_desc_offset;
-};
-#define CURRENT_VSOC_LAYOUT_MAJOR_VERSION 2
-#define CURRENT_VSOC_LAYOUT_MINOR_VERSION 0
-#define VSOC_CREATE_FD_SCOPED_PERMISSION _IOW(0xF5, 0, struct fd_scoped_permission)
-#define VSOC_GET_FD_SCOPED_PERMISSION _IOR(0xF5, 1, struct fd_scoped_permission)
-#define VSOC_MAYBE_SEND_INTERRUPT_TO_HOST _IO(0xF5, 2)
-#define VSOC_WAIT_FOR_INCOMING_INTERRUPT _IO(0xF5, 3)
-#define VSOC_DESCRIBE_REGION _IOR(0xF5, 4, struct vsoc_device_region)
-#define VSOC_SELF_INTERRUPT _IO(0xF5, 5)
-#define VSOC_SEND_INTERRUPT_TO_HOST _IO(0xF5, 6)
-enum wait_types {
-  VSOC_WAIT_UNDEFINED = 0,
-  VSOC_WAIT_IF_EQUAL = 1,
-  VSOC_WAIT_IF_EQUAL_TIMEOUT = 2
-};
-struct vsoc_cond_wait {
-  __u32 offset;
-  __u32 value;
-  __u64 wake_time_sec;
-  __u32 wake_time_nsec;
-  __u32 wait_type;
-  __u32 wakes;
-  __u32 reserved_1;
-};
-#define VSOC_COND_WAIT _IOWR(0xF5, 7, struct vsoc_cond_wait)
-#define VSOC_COND_WAKE _IO(0xF5, 8)
-#endif
diff --git a/libc/kernel/uapi/linux/watch_queue.h b/libc/kernel/uapi/linux/watch_queue.h
new file mode 100644
index 0000000..4c4fd01
--- /dev/null
+++ b/libc/kernel/uapi/linux/watch_queue.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_WATCH_QUEUE_H
+#define _UAPI_LINUX_WATCH_QUEUE_H
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/ioctl.h>
+#define O_NOTIFICATION_PIPE O_EXCL
+#define IOC_WATCH_QUEUE_SET_SIZE _IO('W', 0x60)
+#define IOC_WATCH_QUEUE_SET_FILTER _IO('W', 0x61)
+enum watch_notification_type {
+  WATCH_TYPE_META = 0,
+  WATCH_TYPE_KEY_NOTIFY = 1,
+  WATCH_TYPE__NR = 2
+};
+enum watch_meta_notification_subtype {
+  WATCH_META_REMOVAL_NOTIFICATION = 0,
+  WATCH_META_LOSS_NOTIFICATION = 1,
+};
+struct watch_notification {
+  __u32 type : 24;
+  __u32 subtype : 8;
+  __u32 info;
+#define WATCH_INFO_LENGTH 0x0000007f
+#define WATCH_INFO_LENGTH__SHIFT 0
+#define WATCH_INFO_ID 0x0000ff00
+#define WATCH_INFO_ID__SHIFT 8
+#define WATCH_INFO_TYPE_INFO 0xffff0000
+#define WATCH_INFO_TYPE_INFO__SHIFT 16
+#define WATCH_INFO_FLAG_0 0x00010000
+#define WATCH_INFO_FLAG_1 0x00020000
+#define WATCH_INFO_FLAG_2 0x00040000
+#define WATCH_INFO_FLAG_3 0x00080000
+#define WATCH_INFO_FLAG_4 0x00100000
+#define WATCH_INFO_FLAG_5 0x00200000
+#define WATCH_INFO_FLAG_6 0x00400000
+#define WATCH_INFO_FLAG_7 0x00800000
+};
+struct watch_notification_type_filter {
+  __u32 type;
+  __u32 info_filter;
+  __u32 info_mask;
+  __u32 subtype_filter[8];
+};
+struct watch_notification_filter {
+  __u32 nr_filters;
+  __u32 __reserved;
+  struct watch_notification_type_filter filters[];
+};
+struct watch_notification_removal {
+  struct watch_notification watch;
+  __u64 id;
+};
+enum key_notification_subtype {
+  NOTIFY_KEY_INSTANTIATED = 0,
+  NOTIFY_KEY_UPDATED = 1,
+  NOTIFY_KEY_LINKED = 2,
+  NOTIFY_KEY_UNLINKED = 3,
+  NOTIFY_KEY_CLEARED = 4,
+  NOTIFY_KEY_REVOKED = 5,
+  NOTIFY_KEY_INVALIDATED = 6,
+  NOTIFY_KEY_SETATTR = 7,
+};
+struct key_notification {
+  struct watch_notification watch;
+  __u32 key_id;
+  __u32 aux;
+};
+#endif
diff --git a/libc/kernel/uapi/linux/wireguard.h b/libc/kernel/uapi/linux/wireguard.h
new file mode 100644
index 0000000..6a4128b
--- /dev/null
+++ b/libc/kernel/uapi/linux/wireguard.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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 _WG_UAPI_WIREGUARD_H
+#define _WG_UAPI_WIREGUARD_H
+#define WG_GENL_NAME "wireguard"
+#define WG_GENL_VERSION 1
+#define WG_KEY_LEN 32
+enum wg_cmd {
+  WG_CMD_GET_DEVICE,
+  WG_CMD_SET_DEVICE,
+  __WG_CMD_MAX
+};
+#define WG_CMD_MAX (__WG_CMD_MAX - 1)
+enum wgdevice_flag {
+  WGDEVICE_F_REPLACE_PEERS = 1U << 0,
+  __WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS
+};
+enum wgdevice_attribute {
+  WGDEVICE_A_UNSPEC,
+  WGDEVICE_A_IFINDEX,
+  WGDEVICE_A_IFNAME,
+  WGDEVICE_A_PRIVATE_KEY,
+  WGDEVICE_A_PUBLIC_KEY,
+  WGDEVICE_A_FLAGS,
+  WGDEVICE_A_LISTEN_PORT,
+  WGDEVICE_A_FWMARK,
+  WGDEVICE_A_PEERS,
+  __WGDEVICE_A_LAST
+};
+#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
+enum wgpeer_flag {
+  WGPEER_F_REMOVE_ME = 1U << 0,
+  WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
+  WGPEER_F_UPDATE_ONLY = 1U << 2,
+  __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS | WGPEER_F_UPDATE_ONLY
+};
+enum wgpeer_attribute {
+  WGPEER_A_UNSPEC,
+  WGPEER_A_PUBLIC_KEY,
+  WGPEER_A_PRESHARED_KEY,
+  WGPEER_A_FLAGS,
+  WGPEER_A_ENDPOINT,
+  WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL,
+  WGPEER_A_LAST_HANDSHAKE_TIME,
+  WGPEER_A_RX_BYTES,
+  WGPEER_A_TX_BYTES,
+  WGPEER_A_ALLOWEDIPS,
+  WGPEER_A_PROTOCOL_VERSION,
+  __WGPEER_A_LAST
+};
+#define WGPEER_A_MAX (__WGPEER_A_LAST - 1)
+enum wgallowedip_attribute {
+  WGALLOWEDIP_A_UNSPEC,
+  WGALLOWEDIP_A_FAMILY,
+  WGALLOWEDIP_A_IPADDR,
+  WGALLOWEDIP_A_CIDR_MASK,
+  __WGALLOWEDIP_A_LAST
+};
+#define WGALLOWEDIP_A_MAX (__WGALLOWEDIP_A_LAST - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/wireless.h b/libc/kernel/uapi/linux/wireless.h
index 6d41b94..ca31dd2 100644
--- a/libc/kernel/uapi/linux/wireless.h
+++ b/libc/kernel/uapi/linux/wireless.h
@@ -21,6 +21,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/if.h>
+#include <stddef.h>
 #define WIRELESS_EXT 22
 #define SIOCSIWCOMMIT 0x8B00
 #define SIOCGIWNAME 0x8B01
@@ -435,7 +436,7 @@
 #define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
 #define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
 #define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
-#define IW_EV_POINT_OFF (((char *) & (((struct iw_point *) NULL)->length)) - (char *) NULL)
+#define IW_EV_POINT_OFF offsetof(struct iw_point, length)
 #define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - IW_EV_POINT_OFF)
 #define IW_EV_LCP_PK_LEN (4)
 #define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
diff --git a/libc/kernel/uapi/linux/xattr.h b/libc/kernel/uapi/linux/xattr.h
index 7c098f4..fd02159 100644
--- a/libc/kernel/uapi/linux/xattr.h
+++ b/libc/kernel/uapi/linux/xattr.h
@@ -30,6 +30,8 @@
 #define XATTR_MAC_OSX_PREFIX_LEN (sizeof(XATTR_MAC_OSX_PREFIX) - 1)
 #define XATTR_BTRFS_PREFIX "btrfs."
 #define XATTR_BTRFS_PREFIX_LEN (sizeof(XATTR_BTRFS_PREFIX) - 1)
+#define XATTR_HURD_PREFIX "gnu."
+#define XATTR_HURD_PREFIX_LEN (sizeof(XATTR_HURD_PREFIX) - 1)
 #define XATTR_SECURITY_PREFIX "security."
 #define XATTR_SECURITY_PREFIX_LEN (sizeof(XATTR_SECURITY_PREFIX) - 1)
 #define XATTR_SYSTEM_PREFIX "system."
diff --git a/libc/kernel/uapi/misc/habanalabs.h b/libc/kernel/uapi/misc/habanalabs.h
index 91849ec..3ae1722 100644
--- a/libc/kernel/uapi/misc/habanalabs.h
+++ b/libc/kernel/uapi/misc/habanalabs.h
@@ -21,6 +21,9 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 #define GOYA_KMD_SRAM_RESERVED_SIZE_FROM_START 0x8000
+#define GAUDI_DRIVER_SRAM_RESERVED_SIZE_FROM_START 0x80
+#define GAUDI_FIRST_AVAILABLE_W_S_SYNC_OBJECT 48
+#define GAUDI_FIRST_AVAILABLE_W_S_MONITOR 24
 enum goya_queue_id {
   GOYA_QUEUE_ID_DMA_0 = 0,
   GOYA_QUEUE_ID_DMA_1 = 1,
@@ -39,6 +42,122 @@
   GOYA_QUEUE_ID_TPC7 = 14,
   GOYA_QUEUE_ID_SIZE
 };
+enum gaudi_queue_id {
+  GAUDI_QUEUE_ID_DMA_0_0 = 0,
+  GAUDI_QUEUE_ID_DMA_0_1 = 1,
+  GAUDI_QUEUE_ID_DMA_0_2 = 2,
+  GAUDI_QUEUE_ID_DMA_0_3 = 3,
+  GAUDI_QUEUE_ID_DMA_1_0 = 4,
+  GAUDI_QUEUE_ID_DMA_1_1 = 5,
+  GAUDI_QUEUE_ID_DMA_1_2 = 6,
+  GAUDI_QUEUE_ID_DMA_1_3 = 7,
+  GAUDI_QUEUE_ID_CPU_PQ = 8,
+  GAUDI_QUEUE_ID_DMA_2_0 = 9,
+  GAUDI_QUEUE_ID_DMA_2_1 = 10,
+  GAUDI_QUEUE_ID_DMA_2_2 = 11,
+  GAUDI_QUEUE_ID_DMA_2_3 = 12,
+  GAUDI_QUEUE_ID_DMA_3_0 = 13,
+  GAUDI_QUEUE_ID_DMA_3_1 = 14,
+  GAUDI_QUEUE_ID_DMA_3_2 = 15,
+  GAUDI_QUEUE_ID_DMA_3_3 = 16,
+  GAUDI_QUEUE_ID_DMA_4_0 = 17,
+  GAUDI_QUEUE_ID_DMA_4_1 = 18,
+  GAUDI_QUEUE_ID_DMA_4_2 = 19,
+  GAUDI_QUEUE_ID_DMA_4_3 = 20,
+  GAUDI_QUEUE_ID_DMA_5_0 = 21,
+  GAUDI_QUEUE_ID_DMA_5_1 = 22,
+  GAUDI_QUEUE_ID_DMA_5_2 = 23,
+  GAUDI_QUEUE_ID_DMA_5_3 = 24,
+  GAUDI_QUEUE_ID_DMA_6_0 = 25,
+  GAUDI_QUEUE_ID_DMA_6_1 = 26,
+  GAUDI_QUEUE_ID_DMA_6_2 = 27,
+  GAUDI_QUEUE_ID_DMA_6_3 = 28,
+  GAUDI_QUEUE_ID_DMA_7_0 = 29,
+  GAUDI_QUEUE_ID_DMA_7_1 = 30,
+  GAUDI_QUEUE_ID_DMA_7_2 = 31,
+  GAUDI_QUEUE_ID_DMA_7_3 = 32,
+  GAUDI_QUEUE_ID_MME_0_0 = 33,
+  GAUDI_QUEUE_ID_MME_0_1 = 34,
+  GAUDI_QUEUE_ID_MME_0_2 = 35,
+  GAUDI_QUEUE_ID_MME_0_3 = 36,
+  GAUDI_QUEUE_ID_MME_1_0 = 37,
+  GAUDI_QUEUE_ID_MME_1_1 = 38,
+  GAUDI_QUEUE_ID_MME_1_2 = 39,
+  GAUDI_QUEUE_ID_MME_1_3 = 40,
+  GAUDI_QUEUE_ID_TPC_0_0 = 41,
+  GAUDI_QUEUE_ID_TPC_0_1 = 42,
+  GAUDI_QUEUE_ID_TPC_0_2 = 43,
+  GAUDI_QUEUE_ID_TPC_0_3 = 44,
+  GAUDI_QUEUE_ID_TPC_1_0 = 45,
+  GAUDI_QUEUE_ID_TPC_1_1 = 46,
+  GAUDI_QUEUE_ID_TPC_1_2 = 47,
+  GAUDI_QUEUE_ID_TPC_1_3 = 48,
+  GAUDI_QUEUE_ID_TPC_2_0 = 49,
+  GAUDI_QUEUE_ID_TPC_2_1 = 50,
+  GAUDI_QUEUE_ID_TPC_2_2 = 51,
+  GAUDI_QUEUE_ID_TPC_2_3 = 52,
+  GAUDI_QUEUE_ID_TPC_3_0 = 53,
+  GAUDI_QUEUE_ID_TPC_3_1 = 54,
+  GAUDI_QUEUE_ID_TPC_3_2 = 55,
+  GAUDI_QUEUE_ID_TPC_3_3 = 56,
+  GAUDI_QUEUE_ID_TPC_4_0 = 57,
+  GAUDI_QUEUE_ID_TPC_4_1 = 58,
+  GAUDI_QUEUE_ID_TPC_4_2 = 59,
+  GAUDI_QUEUE_ID_TPC_4_3 = 60,
+  GAUDI_QUEUE_ID_TPC_5_0 = 61,
+  GAUDI_QUEUE_ID_TPC_5_1 = 62,
+  GAUDI_QUEUE_ID_TPC_5_2 = 63,
+  GAUDI_QUEUE_ID_TPC_5_3 = 64,
+  GAUDI_QUEUE_ID_TPC_6_0 = 65,
+  GAUDI_QUEUE_ID_TPC_6_1 = 66,
+  GAUDI_QUEUE_ID_TPC_6_2 = 67,
+  GAUDI_QUEUE_ID_TPC_6_3 = 68,
+  GAUDI_QUEUE_ID_TPC_7_0 = 69,
+  GAUDI_QUEUE_ID_TPC_7_1 = 70,
+  GAUDI_QUEUE_ID_TPC_7_2 = 71,
+  GAUDI_QUEUE_ID_TPC_7_3 = 72,
+  GAUDI_QUEUE_ID_NIC_0_0 = 73,
+  GAUDI_QUEUE_ID_NIC_0_1 = 74,
+  GAUDI_QUEUE_ID_NIC_0_2 = 75,
+  GAUDI_QUEUE_ID_NIC_0_3 = 76,
+  GAUDI_QUEUE_ID_NIC_1_0 = 77,
+  GAUDI_QUEUE_ID_NIC_1_1 = 78,
+  GAUDI_QUEUE_ID_NIC_1_2 = 79,
+  GAUDI_QUEUE_ID_NIC_1_3 = 80,
+  GAUDI_QUEUE_ID_NIC_2_0 = 81,
+  GAUDI_QUEUE_ID_NIC_2_1 = 82,
+  GAUDI_QUEUE_ID_NIC_2_2 = 83,
+  GAUDI_QUEUE_ID_NIC_2_3 = 84,
+  GAUDI_QUEUE_ID_NIC_3_0 = 85,
+  GAUDI_QUEUE_ID_NIC_3_1 = 86,
+  GAUDI_QUEUE_ID_NIC_3_2 = 87,
+  GAUDI_QUEUE_ID_NIC_3_3 = 88,
+  GAUDI_QUEUE_ID_NIC_4_0 = 89,
+  GAUDI_QUEUE_ID_NIC_4_1 = 90,
+  GAUDI_QUEUE_ID_NIC_4_2 = 91,
+  GAUDI_QUEUE_ID_NIC_4_3 = 92,
+  GAUDI_QUEUE_ID_NIC_5_0 = 93,
+  GAUDI_QUEUE_ID_NIC_5_1 = 94,
+  GAUDI_QUEUE_ID_NIC_5_2 = 95,
+  GAUDI_QUEUE_ID_NIC_5_3 = 96,
+  GAUDI_QUEUE_ID_NIC_6_0 = 97,
+  GAUDI_QUEUE_ID_NIC_6_1 = 98,
+  GAUDI_QUEUE_ID_NIC_6_2 = 99,
+  GAUDI_QUEUE_ID_NIC_6_3 = 100,
+  GAUDI_QUEUE_ID_NIC_7_0 = 101,
+  GAUDI_QUEUE_ID_NIC_7_1 = 102,
+  GAUDI_QUEUE_ID_NIC_7_2 = 103,
+  GAUDI_QUEUE_ID_NIC_7_3 = 104,
+  GAUDI_QUEUE_ID_NIC_8_0 = 105,
+  GAUDI_QUEUE_ID_NIC_8_1 = 106,
+  GAUDI_QUEUE_ID_NIC_8_2 = 107,
+  GAUDI_QUEUE_ID_NIC_8_3 = 108,
+  GAUDI_QUEUE_ID_NIC_9_0 = 109,
+  GAUDI_QUEUE_ID_NIC_9_1 = 110,
+  GAUDI_QUEUE_ID_NIC_9_2 = 111,
+  GAUDI_QUEUE_ID_NIC_9_3 = 112,
+  GAUDI_QUEUE_ID_SIZE
+};
 enum goya_engine_id {
   GOYA_ENGINE_ID_DMA_0 = 0,
   GOYA_ENGINE_ID_DMA_1,
@@ -56,6 +175,39 @@
   GOYA_ENGINE_ID_TPC_7,
   GOYA_ENGINE_ID_SIZE
 };
+enum gaudi_engine_id {
+  GAUDI_ENGINE_ID_DMA_0 = 0,
+  GAUDI_ENGINE_ID_DMA_1,
+  GAUDI_ENGINE_ID_DMA_2,
+  GAUDI_ENGINE_ID_DMA_3,
+  GAUDI_ENGINE_ID_DMA_4,
+  GAUDI_ENGINE_ID_DMA_5,
+  GAUDI_ENGINE_ID_DMA_6,
+  GAUDI_ENGINE_ID_DMA_7,
+  GAUDI_ENGINE_ID_MME_0,
+  GAUDI_ENGINE_ID_MME_1,
+  GAUDI_ENGINE_ID_MME_2,
+  GAUDI_ENGINE_ID_MME_3,
+  GAUDI_ENGINE_ID_TPC_0,
+  GAUDI_ENGINE_ID_TPC_1,
+  GAUDI_ENGINE_ID_TPC_2,
+  GAUDI_ENGINE_ID_TPC_3,
+  GAUDI_ENGINE_ID_TPC_4,
+  GAUDI_ENGINE_ID_TPC_5,
+  GAUDI_ENGINE_ID_TPC_6,
+  GAUDI_ENGINE_ID_TPC_7,
+  GAUDI_ENGINE_ID_NIC_0,
+  GAUDI_ENGINE_ID_NIC_1,
+  GAUDI_ENGINE_ID_NIC_2,
+  GAUDI_ENGINE_ID_NIC_3,
+  GAUDI_ENGINE_ID_NIC_4,
+  GAUDI_ENGINE_ID_NIC_5,
+  GAUDI_ENGINE_ID_NIC_6,
+  GAUDI_ENGINE_ID_NIC_7,
+  GAUDI_ENGINE_ID_NIC_8,
+  GAUDI_ENGINE_ID_NIC_9,
+  GAUDI_ENGINE_ID_SIZE
+};
 enum hl_device_status {
   HL_DEVICE_STATUS_OPERATIONAL,
   HL_DEVICE_STATUS_IN_RESET,
@@ -70,6 +222,7 @@
 #define HL_INFO_HW_EVENTS_AGGREGATE 7
 #define HL_INFO_CLK_RATE 8
 #define HL_INFO_RESET_COUNT 9
+#define HL_INFO_TIME_SYNC 10
 #define HL_INFO_VERSION_MAX_LEN 128
 #define HL_INFO_CARD_NAME_MAX_LEN 16
 struct hl_info_hw_ip_info {
@@ -79,7 +232,8 @@
   __u32 sram_size;
   __u32 num_of_events;
   __u32 device_id;
-  __u32 reserved[3];
+  __u32 module_id;
+  __u32 reserved[2];
   __u32 armcp_cpld_version;
   __u32 psoc_pci_pll_nr;
   __u32 psoc_pci_pll_nf;
@@ -115,6 +269,10 @@
   __u32 hard_reset_cnt;
   __u32 soft_reset_cnt;
 };
+struct hl_info_time_sync {
+  __u64 device_time;
+  __u64 host_time;
+};
 struct hl_info_args {
   __u64 return_pointer;
   __u32 return_size;
@@ -127,7 +285,7 @@
 };
 #define HL_CB_OP_CREATE 0
 #define HL_CB_OP_DESTROY 1
-#define HL_MAX_CB_SIZE 0x200000
+#define HL_MAX_CB_SIZE (0x200000 - 32)
 struct hl_cb_in {
   __u64 cb_handle;
   __u32 op;
@@ -143,13 +301,21 @@
   struct hl_cb_out out;
 };
 struct hl_cs_chunk {
-  __u64 cb_handle;
+  union {
+    __u64 cb_handle;
+    __u64 signal_seq_arr;
+  };
   __u32 queue_index;
-  __u32 cb_size;
+  union {
+    __u32 cb_size;
+    __u32 num_signal_seq_arr;
+  };
   __u32 cs_chunk_flags;
   __u32 pad[11];
 };
 #define HL_CS_FLAGS_FORCE_RESTORE 0x1
+#define HL_CS_FLAGS_SIGNAL 0x2
+#define HL_CS_FLAGS_WAIT 0x4
 #define HL_CS_STATUS_SUCCESS 0
 #define HL_MAX_JOBS_PER_CS 512
 struct hl_cs_in {
diff --git a/libc/kernel/uapi/linux/hysdn_if.h b/libc/kernel/uapi/misc/pvpanic.h
similarity index 72%
copy from libc/kernel/uapi/linux/hysdn_if.h
copy to libc/kernel/uapi/misc/pvpanic.h
index 2aac1d0..18edcd8 100644
--- a/libc/kernel/uapi/linux/hysdn_if.h
+++ b/libc/kernel/uapi/misc/pvpanic.h
@@ -16,16 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define ERR_NONE 0
-#define ERR_ALREADY_BOOT 1000
-#define EPOF_BAD_MAGIC 1001
-#define ERR_BOARD_DPRAM 1002
-#define EPOF_INTERNAL 1003
-#define EPOF_BAD_IMG_SIZE 1004
-#define ERR_BOOTIMG_FAIL 1005
-#define ERR_BOOTSEQ_FAIL 1006
-#define ERR_POF_TIMEOUT 1007
-#define ERR_NOT_BOOTED 1008
-#define ERR_CONF_LONG 1009
-#define ERR_INV_CHAN 1010
-#define ERR_ASYNC_TIME 1011
+#ifndef __PVPANIC_H__
+#define __PVPANIC_H__
+#define PVPANIC_PANICKED (1 << 0)
+#define PVPANIC_CRASH_LOADED (1 << 1)
+#endif
diff --git a/libc/kernel/uapi/linux/hysdn_if.h b/libc/kernel/uapi/misc/uacce/hisi_qm.h
similarity index 72%
copy from libc/kernel/uapi/linux/hysdn_if.h
copy to libc/kernel/uapi/misc/uacce/hisi_qm.h
index 2aac1d0..49d9f6a 100644
--- a/libc/kernel/uapi/linux/hysdn_if.h
+++ b/libc/kernel/uapi/misc/uacce/hisi_qm.h
@@ -16,16 +16,14 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define ERR_NONE 0
-#define ERR_ALREADY_BOOT 1000
-#define EPOF_BAD_MAGIC 1001
-#define ERR_BOARD_DPRAM 1002
-#define EPOF_INTERNAL 1003
-#define EPOF_BAD_IMG_SIZE 1004
-#define ERR_BOOTIMG_FAIL 1005
-#define ERR_BOOTSEQ_FAIL 1006
-#define ERR_POF_TIMEOUT 1007
-#define ERR_NOT_BOOTED 1008
-#define ERR_CONF_LONG 1009
-#define ERR_INV_CHAN 1010
-#define ERR_ASYNC_TIME 1011
+#ifndef _UAPI_HISI_QM_H
+#define _UAPI_HISI_QM_H
+#include <linux/types.h>
+struct hisi_qp_ctx {
+  __u16 id;
+  __u16 qc_type;
+};
+#define HISI_QM_API_VER_BASE "hisi_qm_v1"
+#define HISI_QM_API_VER2_BASE "hisi_qm_v2"
+#define UACCE_CMD_QM_SET_QP_CTX _IOWR('H', 10, struct hisi_qp_ctx)
+#endif
diff --git a/libc/kernel/uapi/linux/hysdn_if.h b/libc/kernel/uapi/misc/uacce/uacce.h
similarity index 72%
copy from libc/kernel/uapi/linux/hysdn_if.h
copy to libc/kernel/uapi/misc/uacce/uacce.h
index 2aac1d0..469d188 100644
--- a/libc/kernel/uapi/linux/hysdn_if.h
+++ b/libc/kernel/uapi/misc/uacce/uacce.h
@@ -16,16 +16,15 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define ERR_NONE 0
-#define ERR_ALREADY_BOOT 1000
-#define EPOF_BAD_MAGIC 1001
-#define ERR_BOARD_DPRAM 1002
-#define EPOF_INTERNAL 1003
-#define EPOF_BAD_IMG_SIZE 1004
-#define ERR_BOOTIMG_FAIL 1005
-#define ERR_BOOTSEQ_FAIL 1006
-#define ERR_POF_TIMEOUT 1007
-#define ERR_NOT_BOOTED 1008
-#define ERR_CONF_LONG 1009
-#define ERR_INV_CHAN 1010
-#define ERR_ASYNC_TIME 1011
+#ifndef _UAPIUUACCE_H
+#define _UAPIUUACCE_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define UACCE_CMD_START_Q _IO('W', 0)
+#define UACCE_CMD_PUT_Q _IO('W', 1)
+#define UACCE_DEV_SVA BIT(0)
+enum uacce_qfrt {
+  UACCE_QFRT_MMIO = 0,
+  UACCE_QFRT_DUS = 1,
+};
+#endif
diff --git a/libc/kernel/uapi/mtd/mtd-abi.h b/libc/kernel/uapi/mtd/mtd-abi.h
index e1e0d59..680ac1e 100644
--- a/libc/kernel/uapi/mtd/mtd-abi.h
+++ b/libc/kernel/uapi/mtd/mtd-abi.h
@@ -64,6 +64,7 @@
 #define MTD_BIT_WRITEABLE 0x800
 #define MTD_NO_ERASE 0x1000
 #define MTD_POWERUP_LOCK 0x2000
+#define MTD_SLC_ON_MLC_EMULATION 0x4000
 #define MTD_CAP_ROM 0
 #define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
 #define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE)
diff --git a/libc/kernel/uapi/rdma/hfi/hfi1_user.h b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
index e74d837..3352907 100644
--- a/libc/kernel/uapi/rdma/hfi/hfi1_user.h
+++ b/libc/kernel/uapi/rdma/hfi/hfi1_user.h
@@ -42,6 +42,7 @@
 #define HFI1_CAP_OPFN (1UL << 16)
 #define HFI1_CAP_SDMA_HEAD_CHECK (1UL << 17)
 #define HFI1_CAP_EARLY_CREDIT_RETURN (1UL << 18)
+#define HFI1_CAP_AIP (1UL << 19)
 #define HFI1_RCVHDR_ENTSIZE_2 (1UL << 0)
 #define HFI1_RCVHDR_ENTSIZE_16 (1UL << 1)
 #define HFI1_RCVDHR_ENTSIZE_32 (1UL << 2)
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
index ebf8b7c..e38bd93 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_cmds.h
@@ -39,6 +39,7 @@
   UVERBS_OBJECT_FLOW_ACTION,
   UVERBS_OBJECT_DM,
   UVERBS_OBJECT_COUNTERS,
+  UVERBS_OBJECT_ASYNC_EVENT,
 };
 enum {
   UVERBS_ATTR_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG,
@@ -48,6 +49,7 @@
   UVERBS_METHOD_INVOKE_WRITE,
   UVERBS_METHOD_INFO_HANDLES,
   UVERBS_METHOD_QUERY_PORT,
+  UVERBS_METHOD_GET_CONTEXT,
 };
 enum uverbs_attrs_invoke_write_cmd_attr_ids {
   UVERBS_ATTR_CORE_IN,
@@ -58,6 +60,10 @@
   UVERBS_ATTR_QUERY_PORT_PORT_NUM,
   UVERBS_ATTR_QUERY_PORT_RESP,
 };
+enum uverbs_attrs_get_context_attr_ids {
+  UVERBS_ATTR_GET_CONTEXT_NUM_COMP_VECTORS,
+  UVERBS_ATTR_GET_CONTEXT_CORE_SUPPORT,
+};
 enum uverbs_attrs_create_cq_cmd_attr_ids {
   UVERBS_ATTR_CREATE_CQ_HANDLE,
   UVERBS_ATTR_CREATE_CQ_CQE,
@@ -66,6 +72,7 @@
   UVERBS_ATTR_CREATE_CQ_COMP_VECTOR,
   UVERBS_ATTR_CREATE_CQ_FLAGS,
   UVERBS_ATTR_CREATE_CQ_RESP_CQE,
+  UVERBS_ATTR_CREATE_CQ_EVENT_FD,
 };
 enum uverbs_attrs_destroy_cq_cmd_attr_ids {
   UVERBS_ATTR_DESTROY_CQ_HANDLE,
@@ -85,10 +92,81 @@
 enum uverbs_attrs_destroy_flow_action_esp {
   UVERBS_ATTR_DESTROY_FLOW_ACTION_HANDLE,
 };
+enum uverbs_attrs_create_qp_cmd_attr_ids {
+  UVERBS_ATTR_CREATE_QP_HANDLE,
+  UVERBS_ATTR_CREATE_QP_XRCD_HANDLE,
+  UVERBS_ATTR_CREATE_QP_PD_HANDLE,
+  UVERBS_ATTR_CREATE_QP_SRQ_HANDLE,
+  UVERBS_ATTR_CREATE_QP_SEND_CQ_HANDLE,
+  UVERBS_ATTR_CREATE_QP_RECV_CQ_HANDLE,
+  UVERBS_ATTR_CREATE_QP_IND_TABLE_HANDLE,
+  UVERBS_ATTR_CREATE_QP_USER_HANDLE,
+  UVERBS_ATTR_CREATE_QP_CAP,
+  UVERBS_ATTR_CREATE_QP_TYPE,
+  UVERBS_ATTR_CREATE_QP_FLAGS,
+  UVERBS_ATTR_CREATE_QP_SOURCE_QPN,
+  UVERBS_ATTR_CREATE_QP_EVENT_FD,
+  UVERBS_ATTR_CREATE_QP_RESP_CAP,
+  UVERBS_ATTR_CREATE_QP_RESP_QP_NUM,
+};
+enum uverbs_attrs_destroy_qp_cmd_attr_ids {
+  UVERBS_ATTR_DESTROY_QP_HANDLE,
+  UVERBS_ATTR_DESTROY_QP_RESP,
+};
+enum uverbs_methods_qp {
+  UVERBS_METHOD_QP_CREATE,
+  UVERBS_METHOD_QP_DESTROY,
+};
+enum uverbs_attrs_create_srq_cmd_attr_ids {
+  UVERBS_ATTR_CREATE_SRQ_HANDLE,
+  UVERBS_ATTR_CREATE_SRQ_PD_HANDLE,
+  UVERBS_ATTR_CREATE_SRQ_XRCD_HANDLE,
+  UVERBS_ATTR_CREATE_SRQ_CQ_HANDLE,
+  UVERBS_ATTR_CREATE_SRQ_USER_HANDLE,
+  UVERBS_ATTR_CREATE_SRQ_MAX_WR,
+  UVERBS_ATTR_CREATE_SRQ_MAX_SGE,
+  UVERBS_ATTR_CREATE_SRQ_LIMIT,
+  UVERBS_ATTR_CREATE_SRQ_MAX_NUM_TAGS,
+  UVERBS_ATTR_CREATE_SRQ_TYPE,
+  UVERBS_ATTR_CREATE_SRQ_EVENT_FD,
+  UVERBS_ATTR_CREATE_SRQ_RESP_MAX_WR,
+  UVERBS_ATTR_CREATE_SRQ_RESP_MAX_SGE,
+  UVERBS_ATTR_CREATE_SRQ_RESP_SRQ_NUM,
+};
+enum uverbs_attrs_destroy_srq_cmd_attr_ids {
+  UVERBS_ATTR_DESTROY_SRQ_HANDLE,
+  UVERBS_ATTR_DESTROY_SRQ_RESP,
+};
+enum uverbs_methods_srq {
+  UVERBS_METHOD_SRQ_CREATE,
+  UVERBS_METHOD_SRQ_DESTROY,
+};
 enum uverbs_methods_cq {
   UVERBS_METHOD_CQ_CREATE,
   UVERBS_METHOD_CQ_DESTROY,
 };
+enum uverbs_attrs_create_wq_cmd_attr_ids {
+  UVERBS_ATTR_CREATE_WQ_HANDLE,
+  UVERBS_ATTR_CREATE_WQ_PD_HANDLE,
+  UVERBS_ATTR_CREATE_WQ_CQ_HANDLE,
+  UVERBS_ATTR_CREATE_WQ_USER_HANDLE,
+  UVERBS_ATTR_CREATE_WQ_TYPE,
+  UVERBS_ATTR_CREATE_WQ_EVENT_FD,
+  UVERBS_ATTR_CREATE_WQ_MAX_WR,
+  UVERBS_ATTR_CREATE_WQ_MAX_SGE,
+  UVERBS_ATTR_CREATE_WQ_FLAGS,
+  UVERBS_ATTR_CREATE_WQ_RESP_MAX_WR,
+  UVERBS_ATTR_CREATE_WQ_RESP_MAX_SGE,
+  UVERBS_ATTR_CREATE_WQ_RESP_WQ_NUM,
+};
+enum uverbs_attrs_destroy_wq_cmd_attr_ids {
+  UVERBS_ATTR_DESTROY_WQ_HANDLE,
+  UVERBS_ATTR_DESTROY_WQ_RESP,
+};
+enum uverbs_methods_wq {
+  UVERBS_METHOD_WQ_CREATE,
+  UVERBS_METHOD_WQ_DESTROY,
+};
 enum uverbs_methods_actions_flow_action_ops {
   UVERBS_METHOD_FLOW_ACTION_ESP_CREATE,
   UVERBS_METHOD_FLOW_ACTION_DESTROY,
@@ -187,4 +265,10 @@
 enum uverbs_attrs_flow_destroy_ids {
   UVERBS_ATTR_DESTROY_FLOW_HANDLE,
 };
+enum uverbs_method_async_event {
+  UVERBS_METHOD_ASYNC_EVENT_ALLOC,
+};
+enum uverbs_attrs_async_event_create {
+  UVERBS_ATTR_ASYNC_EVENT_ALLOC_FD_HANDLE,
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
index 1394ed7..7880312 100644
--- a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
@@ -23,6 +23,11 @@
 #ifndef RDMA_UAPI_PTR
 #define RDMA_UAPI_PTR(_type,_name) __aligned_u64 _name
 #endif
+#define IB_UVERBS_ACCESS_OPTIONAL_FIRST (1 << 20)
+#define IB_UVERBS_ACCESS_OPTIONAL_LAST (1 << 29)
+enum ib_uverbs_core_support {
+  IB_UVERBS_CORE_SUPPORT_OPTIONAL_MR_ACCESS = 1 << 0,
+};
 enum ib_uverbs_access_flags {
   IB_UVERBS_ACCESS_LOCAL_WRITE = 1 << 0,
   IB_UVERBS_ACCESS_REMOTE_WRITE = 1 << 1,
@@ -32,6 +37,38 @@
   IB_UVERBS_ACCESS_ZERO_BASED = 1 << 5,
   IB_UVERBS_ACCESS_ON_DEMAND = 1 << 6,
   IB_UVERBS_ACCESS_HUGETLB = 1 << 7,
+  IB_UVERBS_ACCESS_RELAXED_ORDERING = IB_UVERBS_ACCESS_OPTIONAL_FIRST,
+  IB_UVERBS_ACCESS_OPTIONAL_RANGE = ((IB_UVERBS_ACCESS_OPTIONAL_LAST << 1) - 1) & ~(IB_UVERBS_ACCESS_OPTIONAL_FIRST - 1)
+};
+enum ib_uverbs_srq_type {
+  IB_UVERBS_SRQT_BASIC,
+  IB_UVERBS_SRQT_XRC,
+  IB_UVERBS_SRQT_TM,
+};
+enum ib_uverbs_wq_type {
+  IB_UVERBS_WQT_RQ,
+};
+enum ib_uverbs_wq_flags {
+  IB_UVERBS_WQ_FLAGS_CVLAN_STRIPPING = 1 << 0,
+  IB_UVERBS_WQ_FLAGS_SCATTER_FCS = 1 << 1,
+  IB_UVERBS_WQ_FLAGS_DELAY_DROP = 1 << 2,
+  IB_UVERBS_WQ_FLAGS_PCI_WRITE_END_PADDING = 1 << 3,
+};
+enum ib_uverbs_qp_type {
+  IB_UVERBS_QPT_RC = 2,
+  IB_UVERBS_QPT_UC,
+  IB_UVERBS_QPT_UD,
+  IB_UVERBS_QPT_RAW_PACKET = 8,
+  IB_UVERBS_QPT_XRC_INI,
+  IB_UVERBS_QPT_XRC_TGT,
+  IB_UVERBS_QPT_DRIVER = 0xFF,
+};
+enum ib_uverbs_qp_create_flags {
+  IB_UVERBS_QP_CREATE_BLOCK_MULTICAST_LOOPBACK = 1 << 1,
+  IB_UVERBS_QP_CREATE_SCATTER_FCS = 1 << 8,
+  IB_UVERBS_QP_CREATE_CVLAN_STRIPPING = 1 << 9,
+  IB_UVERBS_QP_CREATE_PCI_WRITE_END_PADDING = 1 << 11,
+  IB_UVERBS_QP_CREATE_SQ_SIG_ALL = 1 << 12,
 };
 enum ib_uverbs_query_port_cap_flags {
   IB_UVERBS_PCF_SM = 1 << 1,
@@ -125,6 +162,13 @@
   __u16 port_cap_flags2;
   __u8 reserved[6];
 };
+struct ib_uverbs_qp_cap {
+  __u32 max_send_wr;
+  __u32 max_recv_wr;
+  __u32 max_send_sge;
+  __u32 max_recv_sge;
+  __u32 max_inline_data;
+};
 enum rdma_driver_id {
   RDMA_DRIVER_UNKNOWN,
   RDMA_DRIVER_MLX5,
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index e01b6d3..59a9f53 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -32,6 +32,7 @@
   MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC = 1 << 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,
 };
 enum {
   MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
@@ -46,6 +47,7 @@
 };
 enum mlx5_lib_caps {
   MLX5_LIB_CAP_4K_UAR = (__u64) 1 << 0,
+  MLX5_LIB_CAP_DYN_UAR = (__u64) 1 << 1,
 };
 enum mlx5_ib_alloc_uctx_v2_flags {
   MLX5_IB_ALLOC_UCTX_DEVX = 1 << 0,
@@ -64,6 +66,7 @@
 enum mlx5_ib_alloc_ucontext_resp_mask {
   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,
 };
 enum mlx5_user_cmds_supp_uhw {
   MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE = 1 << 0,
@@ -189,6 +192,7 @@
 };
 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,
 };
 struct mlx5_ib_create_cq {
   __aligned_u64 buf_addr;
@@ -197,6 +201,9 @@
   __u8 cqe_comp_en;
   __u8 cqe_comp_res_format;
   __u16 flags;
+  __u16 uar_page_index;
+  __u16 reserved0;
+  __u32 reserved1;
 };
 struct mlx5_ib_create_cq_resp {
   __u32 cqn;
@@ -233,6 +240,8 @@
     __aligned_u64 sq_buf_addr;
     __aligned_u64 access_key;
   };
+  __u32 ece_options;
+  __u32 reserved;
 };
 enum mlx5_rx_hash_function_flags {
   MLX5_RX_HASH_FUNC_TOEPLITZ = 1 << 0,
@@ -267,7 +276,7 @@
 };
 struct mlx5_ib_create_qp_resp {
   __u32 bfreg_index;
-  __u32 reserved;
+  __u32 ece_options;
   __u32 comp_mask;
   __u32 tirn;
   __u32 tisn;
@@ -310,11 +319,13 @@
 struct mlx5_ib_modify_qp {
   __u32 comp_mask;
   struct mlx5_ib_burst_info burst_info;
-  __u32 reserved;
+  __u32 ece_options;
 };
 struct mlx5_ib_modify_qp_resp {
   __u32 response_length;
   __u32 dctn;
+  __u32 ece_options;
+  __u32 reserved;
 };
 struct mlx5_ib_create_wq_resp {
   __u32 response_length;
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
index 1cd3339..0b7cead 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -85,6 +85,33 @@
   MLX5_IB_METHOD_DEVX_OBJ_QUERY,
   MLX5_IB_METHOD_DEVX_OBJ_ASYNC_QUERY,
 };
+enum mlx5_ib_var_alloc_attrs {
+  MLX5_IB_ATTR_VAR_OBJ_ALLOC_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_ATTR_VAR_OBJ_ALLOC_MMAP_OFFSET,
+  MLX5_IB_ATTR_VAR_OBJ_ALLOC_MMAP_LENGTH,
+  MLX5_IB_ATTR_VAR_OBJ_ALLOC_PAGE_ID,
+};
+enum mlx5_ib_var_obj_destroy_attrs {
+  MLX5_IB_ATTR_VAR_OBJ_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum mlx5_ib_var_obj_methods {
+  MLX5_IB_METHOD_VAR_OBJ_ALLOC = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_METHOD_VAR_OBJ_DESTROY,
+};
+enum mlx5_ib_uar_alloc_attrs {
+  MLX5_IB_ATTR_UAR_OBJ_ALLOC_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_ATTR_UAR_OBJ_ALLOC_TYPE,
+  MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_OFFSET,
+  MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_LENGTH,
+  MLX5_IB_ATTR_UAR_OBJ_ALLOC_PAGE_ID,
+};
+enum mlx5_ib_uar_obj_destroy_attrs {
+  MLX5_IB_ATTR_UAR_OBJ_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum mlx5_ib_uar_obj_methods {
+  MLX5_IB_METHOD_UAR_OBJ_ALLOC = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_METHOD_UAR_OBJ_DESTROY,
+};
 enum mlx5_ib_devx_umem_reg_attrs {
   MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
   MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR,
@@ -95,6 +122,19 @@
 enum mlx5_ib_devx_umem_dereg_attrs {
   MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
 };
+enum mlx5_ib_pp_obj_methods {
+  MLX5_IB_METHOD_PP_OBJ_ALLOC = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_METHOD_PP_OBJ_DESTROY,
+};
+enum mlx5_ib_pp_alloc_attrs {
+  MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX,
+  MLX5_IB_ATTR_PP_OBJ_ALLOC_FLAGS,
+  MLX5_IB_ATTR_PP_OBJ_ALLOC_INDEX,
+};
+enum mlx5_ib_pp_obj_destroy_attrs {
+  MLX5_IB_ATTR_PP_OBJ_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
 enum mlx5_ib_devx_umem_methods {
   MLX5_IB_METHOD_DEVX_UMEM_REG = (1U << UVERBS_ID_NS_SHIFT),
   MLX5_IB_METHOD_DEVX_UMEM_DEREG,
@@ -119,6 +159,9 @@
   MLX5_IB_OBJECT_FLOW_MATCHER,
   MLX5_IB_OBJECT_DEVX_ASYNC_CMD_FD,
   MLX5_IB_OBJECT_DEVX_ASYNC_EVENT_FD,
+  MLX5_IB_OBJECT_VAR,
+  MLX5_IB_OBJECT_PP,
+  MLX5_IB_OBJECT_UAR,
 };
 enum mlx5_ib_flow_matcher_create_attrs {
   MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
@@ -145,6 +188,10 @@
   MLX5_IB_FLOW_TYPE_ALL_DEFAULT,
   MLX5_IB_FLOW_TYPE_MC_DEFAULT,
 };
+enum mlx5_ib_create_flow_flags {
+  MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS = 1 << 0,
+  MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP = 1 << 1,
+};
 enum mlx5_ib_create_flow_attrs {
   MLX5_IB_ATTR_CREATE_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
   MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE,
@@ -155,6 +202,7 @@
   MLX5_IB_ATTR_CREATE_FLOW_TAG,
   MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
   MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
+  MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
 };
 enum mlx5_ib_destoy_flow_attrs {
   MLX5_IB_ATTR_DESTROY_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index dc2e69d..bfbfd76 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -27,6 +27,7 @@
   MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX = 0x1,
   MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB = 0x2,
   MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_RX = 0x3,
+  MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_TX = 0x4,
 };
 enum mlx5_ib_uapi_flow_action_packet_reformat_type {
   MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2 = 0x0,
@@ -50,4 +51,11 @@
   __aligned_u64 cookie;
   __u8 out_data[];
 };
+enum mlx5_ib_uapi_pp_alloc_flags {
+  MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX = 1 << 0,
+};
+enum mlx5_ib_uapi_uar_alloc_type {
+  MLX5_IB_UAPI_UAR_ALLOC_TYPE_BF = 0x0,
+  MLX5_IB_UAPI_UAR_ALLOC_TYPE_NC = 0x1,
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/qedr-abi.h b/libc/kernel/uapi/rdma/qedr-abi.h
index fd96309..2e666f3 100644
--- a/libc/kernel/uapi/rdma/qedr-abi.h
+++ b/libc/kernel/uapi/rdma/qedr-abi.h
@@ -28,6 +28,16 @@
   __u32 context_flags;
   __u32 reserved;
 };
+#define QEDR_LDPM_MAX_SIZE (8192)
+#define QEDR_EDPM_TRANS_SIZE (64)
+enum qedr_rdma_dpm_type {
+  QEDR_DPM_TYPE_NONE = 0,
+  QEDR_DPM_TYPE_ROCE_ENHANCED = 1 << 0,
+  QEDR_DPM_TYPE_ROCE_LEGACY = 1 << 1,
+  QEDR_DPM_TYPE_IWARP_LEGACY = 1 << 2,
+  QEDR_DPM_TYPE_RESERVED = 1 << 3,
+  QEDR_DPM_SIZES_SET = 1 << 4,
+};
 struct qedr_alloc_ucontext_resp {
   __aligned_u64 db_pa;
   __u32 db_size;
@@ -38,10 +48,12 @@
   __u32 sges_per_recv_wr;
   __u32 sges_per_srq_wr;
   __u32 max_cqes;
-  __u8 dpm_enabled;
+  __u8 dpm_flags;
   __u8 wids_enabled;
   __u16 wid_count;
-  __u32 reserved;
+  __u16 ldpm_limit_size;
+  __u8 edpm_trans_size;
+  __u8 reserved;
 };
 struct qedr_alloc_pd_ureq {
   __aligned_u64 rsvd1;
diff --git a/libc/kernel/uapi/rdma/rdma_user_cm.h b/libc/kernel/uapi/rdma/rdma_user_cm.h
index 9042b6f..9618734 100644
--- a/libc/kernel/uapi/rdma/rdma_user_cm.h
+++ b/libc/kernel/uapi/rdma/rdma_user_cm.h
@@ -127,6 +127,8 @@
   __u32 num_paths;
   __u8 port_num;
   __u8 reserved[3];
+  __u32 ibdev_index;
+  __u32 reserved1;
 };
 struct rdma_ucm_query_addr_resp {
   __aligned_u64 node_guid;
@@ -137,6 +139,8 @@
   __u16 dst_size;
   struct sockaddr_storage src_addr;
   struct sockaddr_storage dst_addr;
+  __u32 ibdev_index;
+  __u32 reserved1;
 };
 struct rdma_ucm_query_path_resp {
   __u32 num_paths;
@@ -164,10 +168,15 @@
   __u8 private_data_len;
   __u8 reserved[7];
 };
+struct rdma_ucm_ece {
+  __u32 vendor_id;
+  __u32 attr_mod;
+};
 struct rdma_ucm_connect {
   struct rdma_ucm_conn_param conn_param;
   __u32 id;
   __u32 reserved;
+  struct rdma_ucm_ece ece;
 };
 struct rdma_ucm_listen {
   __u32 id;
@@ -178,11 +187,13 @@
   struct rdma_ucm_conn_param conn_param;
   __u32 id;
   __u32 reserved;
+  struct rdma_ucm_ece ece;
 };
 struct rdma_ucm_reject {
   __u32 id;
   __u8 private_data_len;
-  __u8 reserved[3];
+  __u8 reason;
+  __u8 reserved[2];
   __u8 private_data[RDMA_MAX_PRIVATE_DATA];
 };
 struct rdma_ucm_disconnect {
@@ -229,6 +240,7 @@
     struct rdma_ucm_ud_param ud;
   } param;
   __u32 reserved;
+  struct rdma_ucm_ece ece;
 };
 enum {
   RDMA_OPTION_ID = 0,
diff --git a/libc/kernel/uapi/scsi/fc/fc_els.h b/libc/kernel/uapi/scsi/fc/fc_els.h
index 1cabadd..843bc4e 100644
--- a/libc/kernel/uapi/scsi/fc/fc_els.h
+++ b/libc/kernel/uapi/scsi/fc/fc_els.h
@@ -19,6 +19,7 @@
 #ifndef _FC_ELS_H_
 #define _FC_ELS_H_
 #include <linux/types.h>
+#include <asm/byteorder.h>
 enum fc_els_cmd {
   ELS_LS_RJT = 0x01,
   ELS_LS_ACC = 0x02,
@@ -41,6 +42,7 @@
   ELS_REC = 0x13,
   ELS_SRR = 0x14,
   ELS_FPIN = 0x16,
+  ELS_RDF = 0x19,
   ELS_PRLI = 0x20,
   ELS_PRLO = 0x21,
   ELS_SCN = 0x22,
@@ -82,7 +84,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_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_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;
@@ -123,6 +125,32 @@
   ELS_EXPL_INV_LEN = 0x2d,
   ELS_EXPL_NOT_NEIGHBOR = 0x62,
 };
+enum fc_ls_tlv_dtag {
+  ELS_DTAG_LS_REQ_INFO = 0x00000001,
+  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" }, \
+}
+struct fc_tlv_desc {
+  __be32 desc_tag;
+  __be32 desc_len;
+  __u8 desc_value[0];
+};
+#define FC_TLV_DESC_HDR_SZ sizeof(struct fc_tlv_desc)
+#define FC_TLV_DESC_LENGTH_FROM_SZ(desc) (sizeof(desc) - FC_TLV_DESC_HDR_SZ)
+#define FC_TLV_DESC_SZ_FROM_LENGTH(tlv) (__be32_to_cpu((tlv)->desc_len) + FC_TLV_DESC_HDR_SZ)
+struct fc_els_lsri_desc {
+  __be32 desc_tag;
+  __be32 desc_len;
+  struct {
+    __u8 cmd;
+    __u8 bytes[3];
+  } rqst_w0;
+};
 struct fc_els_csp {
   __u8 sp_hi_ver;
   __u8 sp_lo_ver;
@@ -543,20 +571,52 @@
   ELS_CLID_IC_LOOP_TO = 7,
   ELS_CLID_IC_LIP = 8,
 };
-enum fc_fn_dtag {
-  ELS_FN_DTAG_LNK_INTEGRITY = 0x00020001,
-  ELS_FN_DTAG_PEER_CONGEST = 0x00020003,
-  ELS_FN_DTAG_CONGESTION = 0x00020004,
+enum fc_fpin_li_event_types {
+  FPIN_LI_UNKNOWN = 0x0,
+  FPIN_LI_LINK_FAILURE = 0x1,
+  FPIN_LI_LOSS_OF_SYNC = 0x2,
+  FPIN_LI_LOSS_OF_SIG = 0x3,
+  FPIN_LI_PRIM_SEQ_ERR = 0x4,
+  FPIN_LI_INVALID_TX_WD = 0x5,
+  FPIN_LI_INVALID_CRC = 0x6,
+  FPIN_LI_DEVICE_SPEC = 0xF,
 };
-struct fc_fn_desc {
-  __be32 fn_desc_tag;
-  __be32 fn_desc_value_len;
-  __u8 fn_desc_value[0];
+#define FC_FPIN_LI_EVT_TYPES_INIT { { FPIN_LI_UNKNOWN, "Unknown" }, { FPIN_LI_LINK_FAILURE, "Link Failure" }, { FPIN_LI_LOSS_OF_SYNC, "Loss of Synchronization" }, { FPIN_LI_LOSS_OF_SIG, "Loss of Signal" }, { FPIN_LI_PRIM_SEQ_ERR, "Primitive Sequence Protocol Error" }, { FPIN_LI_INVALID_TX_WD, "Invalid Transmission Word" }, { FPIN_LI_INVALID_CRC, "Invalid CRC" }, { FPIN_LI_DEVICE_SPEC, "Device Specific" }, \
+}
+struct fc_fn_li_desc {
+  __be32 desc_tag;
+  __be32 desc_len;
+  __be64 detecting_wwpn;
+  __be64 attached_wwpn;
+  __be16 event_type;
+  __be16 event_modifier;
+  __be32 event_threshold;
+  __be32 event_count;
+  __be32 pname_count;
+  __be64 pname_list[0];
 };
 struct fc_els_fpin {
   __u8 fpin_cmd;
   __u8 fpin_zero[3];
-  __be32 fpin_desc_cnt;
-  struct fc_fn_desc fpin_desc[0];
+  __be32 desc_len;
+  struct fc_tlv_desc fpin_desc[0];
+};
+struct fc_df_desc_fpin_reg {
+  __be32 desc_tag;
+  __be32 desc_len;
+  __be32 count;
+  __be32 desc_tags[0];
+};
+struct fc_els_rdf {
+  __u8 fpin_cmd;
+  __u8 fpin_zero[3];
+  __be32 desc_len;
+  struct fc_tlv_desc desc[0];
+};
+struct fc_els_rdf_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/scsi/scsi_bsg_ufs.h b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
index 177cae9..ae5c757 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_ufs.h
@@ -46,7 +46,6 @@
   union {
     struct utp_upiu_cmd sc;
     struct utp_upiu_query qr;
-    struct utp_upiu_query tr;
     struct utp_upiu_query uc;
   };
 };
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index abc81dd..397cccc 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -20,7 +20,9 @@
 #define _UAPI__SOUND_ASOUND_H
 #ifdef __linux__
 #include <linux/types.h>
+#include <asm/byteorder.h>
 #else
+#include <endian.h>
 #include <sys/ioctl.h>
 #endif
 #include <stdlib.h>
@@ -101,7 +103,7 @@
 #define SNDRV_HWDEP_IOCTL_INFO _IOR('H', 0x01, struct snd_hwdep_info)
 #define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
 #define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15)
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
 enum {
@@ -234,6 +236,9 @@
 #define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000
 #define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000
 #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000
+#if __BITS_PER_LONG == 32 && defined(__USE_TIME_BITS64)
+#define __SND_STRUCT_TIME64
+#endif
 typedef int __bitwise snd_pcm_state_t;
 #define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0)
 #define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1)
@@ -247,8 +252,17 @@
 #define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
 enum {
   SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
-  SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
-  SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
+  SNDRV_PCM_MMAP_OFFSET_STATUS_OLD = 0x80000000,
+  SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD = 0x81000000,
+  SNDRV_PCM_MMAP_OFFSET_STATUS_NEW = 0x82000000,
+  SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW = 0x83000000,
+#ifdef __SND_STRUCT_TIME64
+  SNDRV_PCM_MMAP_OFFSET_STATUS = SNDRV_PCM_MMAP_OFFSET_STATUS_NEW,
+  SNDRV_PCM_MMAP_OFFSET_CONTROL = SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW,
+#else
+  SNDRV_PCM_MMAP_OFFSET_STATUS = SNDRV_PCM_MMAP_OFFSET_STATUS_OLD,
+  SNDRV_PCM_MMAP_OFFSET_CONTROL = SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD,
+#endif
 };
 union snd_pcm_sync_id {
   unsigned char id[16];
@@ -351,8 +365,12 @@
   SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5,
   SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
 };
+typedef struct {
+  unsigned char pad[sizeof(time_t) - sizeof(int)];
+} __time_pad;
 struct snd_pcm_status {
   snd_pcm_state_t state;
+  __time_pad pad1;
   struct timespec trigger_tstamp;
   struct timespec tstamp;
   snd_pcm_uframes_t appl_ptr;
@@ -368,29 +386,87 @@
   __u32 audio_tstamp_accuracy;
   unsigned char reserved[52 - 2 * sizeof(struct timespec)];
 };
-struct snd_pcm_mmap_status {
+#ifdef __SND_STRUCT_TIME64
+#define __snd_pcm_mmap_status64 snd_pcm_mmap_status
+#define __snd_pcm_mmap_control64 snd_pcm_mmap_control
+#define __snd_pcm_sync_ptr64 snd_pcm_sync_ptr
+#define __snd_timespec64 timespec
+struct __snd_timespec {
+  __s32 tv_sec;
+  __s32 tv_nsec;
+};
+#else
+#define __snd_pcm_mmap_status snd_pcm_mmap_status
+#define __snd_pcm_mmap_control snd_pcm_mmap_control
+#define __snd_pcm_sync_ptr snd_pcm_sync_ptr
+#define __snd_timespec timespec
+struct __snd_timespec64 {
+  __s64 tv_sec;
+  __s64 tv_nsec;
+};
+#endif
+struct __snd_pcm_mmap_status {
   snd_pcm_state_t state;
   int pad1;
   snd_pcm_uframes_t hw_ptr;
-  struct timespec tstamp;
+  struct __snd_timespec tstamp;
   snd_pcm_state_t suspended_state;
-  struct timespec audio_tstamp;
+  struct __snd_timespec audio_tstamp;
 };
-struct snd_pcm_mmap_control {
+struct __snd_pcm_mmap_control {
   snd_pcm_uframes_t appl_ptr;
   snd_pcm_uframes_t avail_min;
 };
 #define SNDRV_PCM_SYNC_PTR_HWSYNC (1 << 0)
 #define SNDRV_PCM_SYNC_PTR_APPL (1 << 1)
 #define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1 << 2)
-struct snd_pcm_sync_ptr {
+struct __snd_pcm_sync_ptr {
   unsigned int flags;
   union {
-    struct snd_pcm_mmap_status status;
+    struct __snd_pcm_mmap_status status;
     unsigned char reserved[64];
   } s;
   union {
-    struct snd_pcm_mmap_control control;
+    struct __snd_pcm_mmap_control control;
+    unsigned char reserved[64];
+  } c;
+};
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
+typedef char __pad_before_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)];
+typedef char __pad_after_uframe[0];
+#endif
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
+typedef char __pad_before_uframe[0];
+typedef char __pad_after_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)];
+#endif
+struct __snd_pcm_mmap_status64 {
+  snd_pcm_state_t state;
+  __u32 pad1;
+  __pad_before_uframe __pad1;
+  snd_pcm_uframes_t hw_ptr;
+  __pad_after_uframe __pad2;
+  struct __snd_timespec64 tstamp;
+  snd_pcm_state_t suspended_state;
+  __u32 pad3;
+  struct __snd_timespec64 audio_tstamp;
+};
+struct __snd_pcm_mmap_control64 {
+  __pad_before_uframe __pad1;
+  snd_pcm_uframes_t appl_ptr;
+  __pad_before_uframe __pad2;
+  __pad_before_uframe __pad3;
+  snd_pcm_uframes_t avail_min;
+  __pad_after_uframe __pad4;
+};
+struct __snd_pcm_sync_ptr64 {
+  __u32 flags;
+  __u32 pad1;
+  union {
+    struct __snd_pcm_mmap_status64 status;
+    unsigned char reserved[64];
+  } s;
+  union {
+    struct __snd_pcm_mmap_control64 control;
     unsigned char reserved[64];
   } c;
 };
@@ -465,6 +541,8 @@
 #define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status)
 #define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t)
 #define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
+#define __SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct __snd_pcm_sync_ptr)
+#define __SNDRV_PCM_IOCTL_SYNC_PTR64 _IOWR('A', 0x23, struct __snd_pcm_sync_ptr64)
 #define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr)
 #define SNDRV_PCM_IOCTL_STATUS_EXT _IOWR('A', 0x24, struct snd_pcm_status)
 #define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info)
@@ -484,7 +562,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, 0)
+#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1)
 enum {
   SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
   SNDRV_RAWMIDI_STREAM_INPUT,
@@ -515,6 +593,7 @@
 };
 struct snd_rawmidi_status {
   int stream;
+  __time_pad pad1;
   struct timespec tstamp;
   size_t avail;
   size_t xruns;
@@ -526,7 +605,7 @@
 #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
 #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
 #define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
-#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
+#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
 enum {
   SNDRV_TIMER_CLASS_NONE = - 1,
   SNDRV_TIMER_CLASS_SLAVE = 0,
@@ -614,7 +693,7 @@
 };
 #define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
 #define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id)
-#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
+#define SNDRV_TIMER_IOCTL_TREAD_OLD _IOW('T', 0x02, int)
 #define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo)
 #define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams)
 #define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus)
@@ -626,6 +705,12 @@
 #define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
 #define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
 #define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
+#define SNDRV_TIMER_IOCTL_TREAD64 _IOW('T', 0xa4, int)
+#if __BITS_PER_LONG == 64
+#define SNDRV_TIMER_IOCTL_TREAD SNDRV_TIMER_IOCTL_TREAD_OLD
+#else
+#define SNDRV_TIMER_IOCTL_TREAD ((sizeof(__kernel_long_t) >= sizeof(time_t)) ? SNDRV_TIMER_IOCTL_TREAD_OLD : SNDRV_TIMER_IOCTL_TREAD64)
+#endif
 struct snd_timer_read {
   unsigned int resolution;
   unsigned int ticks;
@@ -649,10 +734,12 @@
 };
 struct snd_timer_tread {
   int event;
+  __time_pad pad1;
   struct timespec tstamp;
   unsigned int val;
+  __time_pad pad2;
 };
-#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
+#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8)
 struct snd_ctl_card_info {
   int card;
   int pad;
@@ -686,7 +773,6 @@
 #define SNDRV_CTL_ELEM_ACCESS_WRITE (1 << 1)
 #define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE)
 #define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1 << 2)
-#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1 << 3)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1 << 4)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1 << 5)
 #define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
@@ -745,11 +831,7 @@
     } enumerated;
     unsigned char reserved[128];
   } value;
-  union {
-    unsigned short d[4];
-    unsigned short * d_ptr;
-  } dimen;
-  unsigned char reserved[64 - 4 * sizeof(unsigned short)];
+  unsigned char reserved[64];
 };
 struct snd_ctl_elem_value {
   struct snd_ctl_elem_id id;
@@ -773,8 +855,7 @@
     } bytes;
     struct snd_aes_iec958 iec958;
   } value;
-  struct timespec tstamp;
-  unsigned char reserved[128 - sizeof(struct timespec)];
+  unsigned char reserved[128];
 };
 struct snd_ctl_tlv {
   unsigned int numid;
diff --git a/libc/kernel/uapi/sound/compress_offload.h b/libc/kernel/uapi/sound/compress_offload.h
index 3b532ff..60688bc 100644
--- a/libc/kernel/uapi/sound/compress_offload.h
+++ b/libc/kernel/uapi/sound/compress_offload.h
@@ -21,7 +21,7 @@
 #include <linux/types.h>
 #include <sound/asound.h>
 #include <sound/compress_params.h>
-#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 1, 2)
+#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 2, 0)
 struct snd_compressed_buffer {
   __u32 fragment_size;
   __u32 fragments;
diff --git a/libc/kernel/uapi/sound/compress_params.h b/libc/kernel/uapi/sound/compress_params.h
index f49b45f..ee6c000 100644
--- a/libc/kernel/uapi/sound/compress_params.h
+++ b/libc/kernel/uapi/sound/compress_params.h
@@ -37,7 +37,9 @@
 #define SND_AUDIOCODEC_G723_1 ((__u32) 0x0000000C)
 #define SND_AUDIOCODEC_G729 ((__u32) 0x0000000D)
 #define SND_AUDIOCODEC_BESPOKE ((__u32) 0x0000000E)
-#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_BESPOKE
+#define SND_AUDIOCODEC_ALAC ((__u32) 0x0000000F)
+#define SND_AUDIOCODEC_APE ((__u32) 0x00000010)
+#define SND_AUDIOCODEC_MAX SND_AUDIOCODEC_APE
 #define SND_AUDIOPROFILE_PCM ((__u32) 0x00000001)
 #define SND_AUDIOCHANMODE_MP3_MONO ((__u32) 0x00000001)
 #define SND_AUDIOCHANMODE_MP3_STEREO ((__u32) 0x00000002)
@@ -81,6 +83,9 @@
 #define SND_AUDIOPROFILE_WMA8 ((__u32) 0x00000002)
 #define SND_AUDIOPROFILE_WMA9 ((__u32) 0x00000004)
 #define SND_AUDIOPROFILE_WMA10 ((__u32) 0x00000008)
+#define SND_AUDIOPROFILE_WMA9_PRO ((__u32) 0x00000010)
+#define SND_AUDIOPROFILE_WMA9_LOSSLESS ((__u32) 0x00000020)
+#define SND_AUDIOPROFILE_WMA10_LOSSLESS ((__u32) 0x00000040)
 #define SND_AUDIOMODE_WMA_LEVEL1 ((__u32) 0x00000001)
 #define SND_AUDIOMODE_WMA_LEVEL2 ((__u32) 0x00000002)
 #define SND_AUDIOMODE_WMA_LEVEL3 ((__u32) 0x00000004)
@@ -171,6 +176,30 @@
   __u16 max_frame_size;
   __u16 reserved;
 } __attribute__((packed, aligned(4)));
+struct snd_dec_wma {
+  __u32 encoder_option;
+  __u32 adv_encoder_option;
+  __u32 adv_encoder_option2;
+  __u32 reserved;
+} __attribute__((packed, aligned(4)));
+struct snd_dec_alac {
+  __u32 frame_length;
+  __u8 compatible_version;
+  __u8 pb;
+  __u8 mb;
+  __u8 kb;
+  __u32 max_run;
+  __u32 max_frame_bytes;
+} __attribute__((packed, aligned(4)));
+struct snd_dec_ape {
+  __u16 compatible_version;
+  __u16 compression_level;
+  __u32 format_flags;
+  __u32 blocks_per_frame;
+  __u32 final_frame_blocks;
+  __u32 total_frames;
+  __u32 seek_table_present;
+} __attribute__((packed, aligned(4)));
 union snd_codec_options {
   struct snd_enc_wma wma;
   struct snd_enc_vorbis vorbis;
@@ -178,6 +207,9 @@
   struct snd_enc_flac flac;
   struct snd_enc_generic generic;
   struct snd_dec_flac flac_d;
+  struct snd_dec_wma wma_d;
+  struct snd_dec_alac alac_d;
+  struct snd_dec_ape ape_d;
 } __attribute__((packed, aligned(4)));
 struct snd_codec_desc {
   __u32 max_ch;
diff --git a/libc/kernel/uapi/sound/emu10k1.h b/libc/kernel/uapi/sound/emu10k1.h
index 4ad0002..483309e 100644
--- a/libc/kernel/uapi/sound/emu10k1.h
+++ b/libc/kernel/uapi/sound/emu10k1.h
@@ -18,8 +18,9 @@
  ****************************************************************************/
 #ifndef _UAPI__SOUND_EMU10K1_H
 #define _UAPI__SOUND_EMU10K1_H
+#ifdef __linux__
 #include <linux/types.h>
-#include <sound/asound.h>
+#endif
 #define EMU10K1_CARD_CREATIVE 0x00000000
 #define EMU10K1_CARD_EMUAPS 0x00000001
 #define EMU10K1_FX8010_PCM_COUNT 8
@@ -233,8 +234,20 @@
 #define EMU10K1_GPR_TRANSLATION_BASS 2
 #define EMU10K1_GPR_TRANSLATION_TREBLE 3
 #define EMU10K1_GPR_TRANSLATION_ONOFF 4
+enum emu10k1_ctl_elem_iface {
+  EMU10K1_CTL_ELEM_IFACE_MIXER = 2,
+  EMU10K1_CTL_ELEM_IFACE_PCM = 3,
+};
+struct emu10k1_ctl_elem_id {
+  unsigned int pad;
+  int iface;
+  unsigned int device;
+  unsigned int subdevice;
+  unsigned char name[44];
+  unsigned int index;
+};
 struct snd_emu10k1_fx8010_control_gpr {
-  struct snd_ctl_elem_id id;
+  struct emu10k1_ctl_elem_id id;
   unsigned int vcount;
   unsigned int count;
   unsigned short gpr[32];
@@ -245,7 +258,7 @@
   const unsigned int * tlv;
 };
 struct snd_emu10k1_fx8010_control_old_gpr {
-  struct snd_ctl_elem_id id;
+  struct emu10k1_ctl_elem_id id;
   unsigned int vcount;
   unsigned int count;
   unsigned short gpr[32];
@@ -257,19 +270,19 @@
 struct snd_emu10k1_fx8010_code {
   char name[128];
   __EMU10K1_DECLARE_BITMAP(gpr_valid, 0x200);
-  __u32 __user * gpr_map;
+  __u32 * gpr_map;
   unsigned int gpr_add_control_count;
-  struct snd_emu10k1_fx8010_control_gpr __user * gpr_add_controls;
+  struct snd_emu10k1_fx8010_control_gpr * gpr_add_controls;
   unsigned int gpr_del_control_count;
-  struct snd_ctl_elem_id __user * gpr_del_controls;
+  struct emu10k1_ctl_elem_id * gpr_del_controls;
   unsigned int gpr_list_control_count;
   unsigned int gpr_list_control_total;
-  struct snd_emu10k1_fx8010_control_gpr __user * gpr_list_controls;
+  struct snd_emu10k1_fx8010_control_gpr * gpr_list_controls;
   __EMU10K1_DECLARE_BITMAP(tram_valid, 0x100);
-  __u32 __user * tram_data_map;
-  __u32 __user * tram_addr_map;
+  __u32 * tram_data_map;
+  __u32 * tram_addr_map;
   __EMU10K1_DECLARE_BITMAP(code_valid, 1024);
-  __u32 __user * code;
+  __u32 * code;
 };
 struct snd_emu10k1_fx8010_tram {
   unsigned int address;
@@ -307,9 +320,4 @@
 #define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO('H', 0x82)
 #define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW('H', 0x83, int)
 #define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR('H', 0x84, int)
-typedef struct snd_emu10k1_fx8010_info emu10k1_fx8010_info_t;
-typedef struct snd_emu10k1_fx8010_control_gpr emu10k1_fx8010_control_gpr_t;
-typedef struct snd_emu10k1_fx8010_code emu10k1_fx8010_code_t;
-typedef struct snd_emu10k1_fx8010_tram emu10k1_fx8010_tram_t;
-typedef struct snd_emu10k1_fx8010_pcm_rec emu10k1_fx8010_pcm_t;
 #endif
diff --git a/libc/kernel/uapi/sound/hdsp.h b/libc/kernel/uapi/sound/hdsp.h
index 02e7f2d..2fec371 100644
--- a/libc/kernel/uapi/sound/hdsp.h
+++ b/libc/kernel/uapi/sound/hdsp.h
@@ -18,7 +18,9 @@
  ****************************************************************************/
 #ifndef __SOUND_HDSP_H
 #define __SOUND_HDSP_H
+#ifdef __linux__
 #include <linux/types.h>
+#endif
 #define HDSP_MATRIX_MIXER_SIZE 2048
 enum HDSP_IO_Type {
   Digiface,
@@ -64,7 +66,7 @@
 };
 #define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, struct hdsp_config_info)
 struct hdsp_firmware {
-  void __user * firmware_data;
+  void * firmware_data;
 };
 #define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, struct hdsp_firmware)
 struct hdsp_version {
@@ -81,11 +83,4 @@
   int aebo;
 };
 #define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, struct hdsp_9632_aeb)
-typedef enum HDSP_IO_Type HDSP_IO_Type;
-typedef struct hdsp_peak_rms hdsp_peak_rms_t;
-typedef struct hdsp_config_info hdsp_config_info_t;
-typedef struct hdsp_firmware hdsp_firmware_t;
-typedef struct hdsp_version hdsp_version_t;
-typedef struct hdsp_mixer hdsp_mixer_t;
-typedef struct hdsp_9632_aeb hdsp_9632_aeb_t;
 #endif
diff --git a/libc/kernel/uapi/sound/hdspm.h b/libc/kernel/uapi/sound/hdspm.h
index dc3192d..bd28e8c 100644
--- a/libc/kernel/uapi/sound/hdspm.h
+++ b/libc/kernel/uapi/sound/hdspm.h
@@ -18,7 +18,9 @@
  ****************************************************************************/
 #ifndef __SOUND_HDSPM_H
 #define __SOUND_HDSPM_H
+#ifdef __linux__
 #include <linux/types.h>
+#endif
 #define HDSPM_MAX_CHANNELS 64
 enum hdspm_io_type {
   MADI,
@@ -144,9 +146,4 @@
   struct hdspm_mixer * mixer;
 };
 #define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdspm_mixer_ioctl)
-typedef struct hdspm_peak_rms hdspm_peak_rms_t;
-typedef struct hdspm_config_info hdspm_config_info_t;
-typedef struct hdspm_version hdspm_version_t;
-typedef struct hdspm_channelfader snd_hdspm_channelfader_t;
-typedef struct hdspm_mixer hdspm_mixer_t;
 #endif
diff --git a/libc/kernel/uapi/sound/skl-tplg-interface.h b/libc/kernel/uapi/sound/skl-tplg-interface.h
index 58e0afa..b516a08 100644
--- a/libc/kernel/uapi/sound/skl-tplg-interface.h
+++ b/libc/kernel/uapi/sound/skl-tplg-interface.h
@@ -21,6 +21,8 @@
 #include <linux/types.h>
 #define SKL_CONTROL_TYPE_BYTE_TLV 0x100
 #define SKL_CONTROL_TYPE_MIC_SELECT 0x102
+#define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103
+#define SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC 0x104
 #define HDA_SST_CFG_MAX 900
 #define MAX_IN_QUEUE 8
 #define MAX_OUT_QUEUE 8
diff --git a/libc/kernel/uapi/sound/sof/abi.h b/libc/kernel/uapi/sound/sof/abi.h
index f19e4e9..54e9a50 100644
--- a/libc/kernel/uapi/sound/sof/abi.h
+++ b/libc/kernel/uapi/sound/sof/abi.h
@@ -19,7 +19,7 @@
 #ifndef __INCLUDE_UAPI_SOUND_SOF_ABI_H__
 #define __INCLUDE_UAPI_SOUND_SOF_ABI_H__
 #define SOF_ABI_MAJOR 3
-#define SOF_ABI_MINOR 11
+#define SOF_ABI_MINOR 16
 #define SOF_ABI_PATCH 0
 #define SOF_ABI_MAJOR_SHIFT 24
 #define SOF_ABI_MAJOR_MASK 0xff
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index 6d8561f..7d5ed89 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -37,6 +37,10 @@
 #define SOF_TKN_VOLUME_RAMP_STEP_MS 251
 #define SOF_TKN_SRC_RATE_IN 300
 #define SOF_TKN_SRC_RATE_OUT 301
+#define SOF_TKN_ASRC_RATE_IN 320
+#define SOF_TKN_ASRC_RATE_OUT 321
+#define SOF_TKN_ASRC_ASYNCHRONOUS_MODE 322
+#define SOF_TKN_ASRC_OPERATION_MODE 323
 #define SOF_TKN_PCM_DMAC_CONFIG 353
 #define SOF_TKN_COMP_PERIOD_SINK_COUNT 400
 #define SOF_TKN_COMP_PERIOD_SOURCE_COUNT 401
@@ -67,10 +71,14 @@
 #define SOF_TKN_TONE_SAMPLE_RATE 800
 #define SOF_TKN_PROCESS_TYPE 900
 #define SOF_TKN_EFFECT_TYPE SOF_TKN_PROCESS_TYPE
-#define SOF_TKN_IMX_SAI_FIRST_TOKEN 1000
+#define SOF_TKN_IMX_SAI_MCLK_ID 1000
 #define SOF_TKN_IMX_ESAI_MCLK_ID 1100
 #define SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3 1200
 #define SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3 1201
 #define SOF_TKN_MUTE_LED_USE 1300
 #define SOF_TKN_MUTE_LED_DIRECTION 1301
+#define SOF_TKN_INTEL_ALH_RATE 1400
+#define SOF_TKN_INTEL_ALH_CH 1401
+#define SOF_TKN_INTEL_HDA_RATE 1500
+#define SOF_TKN_INTEL_HDA_CH 1501
 #endif
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 4bfb8a2..a224eab 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1550,6 +1550,16 @@
     _Unwind_VRS_Set; # apex llndk arm
 } LIBC_Q;
 
+LIBC_S { # introduced=S
+  global:
+    ffsl;
+    ffsll;
+    __libc_get_static_tls_bounds;
+    __libc_register_thread_exit_callback;
+    __libc_iterate_dynamic_tls;
+    __libc_register_dynamic_tls_listeners;
+} LIBC_R;
+
 LIBC_PRIVATE {
   global:
     __accept4; # arm x86
@@ -1760,4 +1770,5 @@
     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/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index f260db7..1bfe61e 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -40,7 +40,7 @@
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include <gtest/gtest.h>
-#include <log/log.h>
+#include <log/log_read.h>
 
 #include <atomic>
 #include <string>
@@ -158,7 +158,7 @@
   log_str->clear();
 
   logger_list* list;
-  list = android_logger_list_open(log, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid);
+  list = android_logger_list_open(log, ANDROID_LOG_NONBLOCK, 1000, pid);
   ASSERT_TRUE(list != nullptr);
 
   while (true) {
diff --git a/libc/malloc_hooks/README.md b/libc/malloc_hooks/README.md
index b418e1e..1747e8d 100644
--- a/libc/malloc_hooks/README.md
+++ b/libc/malloc_hooks/README.md
@@ -74,11 +74,11 @@
 ======================
 Below is a simple implementation intercepting only malloc/calloc calls.
 
-    void* new_malloc_hook(size_t bytes, const char* arg) {
+    void* new_malloc_hook(size_t bytes, const void* arg) {
       return orig_malloc_hook(bytes, arg);
     }
 
-    void orig_malloc_hook = __malloc_hook;
+    auto orig_malloc_hook = __malloc_hook;
     __malloc_hook = new_malloc_hook;
 
 Enabling Examples
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index 28a69e6..076cff1 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -83,11 +83,15 @@
 #define __BIONIC_FALLTHROUGH
 #endif
 
-template <typename T>
-static inline T* untag_address(T* p) {
+static inline uintptr_t untag_address(uintptr_t p) {
 #if defined(__aarch64__)
-  return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(p) & ((1ULL << 56) - 1));
+  return p & ((1ULL << 56) - 1);
 #else
   return p;
 #endif
 }
+
+template <typename T>
+static inline T* untag_address(T* p) {
+  return reinterpret_cast<T*>(untag_address(reinterpret_cast<uintptr_t>(p)));
+}
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index 0ea7e3c..f9eb03f 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -116,6 +116,8 @@
   M_HEAP_TAGGING_LEVEL_TBI = 1,
   // Enable heap tagging if supported, at a level appropriate for asynchronous memory tag checks.
   M_HEAP_TAGGING_LEVEL_ASYNC = 2,
+  // Enable heap tagging if supported, at a level appropriate for synchronous memory tag checks.
+  M_HEAP_TAGGING_LEVEL_SYNC = 3,
 };
 
 // Manipulates bionic-specific handling of memory allocation APIs such as
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index fbf3895..1e393eb 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -31,16 +31,14 @@
 #include <sys/auxv.h>
 #include <bionic/mte_kernel.h>
 
-#ifdef __aarch64__
 inline bool mte_supported() {
-#ifdef ANDROID_EXPERIMENTAL_MTE
+#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
   static bool supported = getauxval(AT_HWCAP2) & HWCAP2_MTE;
 #else
   static bool supported = false;
 #endif
   return supported;
 }
-#endif
 
 #ifdef __aarch64__
 class ScopedDisableMTE {
diff --git a/libc/platform/bionic/mte_kernel.h b/libc/platform/bionic/mte_kernel.h
index 2c777c9..e8ef2a5 100644
--- a/libc/platform/bionic/mte_kernel.h
+++ b/libc/platform/bionic/mte_kernel.h
@@ -37,7 +37,7 @@
 
 #ifdef ANDROID_EXPERIMENTAL_MTE
 
-#define HWCAP2_MTE (1 << 10)
+#define HWCAP2_MTE (1 << 18)
 #define PROT_MTE 0x20
 
 #define PR_MTE_TCF_SHIFT 1
@@ -45,10 +45,13 @@
 #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_EXCL_SHIFT 3
-#define PR_MTE_EXCL_MASK (0xffffUL << PR_MTE_EXCL_SHIFT)
+#define PR_MTE_TAG_SHIFT 3
+#define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
 
-#define SEGV_MTEAERR 6
-#define SEGV_MTESERR 7
+#define SEGV_MTEAERR 8
+#define SEGV_MTESERR 9
+
+#define PTRACE_PEEKMTETAGS 33
+#define PTRACE_POKEMTETAGS 34
 
 #endif
diff --git a/libc/arch-arm64/mte/bionic/strlen.c b/libc/platform/scudo_platform_tls_slot.h
similarity index 85%
copy from libc/arch-arm64/mte/bionic/strlen.c
copy to libc/platform/scudo_platform_tls_slot.h
index de88320..9d017c0 100644
--- a/libc/arch-arm64/mte/bionic/strlen.c
+++ b/libc/platform/scudo_platform_tls_slot.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,10 @@
  * SUCH DAMAGE.
  */
 
-#include <upstream-openbsd/android/include/openbsd-compat.h>
+#pragma once
 
-#define strlen strlen_mte
-#include <upstream-openbsd/lib/libc/string/strlen.c>
+#include "bionic/tls.h"
+
+inline uintptr_t *getPlatformAllocatorTlsSlot() {
+  return reinterpret_cast<uintptr_t*>(&__get_tls()[TLS_SLOT_SANITIZER]);
+}
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
index 8f5b32d..746f72a 100644
--- a/libc/private/WriteProtected.h
+++ b/libc/private/WriteProtected.h
@@ -40,23 +40,11 @@
 // explicitly.
 template <typename T>
 class WriteProtected {
+ public:
   static_assert(sizeof(T) < PAGE_SIZE,
                 "WriteProtected only supports contents up to PAGE_SIZE");
   static_assert(__is_pod(T), "WriteProtected only supports POD contents");
 
-  WriteProtectedContents<T> contents;
-
-  int set_protection(int prot) {
-    auto addr = &contents;
-#if __has_feature(hwaddress_sanitizer)
-    // The mprotect system call does not currently untag pointers, so do it
-    // ourselves.
-    addr = untag_address(addr);
-#endif
-    return mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot);
-  }
-
- public:
   WriteProtected() = default;
   BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
 
@@ -64,10 +52,7 @@
     // Not strictly necessary, but this will hopefully segfault if we initialize
     // multiple times by accident.
     memset(&contents, 0, sizeof(contents));
-
-    if (set_protection(PROT_READ)) {
-      async_safe_fatal("failed to make WriteProtected nonwritable in initialize");
-    }
+    set_protection(PROT_READ);
   }
 
   const T* operator->() {
@@ -80,14 +65,23 @@
 
   template <typename Mutator>
   void mutate(Mutator mutator) {
-    if (set_protection(PROT_READ | PROT_WRITE) != 0) {
-      async_safe_fatal("failed to make WriteProtected writable in mutate: %s",
-                       strerror(errno));
-    }
+    set_protection(PROT_READ | PROT_WRITE);
     mutator(&contents.value);
-    if (set_protection(PROT_READ) != 0) {
-      async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s",
-                       strerror(errno));
+    set_protection(PROT_READ);
+  }
+
+ private:
+  WriteProtectedContents<T> contents;
+
+  void set_protection(int prot) {
+    auto addr = &contents;
+#if __has_feature(hwaddress_sanitizer)
+    // The mprotect system call does not currently untag pointers, so do it
+    // ourselves.
+    addr = untag_address(addr);
+#endif
+    if (mprotect(reinterpret_cast<void*>(addr), PAGE_SIZE, prot) == -1) {
+      async_safe_fatal("WriteProtected mprotect %x failed: %s", prot, strerror(errno));
     }
   }
 };
diff --git a/libc/private/bionic_allocator.h b/libc/private/bionic_allocator.h
index c705ce4..342fd51 100644
--- a/libc/private/bionic_allocator.h
+++ b/libc/private/bionic_allocator.h
@@ -110,6 +110,11 @@
   // Note that this implementation of realloc never shrinks allocation
   void* realloc(void* ptr, size_t size);
   void free(void* ptr);
+
+  // Returns the size of the given allocated heap chunk, if it is valid.
+  // Otherwise, this may return 0 or cause a segfault if the pointer is invalid.
+  size_t get_chunk_size(void* ptr);
+
  private:
   void* alloc_mmap(size_t align, size_t size);
   inline void* alloc_impl(size_t align, size_t size);
diff --git a/libc/private/bionic_auxv.h b/libc/private/bionic_auxv.h
index 8e33c1c..9d2cfdd 100644
--- a/libc/private/bionic_auxv.h
+++ b/libc/private/bionic_auxv.h
@@ -30,4 +30,4 @@
 
 #include <sys/cdefs.h>
 
-__LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool& exists);
+__LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool* exists);
diff --git a/libc/private/bionic_elf_tls.h b/libc/private/bionic_elf_tls.h
index fa1af76..e0ec7b5 100644
--- a/libc/private/bionic_elf_tls.h
+++ b/libc/private/bionic_elf_tls.h
@@ -111,6 +111,18 @@
   void* soinfo_ptr = nullptr;
 };
 
+// Signature of the callbacks that will be called after DTLS creation and
+// before DTLS destruction.
+typedef void (*dtls_listener_t)(void* dynamic_tls_begin, void* dynamic_tls_end);
+
+// Signature of the thread-exit callbacks.
+typedef void (*thread_exit_cb_t)(void);
+
+struct CallbackHolder {
+  thread_exit_cb_t cb;
+  CallbackHolder* prev;
+};
+
 // Table of the ELF TLS modules. Either the dynamic linker or the static
 // initialization code prepares this table, and it's then used during thread
 // creation and for dynamic TLS lookups.
@@ -128,7 +140,20 @@
   // Pointer to a block of TlsModule objects. The first module has ID 1 and
   // is stored at index 0 in this table.
   size_t module_count = 0;
+  size_t static_module_count = 0;
   TlsModule* module_table = nullptr;
+
+  // Callback to be invoked after a dynamic TLS allocation.
+  dtls_listener_t on_creation_cb = nullptr;
+
+  // Callback to be invoked before a dynamic TLS deallocation.
+  dtls_listener_t on_destruction_cb = nullptr;
+
+  // The first thread-exit callback; inlined to avoid allocation.
+  thread_exit_cb_t first_thread_exit_callback = nullptr;
+
+  // The additional callbacks, if any.
+  CallbackHolder* thread_exit_callback_tail_node = nullptr;
 };
 
 void __init_static_tls(void* static_tls);
@@ -175,3 +200,4 @@
 
 struct bionic_tcb;
 void __free_dynamic_tls(bionic_tcb* tcb);
+void __notify_thread_exit_callbacks();
diff --git a/libc/private/bionic_fortify.h b/libc/private/bionic_fortify.h
index 3c3292e..df83360 100644
--- a/libc/private/bionic_fortify.h
+++ b/libc/private/bionic_fortify.h
@@ -35,7 +35,11 @@
 
 #include <async_safe/log.h>
 
-static inline __noreturn void __fortify_fatal(const char* fmt, ...) {
+//
+// LLVM can't inline variadic functions, and we don't want one definition of
+// this per #include in libc.so, so no `static`.
+//
+inline __noreturn __printflike(1, 2) void __fortify_fatal(const char* fmt, ...) {
   va_list args;
   va_start(args, fmt);
   async_safe_fatal_va_list("FORTIFY", fmt, args);
@@ -52,7 +56,7 @@
     __fortify_fatal("%s: file descriptor %d < 0", fn, fd);
   }
   if (__predict_false(fd >= FD_SETSIZE)) {
-    __fortify_fatal("%s: file descriptor %d >= FD_SETSIZE %zu", fn, fd, FD_SETSIZE);
+    __fortify_fatal("%s: file descriptor %d >= FD_SETSIZE %d", fn, fd, FD_SETSIZE);
   }
   if (__predict_false(set_size < sizeof(fd_set))) {
     __fortify_fatal("%s: set size %zu is too small to be an fd_set", fn, set_size);
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 6e7eb76..5c9b726 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -101,8 +101,11 @@
   const char* init_progname = nullptr;
   char** init_environ = nullptr;
 
-  const gwp_asan::AllocatorState *gwp_asan_state = nullptr;
-  const gwp_asan::AllocationMetadata *gwp_asan_metadata = nullptr;
+  const gwp_asan::AllocatorState* gwp_asan_state = nullptr;
+  const gwp_asan::AllocationMetadata* gwp_asan_metadata = nullptr;
+
+  const char* scudo_stack_depot = nullptr;
+  const char* scudo_region_info = nullptr;
 };
 
 __LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
diff --git a/libc/private/bionic_ifuncs.h b/libc/private/bionic_ifuncs.h
index f175bec..e6b349a 100644
--- a/libc/private/bionic_ifuncs.h
+++ b/libc/private/bionic_ifuncs.h
@@ -40,9 +40,12 @@
 #define IFUNC_ARGS ()
 #endif
 
+// We can't have HWASAN enabled in resolvers because they may be called before HWASAN is
+// initialized.
 #define DEFINE_IFUNC_FOR(name) \
     name##_func name __attribute__((ifunc(#name "_resolver"))); \
     __attribute__((visibility("hidden"))) \
+    __attribute__((no_sanitize("hwaddress"))) \
     name##_func* name##_resolver IFUNC_ARGS
 
 #define DECLARE_FUNC(type, name) \
diff --git a/libc/private/bionic_string_utils.h b/libc/private/bionic_string_utils.h
deleted file mode 100644
index ab0eccf..0000000
--- a/libc/private/bionic_string_utils.h
+++ /dev/null
@@ -1,31 +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.
- */
-
-#ifndef _BIONIC_STRING_UTILS_H_
-#define _BIONIC_STRING_UTILS_H_
-
-#include <string.h>
-
-static inline bool ends_with(const char* s1, const char* s2) {
-  size_t s1_length = strlen(s1);
-  size_t s2_length = strlen(s2);
-  if (s2_length > s1_length) {
-    return false;
-  }
-  return memcmp(s1 + (s1_length - s2_length), s2, s2_length) == 0;
-}
-
-#endif // _BIONIC_STRING_UTILS_H_
diff --git a/libc/private/bionic_systrace.h b/libc/private/bionic_systrace.h
index dbe1739..6b11812 100644
--- a/libc/private/bionic_systrace.h
+++ b/libc/private/bionic_systrace.h
@@ -16,8 +16,12 @@
 
 #pragma once
 
+#include <cutils/trace.h>  // For ATRACE_TAG_BIONIC.
+
 #include "platform/bionic/macros.h"
 
+static constexpr char kTraceTagsProp[] = "debug.atrace.tags.enableflags";
+
 // Tracing class for bionic. To begin a trace at a specified point:
 //   ScopedTrace("Trace message");
 // The trace will end when the contructor goes out of scope.
@@ -33,5 +37,9 @@
   BIONIC_DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
 };
 
+int get_trace_marker_fd();
+bool should_trace(const uint64_t enable_tags = ATRACE_TAG_BIONIC);
+void output_trace(const char* message, const char event = 'B');
+
 void bionic_trace_begin(const char* message);
 void bionic_trace_end();
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index 65357fc..a42816e 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -140,12 +140,12 @@
     Disallow(f);
 }
 
-// This filter is meant to be installed in addition to a regular whitelist filter.
+// This filter is meant to be installed in addition to a regular allowlist filter.
 // Therefore, it's default action has to be Allow, except when the evaluated
 // system call matches setresuid/setresgid and the arguments don't fall within the
 // passed in range.
 //
-// The regular whitelist only allows setresuid/setresgid for UID/GID changes, so
+// The regular allowlist only allows setresuid/setresgid for UID/GID changes, so
 // that's the only system call we need to check here. A CTS test ensures the other
 // calls will remain blocked.
 static void ValidateSetUidGid(filter& f, uint32_t uid_gid_min, uint32_t uid_gid_max, bool primary) {
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 1ecf122..6ffda49 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -259,8 +259,8 @@
 size_t parsefloat(FILE*, char*, char*);
 size_t wparsefloat(FILE*, wchar_t*, wchar_t*);
 
-// Sanity check a FILE* for nullptr, so we can emit a message while crashing
-// instead of doing a blind null-dereference.
+// Check a FILE* isn't nullptr, so we can emit a clear diagnostic message
+// instead of just crashing with SIGSEGV.
 #define CHECK_FP(fp) \
   if (fp == nullptr) __fortify_fatal("%s: null FILE*", __FUNCTION__)
 
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index a0b4219..b8aced8 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -773,10 +773,7 @@
 // Returns first argument, or nullptr if no characters were read.
 // Does not return nullptr if n == 1.
 char* fgets_unlocked(char* buf, int n, FILE* fp) {
-  if (n <= 0) {
-    errno = EINVAL;
-    return nullptr;
-  }
+  if (n <= 0) __fortify_fatal("fgets: buffer size %d <= 0", n);
 
   _SET_ORIENTATION(fp, -1);
 
@@ -1026,9 +1023,9 @@
   __check_count("vsnprintf", "size", n);
 
   // Stdio internals do not deal correctly with zero length buffer.
-  char dummy;
+  char one_byte_buffer[1];
   if (n == 0) {
-    s = &dummy;
+    s = one_byte_buffer;
     n = 1;
   }
 
diff --git a/libc/stdlib/exit.c b/libc/stdlib/exit.c
deleted file mode 100644
index e301a2a..0000000
--- a/libc/stdlib/exit.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <unistd.h>
-
-#include "private/bionic_defs.h"
-
-extern void __cxa_finalize(void* dso_handle);
-extern void __cxa_thread_finalize();
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-void exit(int status) {
-  __cxa_thread_finalize();
-  __cxa_finalize(NULL);
-  _exit(status);
-}
diff --git a/libc/system_properties/Android.bp b/libc/system_properties/Android.bp
index 8780dda..3846169 100644
--- a/libc/system_properties/Android.bp
+++ b/libc/system_properties/Android.bp
@@ -8,9 +8,11 @@
         "contexts_serialized.cpp",
         "prop_area.cpp",
         "prop_info.cpp",
+        "prop_trace.cpp",
         "system_properties.cpp",
     ],
     whole_static_libs: [
+        "libc_bionic_systrace",
         "libpropertyinfoparser",
     ],
     header_libs: [
@@ -23,3 +25,20 @@
     ],
     export_include_dirs: ["include"],
 }
+
+cc_benchmark {
+    name: "property_context_lookup_benchmark",
+    srcs: [
+        "context_lookup_benchmark.cpp",
+    ],
+    include_dirs: [
+        "bionic/libc",
+    ],
+
+    shared_libs: ["libbase"],
+    static_libs: [
+        "libpropertyinfoserializer",
+        "libsystemproperties",
+        "libasync_safe",
+    ],
+}
diff --git a/libc/system_properties/context_lookup_benchmark.cpp b/libc/system_properties/context_lookup_benchmark.cpp
new file mode 100644
index 0000000..1564250
--- /dev/null
+++ b/libc/system_properties/context_lookup_benchmark.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2020 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 <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <benchmark/benchmark.h>
+#include <property_info_parser/property_info_parser.h>
+#include <property_info_serializer/property_info_serializer.h>
+#include <system_properties/contexts_split.h>
+
+#include "context_lookup_benchmark_data.h"
+
+using android::base::Split;
+using android::base::WriteStringToFd;
+using android::properties::BuildTrie;
+using android::properties::ParsePropertyInfoFile;
+using android::properties::PropertyInfoArea;
+using android::properties::PropertyInfoEntry;
+
+BENCHMARK_MAIN();
+
+class LegacyPropertyMapping : public ContextsSplit {
+ public:
+  LegacyPropertyMapping(const char* property_contexts) {
+    TemporaryFile file;
+    if (!WriteStringToFd(property_contexts, file.fd)) {
+      PLOG(FATAL) << "Could not write to temporary file";
+    }
+
+    if (!InitializePropertiesFromFile(file.path)) {
+      LOG(FATAL) << "Could not initialize properties";
+    }
+  }
+};
+
+static std::vector<std::string> PropertiesToLookup() {
+  std::vector<std::string> properties;
+  auto property_lines = Split(aosp_s_property_contexts, "\n");
+  for (const auto& line : property_lines) {
+    if (line.empty() || line[0] == '#') {
+      continue;
+    }
+
+    auto property = Split(line, " ")[0];
+    properties.push_back(property);
+    properties.push_back(property + "0");
+    properties.push_back(property + "A");
+  }
+  return properties;
+}
+
+static void LegacyLookupOreo(benchmark::State& state) {
+  LegacyPropertyMapping mapping(oreo_property_contexts);
+  auto properties = PropertiesToLookup();
+  for (auto _ : state) {
+    for (const auto& property : properties) {
+      benchmark::DoNotOptimize(mapping.GetPrefixNodeForName(property.c_str()));
+    }
+  }
+}
+BENCHMARK(LegacyLookupOreo);
+
+static void LegacyLookupS(benchmark::State& state) {
+  LegacyPropertyMapping mapping(aosp_s_property_contexts);
+  auto properties = PropertiesToLookup();
+  for (auto _ : state) {
+    for (const auto& property : properties) {
+      benchmark::DoNotOptimize(mapping.GetPrefixNodeForName(property.c_str()));
+    }
+  }
+}
+BENCHMARK(LegacyLookupS);
+
+static std::string CreateSerializedTrie(const char* input_file) {
+  std::vector<std::string> errors;
+  std::vector<PropertyInfoEntry> property_infos;
+  ParsePropertyInfoFile(input_file, false, &property_infos, &errors);
+
+  std::string serialized_trie;
+  std::string error;
+  if (!BuildTrie(property_infos, "u:object_r:default_prop:s0", "string", &serialized_trie,
+                 &error)) {
+    LOG(FATAL) << "Could not build trie: " << error;
+  }
+  return serialized_trie;
+}
+
+static void TrieLookupOreo(benchmark::State& state) {
+  std::string serialized_trie = CreateSerializedTrie(oreo_property_contexts);
+  PropertyInfoArea* trie = reinterpret_cast<PropertyInfoArea*>(serialized_trie.data());
+  auto properties = PropertiesToLookup();
+  for (auto _ : state) {
+    for (const auto& property : properties) {
+      trie->GetPropertyInfo(property.c_str(), nullptr, nullptr);
+    }
+  }
+}
+BENCHMARK(TrieLookupOreo);
+
+static void TrieLookupS(benchmark::State& state) {
+  std::string serialized_trie = CreateSerializedTrie(aosp_s_property_contexts);
+  PropertyInfoArea* trie = reinterpret_cast<PropertyInfoArea*>(serialized_trie.data());
+  auto properties = PropertiesToLookup();
+  for (auto _ : state) {
+    for (const auto& property : properties) {
+      trie->GetPropertyInfo(property.c_str(), nullptr, nullptr);
+    }
+  }
+}
+BENCHMARK(TrieLookupS);
diff --git a/libc/system_properties/context_lookup_benchmark_data.h b/libc/system_properties/context_lookup_benchmark_data.h
new file mode 100644
index 0000000..3cc3257
--- /dev/null
+++ b/libc/system_properties/context_lookup_benchmark_data.h
@@ -0,0 +1,1012 @@
+/*
+ * Copyright (C) 2020 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
+
+static char oreo_property_contexts[] = R"(
+net.rmnet               u:object_r:net_radio_prop:s0
+net.gprs                u:object_r:net_radio_prop:s0
+net.ppp                 u:object_r:net_radio_prop:s0
+net.qmi                 u:object_r:net_radio_prop:s0
+net.lte                 u:object_r:net_radio_prop:s0
+net.cdma                u:object_r:net_radio_prop:s0
+net.dns                 u:object_r:net_dns_prop:s0
+sys.usb.config          u:object_r:system_radio_prop:s0
+ril.                    u:object_r:radio_prop:s0
+ro.ril.                 u:object_r:radio_prop:s0
+gsm.                    u:object_r:radio_prop:s0
+persist.radio           u:object_r:radio_prop:s0
+net.                    u:object_r:system_prop:s0
+dev.                    u:object_r:system_prop:s0
+ro.runtime.             u:object_r:system_prop:s0
+ro.runtime.firstboot    u:object_r:firstboot_prop:s0
+hw.                     u:object_r:system_prop:s0
+ro.hw.                  u:object_r:system_prop:s0
+sys.                    u:object_r:system_prop:s0
+sys.cppreopt            u:object_r:cppreopt_prop:s0
+sys.powerctl            u:object_r:powerctl_prop:s0
+sys.usb.ffs.            u:object_r:ffs_prop:s0
+service.                u:object_r:system_prop:s0
+dhcp.                   u:object_r:dhcp_prop:s0
+dhcp.bt-pan.result      u:object_r:pan_result_prop:s0
+bluetooth.              u:object_r:bluetooth_prop:s0
+debug.                  u:object_r:debug_prop:s0
+debug.db.               u:object_r:debuggerd_prop:s0
+dumpstate.              u:object_r:dumpstate_prop:s0
+dumpstate.options       u:object_r:dumpstate_options_prop:s0
+log.                    u:object_r:log_prop:s0
+log.tag                 u:object_r:log_tag_prop:s0
+log.tag.WifiHAL         u:object_r:wifi_log_prop:s0
+security.perf_harden    u:object_r:shell_prop:s0
+service.adb.root        u:object_r:shell_prop:s0
+service.adb.tcp.port    u:object_r:shell_prop:s0
+persist.audio.          u:object_r:audio_prop:s0
+persist.bluetooth.      u:object_r:bluetooth_prop:s0
+persist.debug.          u:object_r:persist_debug_prop:s0
+persist.logd.           u:object_r:logd_prop:s0
+persist.logd.security   u:object_r:device_logging_prop:s0
+persist.logd.logpersistd        u:object_r:logpersistd_logging_prop:s0
+logd.logpersistd        u:object_r:logpersistd_logging_prop:s0
+persist.log.tag         u:object_r:log_tag_prop:s0
+persist.mmc.            u:object_r:mmc_prop:s0
+persist.sys.            u:object_r:system_prop:s0
+persist.sys.safemode    u:object_r:safemode_prop:s0
+ro.sys.safemode         u:object_r:safemode_prop:s0
+persist.sys.audit_safemode      u:object_r:safemode_prop:s0
+persist.service.        u:object_r:system_prop:s0
+persist.service.bdroid. u:object_r:bluetooth_prop:s0
+persist.security.       u:object_r:system_prop:s0
+persist.vendor.overlay.  u:object_r:overlay_prop:s0
+ro.boot.vendor.overlay.  u:object_r:overlay_prop:s0
+ro.boottime.             u:object_r:boottime_prop:s0
+ro.serialno             u:object_r:serialno_prop:s0
+ro.boot.btmacaddr       u:object_r:bluetooth_prop:s0
+ro.boot.serialno        u:object_r:serialno_prop:s0
+ro.bt.                  u:object_r:bluetooth_prop:s0
+# Boolean property set by system server upon boot indicating
+# if device owner is provisioned.
+ro.device_owner         u:object_r:device_logging_prop:s0
+# selinux non-persistent properties
+selinux.restorecon_recursive   u:object_r:restorecon_prop:s0
+# default property context
+*                       u:object_r:default_prop:s0
+# data partition encryption properties
+vold.                   u:object_r:vold_prop:s0
+ro.crypto.              u:object_r:vold_prop:s0
+# ro.build.fingerprint is either set in /system/build.prop, or is
+# set at runtime by system_server.
+ro.build.fingerprint    u:object_r:fingerprint_prop:s0
+ro.persistent_properties.ready  u:object_r:persistent_properties_ready_prop:s0
+# ctl properties
+ctl.bootanim            u:object_r:ctl_bootanim_prop:s0
+ctl.dumpstate           u:object_r:ctl_dumpstate_prop:s0
+ctl.fuse_               u:object_r:ctl_fuse_prop:s0
+ctl.mdnsd               u:object_r:ctl_mdnsd_prop:s0
+ctl.ril-daemon          u:object_r:ctl_rildaemon_prop:s0
+ctl.bugreport           u:object_r:ctl_bugreport_prop:s0
+ctl.console             u:object_r:ctl_console_prop:s0
+ctl.                    u:object_r:ctl_default_prop:s0
+# NFC properties
+nfc.                    u:object_r:nfc_prop:s0
+# These properties are not normally set by processes other than init.
+# They are only distinguished here for setting by qemu-props on the
+# emulator/goldfish.
+config.                 u:object_r:config_prop:s0
+ro.config.              u:object_r:config_prop:s0
+dalvik.                 u:object_r:dalvik_prop:s0
+ro.dalvik.              u:object_r:dalvik_prop:s0
+# Shared between system server and wificond
+wlan.                   u:object_r:wifi_prop:s0
+# hwservicemanager properties
+hwservicemanager.       u:object_r:hwservicemanager_prop:s0
+# ASAN install trigger
+asan.restore_reboot  u:object_r:asan_reboot_prop:s0)";
+
+static char aosp_s_property_contexts[] = R"(
+net.rmnet               u:object_r:net_radio_prop:s0
+net.gprs                u:object_r:net_radio_prop:s0
+net.ppp                 u:object_r:net_radio_prop:s0
+net.qmi                 u:object_r:net_radio_prop:s0
+net.lte                 u:object_r:net_radio_prop:s0
+net.cdma                u:object_r:net_radio_prop:s0
+net.dns                 u:object_r:net_dns_prop:s0
+ril.                    u:object_r:radio_prop:s0
+ro.ril.                 u:object_r:radio_prop:s0
+gsm.                    u:object_r:radio_prop:s0
+persist.radio           u:object_r:radio_prop:s0
+
+net.                    u:object_r:system_prop:s0
+dev.                    u:object_r:system_prop:s0
+ro.runtime.             u:object_r:system_prop:s0
+ro.runtime.firstboot    u:object_r:firstboot_prop:s0
+hw.                     u:object_r:system_prop:s0
+ro.hw.                  u:object_r:system_prop:s0
+sys.                    u:object_r:system_prop:s0
+sys.audio.              u:object_r:audio_prop:s0
+sys.init.perf_lsm_hooks u:object_r:init_perf_lsm_hooks_prop:s0
+sys.cppreopt            u:object_r:cppreopt_prop:s0
+sys.lpdumpd             u:object_r:lpdumpd_prop:s0
+sys.powerctl            u:object_r:powerctl_prop:s0
+service.                u:object_r:system_prop:s0
+dhcp.                   u:object_r:dhcp_prop:s0
+dhcp.bt-pan.result      u:object_r:pan_result_prop:s0
+bluetooth.              u:object_r:bluetooth_prop:s0
+
+debug.                  u:object_r:debug_prop:s0
+debug.db.               u:object_r:debuggerd_prop:s0
+dumpstate.              u:object_r:dumpstate_prop:s0
+dumpstate.options       u:object_r:dumpstate_options_prop:s0
+init.svc_debug_pid.     u:object_r:init_svc_debug_prop:s0
+llk.                    u:object_r:llkd_prop:s0
+khungtask.              u:object_r:llkd_prop:s0
+ro.llk.                 u:object_r:llkd_prop:s0
+ro.khungtask.           u:object_r:llkd_prop:s0
+log.                    u:object_r:log_prop:s0
+log.tag                 u:object_r:log_tag_prop:s0
+log.tag.WifiHAL         u:object_r:wifi_log_prop:s0
+security.perf_harden    u:object_r:shell_prop:s0
+service.adb.root        u:object_r:shell_prop:s0
+service.adb.tls.port    u:object_r:adbd_prop:s0
+persist.adb.wifi.       u:object_r:adbd_prop:s0
+persist.adb.tls_server.enable  u:object_r:system_adbd_prop:s0
+
+persist.audio.          u:object_r:audio_prop:s0
+persist.bluetooth.      u:object_r:bluetooth_prop:s0
+persist.nfc_cfg.        u:object_r:nfc_prop:s0
+persist.debug.          u:object_r:persist_debug_prop:s0
+logd.                   u:object_r:logd_prop:s0
+persist.logd.           u:object_r:logd_prop:s0
+ro.logd.                u:object_r:logd_prop:s0
+persist.logd.security   u:object_r:device_logging_prop:s0
+persist.logd.logpersistd        u:object_r:logpersistd_logging_prop:s0
+logd.logpersistd        u:object_r:logpersistd_logging_prop:s0
+persist.log.tag         u:object_r:log_tag_prop:s0
+persist.mmc.            u:object_r:mmc_prop:s0
+persist.netd.stable_secret      u:object_r:netd_stable_secret_prop:s0
+persist.pm.mock-upgrade u:object_r:mock_ota_prop:s0
+persist.sys.            u:object_r:system_prop:s0
+persist.sys.safemode    u:object_r:safemode_prop:s0
+persist.sys.theme       u:object_r:theme_prop:s0
+persist.sys.fflag.override.settings_dynamic_system    u:object_r:dynamic_system_prop:s0
+ro.sys.safemode         u:object_r:safemode_prop:s0
+persist.sys.audit_safemode      u:object_r:safemode_prop:s0
+persist.sys.dalvik.jvmtiagent   u:object_r:system_jvmti_agent_prop:s0
+persist.service.        u:object_r:system_prop:s0
+persist.service.bdroid. u:object_r:bluetooth_prop:s0
+persist.security.       u:object_r:system_prop:s0
+persist.traced.enable   u:object_r:traced_enabled_prop:s0
+traced.lazy.            u:object_r:traced_lazy_prop:s0
+persist.heapprofd.enable u:object_r:heapprofd_enabled_prop:s0
+persist.traced_perf.enable u:object_r:traced_perf_enabled_prop:s0
+persist.vendor.overlay.  u:object_r:overlay_prop:s0
+ro.boot.vendor.overlay.  u:object_r:overlay_prop:s0
+ro.boottime.             u:object_r:boottime_prop:s0
+ro.serialno             u:object_r:serialno_prop:s0
+ro.boot.btmacaddr       u:object_r:bluetooth_prop:s0
+ro.boot.serialno        u:object_r:serialno_prop:s0
+ro.bt.                  u:object_r:bluetooth_prop:s0
+ro.boot.bootreason      u:object_r:bootloader_boot_reason_prop:s0
+persist.sys.boot.reason u:object_r:last_boot_reason_prop:s0
+sys.boot.reason         u:object_r:system_boot_reason_prop:s0
+sys.boot.reason.last    u:object_r:last_boot_reason_prop:s0
+pm.                     u:object_r:pm_prop:s0
+test.sys.boot.reason    u:object_r:test_boot_reason_prop:s0
+test.userspace_reboot.requested u:object_r:userspace_reboot_test_prop:s0
+sys.lmk.                u:object_r:system_lmk_prop:s0
+sys.trace.              u:object_r:system_trace_prop:s0
+
+# Fastbootd protocol control property
+fastbootd.protocol    u:object_r:fastbootd_protocol_prop:s0 exact enum usb tcp
+
+# adbd protoctl configuration property
+service.adb.tcp.port    u:object_r:adbd_config_prop:s0 exact int
+
+# Boolean property set by system server upon boot indicating
+# if device is fully owned by organization instead of being
+# a personal device.
+ro.organization_owned   u:object_r:device_logging_prop:s0
+
+# selinux non-persistent properties
+selinux.restorecon_recursive   u:object_r:restorecon_prop:s0
+
+# default property context
+*                       u:object_r:default_prop:s0
+
+# data partition encryption properties
+vold.                   u:object_r:vold_prop:s0
+ro.crypto.              u:object_r:vold_prop:s0
+
+# ro.build.fingerprint is either set in /system/build.prop, or is
+# set at runtime by system_server.
+ro.build.fingerprint    u:object_r:fingerprint_prop:s0 exact string
+
+ro.persistent_properties.ready  u:object_r:persistent_properties_ready_prop:s0
+
+# ctl properties
+ctl.bootanim            u:object_r:ctl_bootanim_prop:s0
+ctl.dumpstate           u:object_r:ctl_dumpstate_prop:s0
+ctl.fuse_               u:object_r:ctl_fuse_prop:s0
+ctl.mdnsd               u:object_r:ctl_mdnsd_prop:s0
+ctl.ril-daemon          u:object_r:ctl_rildaemon_prop:s0
+ctl.bugreport           u:object_r:ctl_bugreport_prop:s0
+ctl.console             u:object_r:ctl_console_prop:s0
+ctl.                    u:object_r:ctl_default_prop:s0
+
+# Don't allow uncontrolled access to all services
+ctl.sigstop_on$         u:object_r:ctl_sigstop_prop:s0
+ctl.sigstop_off$        u:object_r:ctl_sigstop_prop:s0
+ctl.start$              u:object_r:ctl_start_prop:s0
+ctl.stop$               u:object_r:ctl_stop_prop:s0
+ctl.restart$            u:object_r:ctl_restart_prop:s0
+ctl.interface_start$    u:object_r:ctl_interface_start_prop:s0
+ctl.interface_stop$     u:object_r:ctl_interface_stop_prop:s0
+ctl.interface_restart$  u:object_r:ctl_interface_restart_prop:s0
+
+ # Restrict access to starting/stopping adbd
+ctl.start$adbd             u:object_r:ctl_adbd_prop:s0
+ctl.stop$adbd              u:object_r:ctl_adbd_prop:s0
+ctl.restart$adbd           u:object_r:ctl_adbd_prop:s0
+
+# Restrict access to starting/stopping gsid.
+ctl.start$gsid          u:object_r:ctl_gsid_prop:s0
+ctl.stop$gsid           u:object_r:ctl_gsid_prop:s0
+ctl.restart$gsid        u:object_r:ctl_gsid_prop:s0
+
+# Restrict access to stopping apexd.
+ctl.stop$apexd          u:object_r:ctl_apexd_prop:s0
+
+# Restrict access to restart dumpstate
+ctl.interface_restart$android.hardware.dumpstate u:object_r:ctl_dumpstate_prop:s0
+
+# NFC properties
+nfc.                    u:object_r:nfc_prop:s0
+
+# These properties are not normally set by processes other than init.
+# They are only distinguished here for setting by qemu-props on the
+# emulator/goldfish.
+config.                 u:object_r:config_prop:s0
+ro.config.              u:object_r:config_prop:s0
+dalvik.                 u:object_r:dalvik_prop:s0
+ro.dalvik.              u:object_r:dalvik_prop:s0
+
+# Shared between system server and wificond
+wifi.                   u:object_r:wifi_prop:s0
+wlan.                   u:object_r:wifi_prop:s0
+
+# Lowpan properties
+lowpan.                 u:object_r:lowpan_prop:s0
+ro.lowpan.              u:object_r:lowpan_prop:s0
+
+# heapprofd properties
+heapprofd.              u:object_r:heapprofd_prop:s0
+
+# hwservicemanager properties
+hwservicemanager.       u:object_r:hwservicemanager_prop:s0
+
+# Common default properties for vendor, odm, vendor_dlkm, and odm_dlkm.
+init.svc.odm.           u:object_r:vendor_default_prop:s0
+init.svc.vendor.        u:object_r:vendor_default_prop:s0
+ro.hardware.            u:object_r:vendor_default_prop:s0
+ro.odm.                 u:object_r:vendor_default_prop:s0
+ro.vendor.              u:object_r:vendor_default_prop:s0
+ro.vendor_dlkm.         u:object_r:vendor_default_prop:s0
+ro.odm_dlkm.            u:object_r:vendor_default_prop:s0
+odm.                    u:object_r:vendor_default_prop:s0
+persist.odm.            u:object_r:vendor_default_prop:s0
+persist.vendor.         u:object_r:vendor_default_prop:s0
+vendor.                 u:object_r:vendor_default_prop:s0
+
+# Properties that relate to time / time zone detection behavior.
+persist.time.           u:object_r:time_prop:s0
+
+# Properties that relate to server configurable flags
+device_config.reset_performed           u:object_r:device_config_reset_performed_prop:s0
+persist.device_config.activity_manager_native_boot. u:object_r:device_config_activity_manager_native_boot_prop:s0
+persist.device_config.attempted_boot_count        u:object_r:device_config_boot_count_prop:s0
+persist.device_config.input_native_boot. u:object_r:device_config_input_native_boot_prop:s0
+persist.device_config.netd_native.           u:object_r:device_config_netd_native_prop:s0
+persist.device_config.runtime_native.        u:object_r:device_config_runtime_native_prop:s0
+persist.device_config.runtime_native_boot.   u:object_r:device_config_runtime_native_boot_prop:s0
+persist.device_config.media_native.          u:object_r:device_config_media_native_prop:s0
+persist.device_config.storage_native_boot.   u:object_r:device_config_storage_native_boot_prop:s0
+persist.device_config.window_manager_native_boot. u:object_r:device_config_window_manager_native_boot_prop:s0
+persist.device_config.configuration. u:object_r:device_config_configuration_prop:s0
+
+# Properties that relate to legacy server configurable flags
+persist.device_config.global_settings.sys_traced u:object_r:device_config_sys_traced_prop:s0
+
+apexd.                  u:object_r:apexd_prop:s0
+persist.apexd.          u:object_r:apexd_prop:s0
+
+bpf.progs_loaded        u:object_r:bpf_progs_loaded_prop:s0
+
+gsid.                   u:object_r:gsid_prop:s0
+ro.gsid.                u:object_r:gsid_prop:s0
+
+# Property for disabling NNAPI vendor extensions on product image (used on GSI /product image,
+# which can't use NNAPI vendor extensions).
+ro.nnapi.extensions.deny_on_product                u:object_r:nnapi_ext_deny_product_prop:s0
+
+# Property that is set once ueventd finishes cold boot.
+ro.cold_boot_done       u:object_r:cold_boot_done_prop:s0
+
+# Charger properties
+ro.charger.                 u:object_r:charger_prop:s0
+sys.boot_from_charger_mode  u:object_r:charger_status_prop:s0 exact int
+ro.enable_boot_charger_mode u:object_r:charger_config_prop:s0 exact bool
+
+# Virtual A/B properties
+ro.virtual_ab.enabled   u:object_r:virtual_ab_prop:s0
+ro.virtual_ab.retrofit  u:object_r:virtual_ab_prop:s0
+
+ro.product.ab_ota_partitions u:object_r:ota_prop:s0 exact string
+# Property to set/clear the warm reset flag after an OTA update.
+ota.warm_reset  u:object_r:ota_prop:s0
+
+# Module properties
+com.android.sdkext.                  u:object_r:module_sdkextensions_prop:s0
+persist.com.android.sdkext.          u:object_r:module_sdkextensions_prop:s0
+
+# Userspace reboot properties
+sys.userspace_reboot.log.         u:object_r:userspace_reboot_log_prop:s0
+persist.sys.userspace_reboot.log. u:object_r:userspace_reboot_log_prop:s0
+
+# Integer property which is used in libgui to configure the number of frames
+# tracked by buffer queue's frame event timing history. The property is set
+# by devices with video decoding pipelines long enough to overflow the default
+# history size.
+ro.lib_gui.frame_event_history_size u:object_r:bq_config_prop:s0
+
+af.fast_track_multiplier     u:object_r:audio_config_prop:s0 exact int
+ro.af.client_heap_size_kbyte u:object_r:audio_config_prop:s0 exact int
+
+audio.camerasound.force         u:object_r:audio_config_prop:s0 exact bool
+audio.deep_buffer.media         u:object_r:audio_config_prop:s0 exact bool
+audio.offload.video             u:object_r:audio_config_prop:s0 exact bool
+audio.offload.min.duration.secs u:object_r:audio_config_prop:s0 exact int
+
+ro.audio.ignore_effects  u:object_r:audio_config_prop:s0 exact bool
+ro.audio.monitorRotation u:object_r:audio_config_prop:s0 exact bool
+
+persist.config.calibration_fac u:object_r:camera_calibration_prop:s0 exact string
+
+config.disable_cameraservice u:object_r:camera_config_prop:s0 exact bool
+
+camera.disable_zsl_mode u:object_r:camera_config_prop:s0 exact bool
+camera.fifo.disable     u:object_r:camera_config_prop:s0 exact bool
+ro.camera.notify_nfc    u:object_r:camera_config_prop:s0 exact bool
+ro.camera.enableLazyHal u:object_r:camera_config_prop:s0 exact bool
+
+# Should always_debuggable be bool? It's checked against the string "1".
+dalvik.vm.always_debuggable                   u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.appimageformat                      u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.backgroundgctype                    u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.boot-dex2oat-cpu-set                u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.boot-dex2oat-threads                u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.boot-image                          u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.checkjni                            u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.dex2oat-Xms                         u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.dex2oat-Xmx                         u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.dex2oat-cpu-set                     u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.dex2oat-filter                      u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.dex2oat-flags                       u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.dex2oat-max-image-block-size        u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.dex2oat-minidebuginfo               u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.dex2oat-resolve-startup-strings     u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.dex2oat-threads                     u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.dex2oat-updatable-bcp-packages-file u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.dex2oat-very-large                  u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.dex2oat-swap                        u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.dex2oat64.enabled                   u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.dexopt.secondary                    u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.execution-mode                      u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.extra-opts                          u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.foreground-heap-growth-multiplier   u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.gctype                              u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.heapgrowthlimit                     u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.heapmaxfree                         u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.heapminfree                         u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.heapsize                            u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.heapstartsize                       u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.heaptargetutilization               u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.hot-startup-method-samples          u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.image-dex2oat-Xms                   u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.image-dex2oat-Xmx                   u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.image-dex2oat-cpu-set               u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.image-dex2oat-filter                u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.image-dex2oat-flags                 u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.image-dex2oat-threads               u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.isa.arm.features                    u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.arm.variant                     u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.arm64.features                  u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.arm64.variant                   u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.mips.features                   u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.mips.variant                    u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.mips64.features                 u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.mips64.variant                  u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.unknown.features                u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.unknown.variant                 u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.x86.features                    u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.x86.variant                     u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.x86_64.features                 u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.isa.x86_64.variant                  u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.jitinitialsize                      u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.jitmaxsize                          u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.jitprithreadweight                  u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.jitthreshold                        u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.jittransitionweight                 u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.jniopts                             u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.lockprof.threshold                  u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.method-trace                        u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.method-trace-file                   u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.method-trace-file-siz               u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.method-trace-stream                 u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.profilesystemserver                 u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.profilebootclasspath                u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.restore-dex2oat-cpu-set             u:object_r:dalvik_config_prop:s0 exact string
+dalvik.vm.restore-dex2oat-threads             u:object_r:dalvik_config_prop:s0 exact int
+dalvik.vm.usejit                              u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.usejitprofiles                      u:object_r:dalvik_config_prop:s0 exact bool
+dalvik.vm.zygote.max-boot-retry               u:object_r:dalvik_config_prop:s0 exact int
+ro.zygote                                     u:object_r:dalvik_config_prop:s0 exact string
+
+persist.sys.dalvik.vm.lib.2 u:object_r:dalvik_runtime_prop:s0 exact string
+
+keyguard.no_require_sim u:object_r:keyguard_config_prop:s0 exact bool
+
+media.recorder.show_manufacturer_and_model   u:object_r:media_config_prop:s0 exact bool
+media.stagefright.cache-params               u:object_r:media_config_prop:s0 exact string
+media.stagefright.thumbnail.prefer_hw_codecs u:object_r:media_config_prop:s0 exact bool
+persist.sys.media.avsync                     u:object_r:media_config_prop:s0 exact bool
+
+persist.bluetooth.a2dp_offload.cap             u:object_r:bluetooth_a2dp_offload_prop:s0 exact string
+persist.bluetooth.a2dp_offload.disabled        u:object_r:bluetooth_a2dp_offload_prop:s0 exact bool
+persist.bluetooth.bluetooth_audio_hal.disabled u:object_r:bluetooth_audio_hal_prop:s0 exact bool
+persist.bluetooth.btsnoopenable                u:object_r:exported_bluetooth_prop:s0 exact bool
+
+persist.radio.multisim.config u:object_r:radio_control_prop:s0 exact string
+
+persist.sys.hdmi.keep_awake              u:object_r:hdmi_config_prop:s0 exact bool
+ro.hdmi.cec_device_types                 u:object_r:hdmi_config_prop:s0 exact string
+ro.hdmi.device_type                      u:object_r:hdmi_config_prop:s0 exact string
+ro.hdmi.wake_on_hotplug                  u:object_r:hdmi_config_prop:s0 exact bool
+ro.hdmi.cec.source.send_standby_on_sleep u:object_r:hdmi_config_prop:s0 exact enum to_tv broadcast none
+
+pm.dexopt.ab-ota                        u:object_r:exported_pm_prop:s0 exact string
+pm.dexopt.bg-dexopt                     u:object_r:exported_pm_prop:s0 exact string
+pm.dexopt.boot                          u:object_r:exported_pm_prop:s0 exact string
+pm.dexopt.disable_bg_dexopt             u:object_r:exported_pm_prop:s0 exact bool
+pm.dexopt.downgrade_after_inactive_days u:object_r:exported_pm_prop:s0 exact int
+pm.dexopt.first-boot                    u:object_r:exported_pm_prop:s0 exact string
+pm.dexopt.inactive                      u:object_r:exported_pm_prop:s0 exact string
+pm.dexopt.install                       u:object_r:exported_pm_prop:s0 exact string
+pm.dexopt.shared                        u:object_r:exported_pm_prop:s0 exact string
+
+ro.apk_verity.mode u:object_r:apk_verity_prop:s0 exact int
+
+ro.bluetooth.a2dp_offload.supported u:object_r:bluetooth_a2dp_offload_prop:s0 exact bool
+
+ro.boot.vendor.overlay.theme u:object_r:exported_overlay_prop:s0 exact string
+
+ro.bt.bdaddr_path u:object_r:exported_bluetooth_prop:s0 exact string
+
+ro.config.alarm_alert         u:object_r:systemsound_config_prop:s0 exact string
+ro.config.alarm_vol_default   u:object_r:systemsound_config_prop:s0 exact int
+ro.config.alarm_vol_steps     u:object_r:systemsound_config_prop:s0 exact int
+ro.config.media_vol_default   u:object_r:systemsound_config_prop:s0 exact int
+ro.config.media_vol_steps     u:object_r:systemsound_config_prop:s0 exact int
+ro.config.notification_sound  u:object_r:systemsound_config_prop:s0 exact string
+ro.config.ringtone            u:object_r:systemsound_config_prop:s0 exact string
+ro.config.system_vol_default  u:object_r:systemsound_config_prop:s0 exact int
+ro.config.system_vol_steps    u:object_r:systemsound_config_prop:s0 exact int
+ro.config.vc_call_vol_default u:object_r:systemsound_config_prop:s0 exact int
+
+ro.control_privapp_permissions u:object_r:packagemanager_config_prop:s0 exact enum disable enforce log
+ro.cp_system_other_odex        u:object_r:packagemanager_config_prop:s0 exact bool
+
+ro.crypto.allow_encrypt_override                u:object_r:vold_config_prop:s0 exact bool
+ro.crypto.dm_default_key.options_format.version u:object_r:vold_config_prop:s0 exact int
+ro.crypto.fde_algorithm                         u:object_r:vold_config_prop:s0 exact string
+ro.crypto.fde_sector_size                       u:object_r:vold_config_prop:s0 exact int
+ro.crypto.scrypt_params                         u:object_r:vold_config_prop:s0 exact string
+ro.crypto.set_dun                               u:object_r:vold_config_prop:s0 exact bool
+ro.crypto.volume.contents_mode                  u:object_r:vold_config_prop:s0 exact string
+ro.crypto.volume.filenames_mode                 u:object_r:vold_config_prop:s0 exact string
+ro.crypto.volume.metadata.encryption            u:object_r:vold_config_prop:s0 exact string
+ro.crypto.volume.metadata.method                u:object_r:vold_config_prop:s0 exact string
+ro.crypto.volume.options                        u:object_r:vold_config_prop:s0 exact string
+
+ro.dalvik.vm.native.bridge u:object_r:dalvik_config_prop:s0 exact string
+
+external_storage.projid.enabled   u:object_r:storage_config_prop:s0 exact bool
+external_storage.casefold.enabled u:object_r:storage_config_prop:s0 exact bool
+external_storage.sdcardfs.enabled u:object_r:storage_config_prop:s0 exact bool
+
+ro.config.per_app_memcg         u:object_r:lmkd_config_prop:s0 exact bool
+ro.lmk.critical                 u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.critical_upgrade         u:object_r:lmkd_config_prop:s0 exact bool
+ro.lmk.debug                    u:object_r:lmkd_config_prop:s0 exact bool
+ro.lmk.downgrade_pressure       u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.kill_heaviest_task       u:object_r:lmkd_config_prop:s0 exact bool
+ro.lmk.kill_timeout_ms          u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.low                      u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.medium                   u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.psi_partial_stall_ms     u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.psi_complete_stall_ms    u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.swap_free_low_percentage u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.swap_util_max            u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.thrashing_limit          u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.thrashing_limit_decay    u:object_r:lmkd_config_prop:s0 exact int
+ro.lmk.use_minfree_levels       u:object_r:lmkd_config_prop:s0 exact bool
+ro.lmk.upgrade_pressure         u:object_r:lmkd_config_prop:s0 exact int
+lmkd.reinit                     u:object_r:lmkd_prop:s0 exact int
+
+ro.media.xml_variant.codecs             u:object_r:media_variant_prop:s0 exact string
+ro.media.xml_variant.codecs_performance u:object_r:media_variant_prop:s0 exact string
+ro.media.xml_variant.profiles           u:object_r:media_variant_prop:s0 exact string
+
+ro.minui.default_rotation u:object_r:recovery_config_prop:s0 exact string
+ro.minui.overscan_percent u:object_r:recovery_config_prop:s0 exact int
+ro.minui.pixel_format     u:object_r:recovery_config_prop:s0 exact string
+
+ro.oem_unlock_supported u:object_r:oem_unlock_prop:s0 exact int
+
+ro.rebootescrow.device u:object_r:rebootescrow_hal_prop:s0 exact string
+
+ro.storage_manager.enabled u:object_r:storagemanager_config_prop:s0 exact bool
+
+ro.vehicle.hal u:object_r:vehicle_hal_prop:s0 exact string
+
+ro.vendor.build.security_patch u:object_r:vendor_security_patch_level_prop:s0 exact string
+
+ro.zram.mark_idle_delay_mins    u:object_r:zram_config_prop:s0 exact int
+ro.zram.first_wb_delay_mins     u:object_r:zram_config_prop:s0 exact int
+ro.zram.periodic_wb_delay_hours u:object_r:zram_config_prop:s0 exact int
+zram.force_writeback            u:object_r:zram_config_prop:s0 exact bool
+persist.sys.zram_enabled        u:object_r:zram_control_prop:s0 exact bool
+
+sendbug.preferred.domain u:object_r:sendbug_config_prop:s0 exact string
+
+persist.sys.usb.usbradio.config u:object_r:usb_control_prop:s0 exact string
+
+sys.usb.config     u:object_r:usb_control_prop:s0 exact string
+sys.usb.configfs   u:object_r:usb_control_prop:s0 exact int
+sys.usb.controller u:object_r:usb_control_prop:s0 exact string
+sys.usb.state      u:object_r:usb_control_prop:s0 exact string
+
+sys.usb.mtp.device_type u:object_r:usb_config_prop:s0 exact int
+
+sys.usb.config. u:object_r:usb_prop:s0
+
+sys.usb.ffs.aio_compat u:object_r:ffs_config_prop:s0 exact bool
+sys.usb.ffs.max_read   u:object_r:ffs_config_prop:s0 exact int
+sys.usb.ffs.max_write  u:object_r:ffs_config_prop:s0 exact int
+
+sys.usb.ffs.ready     u:object_r:ffs_control_prop:s0 exact bool
+sys.usb.ffs.mtp.ready u:object_r:ffs_control_prop:s0 exact bool
+
+tombstoned.max_tombstone_count u:object_r:tombstone_config_prop:s0 exact int
+
+vold.post_fs_data_done u:object_r:vold_config_prop:s0 exact int
+
+apexd.status u:object_r:apexd_prop:s0 exact enum starting activated ready
+
+dev.bootcomplete   u:object_r:boot_status_prop:s0 exact bool
+sys.boot_completed u:object_r:boot_status_prop:s0 exact bool
+
+persist.sys.device_provisioned u:object_r:provisioned_prop:s0 exact string
+
+persist.sys.theme               u:object_r:theme_prop:s0 exact string
+
+sys.retaildemo.enabled u:object_r:retaildemo_prop:s0 exact int
+
+sys.user.0.ce_available u:object_r:exported3_system_prop:s0 exact bool
+
+aac_drc_boost            u:object_r:aac_drc_prop:s0 exact int
+aac_drc_cut              u:object_r:aac_drc_prop:s0 exact int
+aac_drc_enc_target_level u:object_r:aac_drc_prop:s0 exact int
+aac_drc_heavy            u:object_r:aac_drc_prop:s0 exact int
+aac_drc_reference_level  u:object_r:aac_drc_prop:s0 exact int
+ro.aac_drc_effect_type   u:object_r:aac_drc_prop:s0 exact int
+
+build.version.extensions. u:object_r:module_sdkextensions_prop:s0 prefix int
+
+drm.64bit.enabled            u:object_r:mediadrm_config_prop:s0 exact bool
+media.mediadrmservice.enable u:object_r:mediadrm_config_prop:s0 exact bool
+
+drm.service.enabled u:object_r:drm_service_config_prop:s0 exact bool
+
+dumpstate.dry_run u:object_r:exported_dumpstate_prop:s0 exact bool
+dumpstate.unroot  u:object_r:exported_dumpstate_prop:s0 exact bool
+persist.dumpstate.verbose_logging.enabled u:object_r:hal_dumpstate_config_prop:s0 exact bool
+
+hal.instrumentation.enable u:object_r:hal_instrumentation_prop:s0 exact bool
+
+# default contexts only accessible by coredomain
+init.svc. u:object_r:init_service_status_private_prop:s0 prefix string
+
+# vendor-init-readable init service props
+init.svc.bugreport      u:object_r:init_service_status_prop:s0 exact string
+init.svc.bugreportd     u:object_r:init_service_status_prop:s0 exact string
+init.svc.console        u:object_r:init_service_status_prop:s0 exact string
+init.svc.dumpstatez     u:object_r:init_service_status_prop:s0 exact string
+init.svc.mediadrm       u:object_r:init_service_status_prop:s0 exact string
+init.svc.statsd         u:object_r:init_service_status_prop:s0 exact string
+init.svc.surfaceflinger u:object_r:init_service_status_prop:s0 exact string
+init.svc.tombstoned     u:object_r:init_service_status_prop:s0 exact string
+init.svc.zygote         u:object_r:init_service_status_prop:s0 exact string
+
+libc.debug.malloc.options u:object_r:libc_debug_prop:s0 exact string
+libc.debug.malloc.program u:object_r:libc_debug_prop:s0 exact string
+libc.debug.hooks.enable   u:object_r:libc_debug_prop:s0 exact string
+
+net.redirect_socket_calls.hooked u:object_r:socket_hook_prop:s0 exact bool
+
+persist.sys.locale       u:object_r:exported_system_prop:s0 exact string
+persist.sys.timezone     u:object_r:exported_system_prop:s0 exact string
+persist.sys.test_harness u:object_r:test_harness_prop:s0 exact bool
+
+ro.arch u:object_r:build_prop:s0 exact string
+
+# ro.boot. properties are set based on kernel commandline arguments, which are vendor owned.
+ro.boot.                   u:object_r:bootloader_prop:s0
+ro.boot.avb_version        u:object_r:bootloader_prop:s0 exact string
+ro.boot.baseband           u:object_r:bootloader_prop:s0 exact string
+ro.boot.bootdevice         u:object_r:bootloader_prop:s0 exact string
+ro.boot.bootloader         u:object_r:bootloader_prop:s0 exact string
+ro.boot.boottime           u:object_r:bootloader_prop:s0 exact string
+ro.boot.console            u:object_r:bootloader_prop:s0 exact string
+ro.boot.hardware           u:object_r:bootloader_prop:s0 exact string
+ro.boot.hardware.color     u:object_r:bootloader_prop:s0 exact string
+ro.boot.hardware.sku       u:object_r:bootloader_prop:s0 exact string
+ro.boot.keymaster          u:object_r:bootloader_prop:s0 exact string
+ro.boot.mode               u:object_r:bootloader_prop:s0 exact string
+ro.boot.revision           u:object_r:bootloader_prop:s0 exact string
+ro.boot.vbmeta.avb_version u:object_r:bootloader_prop:s0 exact string
+ro.boot.verifiedbootstate  u:object_r:bootloader_prop:s0 exact string
+ro.boot.veritymode         u:object_r:bootloader_prop:s0 exact string
+
+# These ro.X properties are set to values of ro.boot.X by property_service.
+ro.baseband   u:object_r:bootloader_prop:s0 exact string
+ro.bootloader u:object_r:bootloader_prop:s0 exact string
+ro.bootmode   u:object_r:bootloader_prop:s0 exact string
+ro.hardware   u:object_r:bootloader_prop:s0 exact string
+ro.revision   u:object_r:bootloader_prop:s0 exact string
+
+ro.boot.dynamic_partitions          u:object_r:exported_default_prop:s0 exact string
+ro.boot.dynamic_partitions_retrofit u:object_r:exported_default_prop:s0 exact string
+
+ro.build.date                        u:object_r:build_prop:s0 exact string
+ro.build.date.utc                    u:object_r:build_prop:s0 exact int
+ro.build.description                 u:object_r:build_prop:s0 exact string
+ro.build.display.id                  u:object_r:build_prop:s0 exact string
+ro.build.host                        u:object_r:build_prop:s0 exact string
+ro.build.id                          u:object_r:build_prop:s0 exact string
+ro.build.product                     u:object_r:build_prop:s0 exact string
+ro.build.system_root_image           u:object_r:build_prop:s0 exact bool
+ro.build.tags                        u:object_r:build_prop:s0 exact string
+ro.build.type                        u:object_r:build_prop:s0 exact string
+ro.build.user                        u:object_r:build_prop:s0 exact string
+ro.build.version.base_os             u:object_r:build_prop:s0 exact string
+ro.build.version.codename            u:object_r:build_prop:s0 exact string
+ro.build.version.incremental         u:object_r:build_prop:s0 exact string
+ro.build.version.preview_sdk         u:object_r:build_prop:s0 exact int
+ro.build.version.release             u:object_r:build_prop:s0 exact string
+ro.build.version.release_or_codename u:object_r:build_prop:s0 exact string
+ro.build.version.sdk                 u:object_r:build_prop:s0 exact int
+ro.build.version.security_patch      u:object_r:build_prop:s0 exact string
+
+ro.debuggable u:object_r:build_prop:s0 exact bool
+
+ro.product.cpu.abi       u:object_r:build_prop:s0 exact string
+ro.product.cpu.abilist   u:object_r:build_prop:s0 exact string
+ro.product.cpu.abilist32 u:object_r:build_prop:s0 exact string
+ro.product.cpu.abilist64 u:object_r:build_prop:s0 exact string
+
+ro.adb.secure u:object_r:build_prop:s0 exact bool
+ro.secure     u:object_r:build_prop:s0 exact int
+
+# These 5 properties are set by property_service
+ro.product.brand         u:object_r:build_prop:s0 exact string
+ro.product.device        u:object_r:build_prop:s0 exact string
+ro.product.manufacturer  u:object_r:build_prop:s0 exact string
+ro.product.model         u:object_r:build_prop:s0 exact string
+ro.product.name          u:object_r:build_prop:s0 exact string
+
+# Sanitizer properties
+ro.sanitize.address          u:object_r:build_prop:s0 exact bool
+ro.sanitize.cfi              u:object_r:build_prop:s0 exact bool
+ro.sanitize.default-ub       u:object_r:build_prop:s0 exact bool
+ro.sanitize.fuzzer           u:object_r:build_prop:s0 exact bool
+ro.sanitize.hwaddress        u:object_r:build_prop:s0 exact bool
+ro.sanitize.integer_overflow u:object_r:build_prop:s0 exact bool
+ro.sanitize.safe-stack       u:object_r:build_prop:s0 exact bool
+ro.sanitize.scudo            u:object_r:build_prop:s0 exact bool
+ro.sanitize.thread           u:object_r:build_prop:s0 exact bool
+ro.sanitize.undefined        u:object_r:build_prop:s0 exact bool
+
+# All odm build props are set by /odm/build.prop
+ro.odm.build.date                u:object_r:build_odm_prop:s0 exact string
+ro.odm.build.date.utc            u:object_r:build_odm_prop:s0 exact int
+ro.odm.build.fingerprint         u:object_r:build_odm_prop:s0 exact string
+ro.odm.build.version.incremental u:object_r:build_odm_prop:s0 exact string
+
+ro.product.odm.brand        u:object_r:build_odm_prop:s0 exact string
+ro.product.odm.device       u:object_r:build_odm_prop:s0 exact string
+ro.product.odm.manufacturer u:object_r:build_odm_prop:s0 exact string
+ro.product.odm.model        u:object_r:build_odm_prop:s0 exact string
+ro.product.odm.name         u:object_r:build_odm_prop:s0 exact string
+
+# All vendor_dlkm build props are set by /vendor_dlkm/etc/build.prop
+ro.vendor_dlkm.build.date                u:object_r:build_vendor_prop:s0 exact string
+ro.vendor_dlkm.build.date.utc            u:object_r:build_vendor_prop:s0 exact int
+ro.vendor_dlkm.build.fingerprint         u:object_r:build_vendor_prop:s0 exact string
+ro.vendor_dlkm.build.version.incremental u:object_r:build_vendor_prop:s0 exact string
+
+# All odm_dlkm build props are set by /odm_dlkm/etc/build.prop
+ro.odm_dlkm.build.date                u:object_r:build_vendor_prop:s0 exact string
+ro.odm_dlkm.build.date.utc            u:object_r:build_vendor_prop:s0 exact int
+ro.odm_dlkm.build.fingerprint         u:object_r:build_vendor_prop:s0 exact string
+ro.odm_dlkm.build.version.incremental u:object_r:build_vendor_prop:s0 exact string
+
+# All vendor build props are set by /vendor/build.prop
+ro.vendor.build.date                u:object_r:build_vendor_prop:s0 exact string
+ro.vendor.build.date.utc            u:object_r:build_vendor_prop:s0 exact int
+ro.vendor.build.fingerprint         u:object_r:build_vendor_prop:s0 exact string
+ro.vendor.build.version.incremental u:object_r:build_vendor_prop:s0 exact string
+ro.vendor.build.version.sdk         u:object_r:build_vendor_prop:s0 exact int
+
+ro.product.board               u:object_r:build_vendor_prop:s0 exact string
+ro.product.first_api_level     u:object_r:build_vendor_prop:s0 exact int
+ro.product.vendor.brand        u:object_r:build_vendor_prop:s0 exact string
+ro.product.vendor.device       u:object_r:build_vendor_prop:s0 exact string
+ro.product.vendor.manufacturer u:object_r:build_vendor_prop:s0 exact string
+ro.product.vendor.model        u:object_r:build_vendor_prop:s0 exact string
+ro.product.vendor.name         u:object_r:build_vendor_prop:s0 exact string
+
+ro.crypto.state u:object_r:vold_status_prop:s0 exact enum encrypted unencrypted unsupported
+ro.crypto.type  u:object_r:vold_status_prop:s0 exact enum block file none
+
+ro.property_service.version u:object_r:property_service_version_prop:s0 exact int
+
+ro.vendor.redirect_socket_calls u:object_r:vendor_socket_hook_prop:s0 exact bool
+
+service.bootanim.exit u:object_r:exported_system_prop:s0 exact int
+
+sys.init.userspace_reboot.in_progress u:object_r:userspace_reboot_exported_prop:s0 exact bool
+sys.use_memfd                         u:object_r:use_memfd_prop:s0 exact bool
+
+vold.decrypt u:object_r:vold_status_prop:s0 exact string
+
+aaudio.hw_burst_min_usec     u:object_r:aaudio_config_prop:s0 exact int
+aaudio.minimum_sleep_usec    u:object_r:aaudio_config_prop:s0 exact int
+aaudio.mixer_bursts          u:object_r:aaudio_config_prop:s0 exact int
+aaudio.mmap_exclusive_policy u:object_r:aaudio_config_prop:s0 exact int
+aaudio.mmap_policy           u:object_r:aaudio_config_prop:s0 exact int
+aaudio.wakeup_delay_usec     u:object_r:aaudio_config_prop:s0 exact int
+
+persist.rcs.supported u:object_r:exported_default_prop:s0 exact int
+
+ro.bionic.2nd_arch        u:object_r:cpu_variant_prop:s0 exact string
+ro.bionic.2nd_cpu_variant u:object_r:cpu_variant_prop:s0 exact string
+ro.bionic.arch            u:object_r:cpu_variant_prop:s0 exact string
+ro.bionic.cpu_variant     u:object_r:cpu_variant_prop:s0 exact string
+
+ro.board.platform u:object_r:exported_default_prop:s0 exact string
+
+ro.boot.fake_battery         u:object_r:exported_default_prop:s0 exact int
+ro.boot.fstab_suffix         u:object_r:exported_default_prop:s0 exact string
+ro.boot.hardware.revision    u:object_r:exported_default_prop:s0 exact string
+ro.boot.product.hardware.sku u:object_r:exported_default_prop:s0 exact string
+ro.boot.product.vendor.sku   u:object_r:exported_default_prop:s0 exact string
+ro.boot.slot_suffix          u:object_r:exported_default_prop:s0 exact string
+
+ro.boringcrypto.hwrand u:object_r:exported_default_prop:s0 exact bool
+
+ro.build.ab_update         u:object_r:exported_default_prop:s0 exact string
+ro.build.expect.baseband   u:object_r:exported_default_prop:s0 exact string
+ro.build.expect.bootloader u:object_r:exported_default_prop:s0 exact string
+
+ro.carrier u:object_r:exported_default_prop:s0 exact string
+
+ro.config.low_ram           u:object_r:exported_config_prop:s0 exact bool
+ro.config.vc_call_vol_steps u:object_r:exported_config_prop:s0 exact int
+
+ro.frp.pst u:object_r:exported_default_prop:s0 exact string
+
+ro.hardware.activity_recognition u:object_r:exported_default_prop:s0 exact string
+ro.hardware.audio                u:object_r:exported_default_prop:s0 exact string
+ro.hardware.audio.a2dp           u:object_r:exported_default_prop:s0 exact string
+ro.hardware.audio.hearing_aid    u:object_r:exported_default_prop:s0 exact string
+ro.hardware.audio.primary        u:object_r:exported_default_prop:s0 exact string
+ro.hardware.audio.usb            u:object_r:exported_default_prop:s0 exact string
+ro.hardware.audio_policy         u:object_r:exported_default_prop:s0 exact string
+ro.hardware.bootctrl             u:object_r:exported_default_prop:s0 exact string
+ro.hardware.camera               u:object_r:exported_default_prop:s0 exact string
+ro.hardware.consumerir           u:object_r:exported_default_prop:s0 exact string
+ro.hardware.context_hub          u:object_r:exported_default_prop:s0 exact string
+ro.hardware.egl                  u:object_r:exported_default_prop:s0 exact string
+ro.hardware.fingerprint          u:object_r:exported_default_prop:s0 exact string
+ro.hardware.flp                  u:object_r:exported_default_prop:s0 exact string
+ro.hardware.gatekeeper           u:object_r:exported_default_prop:s0 exact string
+ro.hardware.gps                  u:object_r:exported_default_prop:s0 exact string
+ro.hardware.gralloc              u:object_r:exported_default_prop:s0 exact string
+ro.hardware.hdmi_cec             u:object_r:exported_default_prop:s0 exact string
+ro.hardware.hwcomposer           u:object_r:exported_default_prop:s0 exact string
+ro.hardware.input                u:object_r:exported_default_prop:s0 exact string
+ro.hardware.keystore             u:object_r:exported_default_prop:s0 exact string
+ro.hardware.keystore_desede      u:object_r:exported_default_prop:s0 exact string
+ro.hardware.lights               u:object_r:exported_default_prop:s0 exact string
+ro.hardware.local_time           u:object_r:exported_default_prop:s0 exact string
+ro.hardware.memtrack             u:object_r:exported_default_prop:s0 exact string
+ro.hardware.nfc                  u:object_r:exported_default_prop:s0 exact string
+ro.hardware.nfc_nci              u:object_r:exported_default_prop:s0 exact string
+ro.hardware.nfc_tag              u:object_r:exported_default_prop:s0 exact string
+ro.hardware.nvram                u:object_r:exported_default_prop:s0 exact string
+ro.hardware.power                u:object_r:exported_default_prop:s0 exact string
+ro.hardware.radio                u:object_r:exported_default_prop:s0 exact string
+ro.hardware.sensors              u:object_r:exported_default_prop:s0 exact string
+ro.hardware.sound_trigger        u:object_r:exported_default_prop:s0 exact string
+ro.hardware.thermal              u:object_r:exported_default_prop:s0 exact string
+ro.hardware.tv_input             u:object_r:exported_default_prop:s0 exact string
+ro.hardware.type                 u:object_r:exported_default_prop:s0 exact string
+ro.hardware.vehicle              u:object_r:exported_default_prop:s0 exact string
+ro.hardware.vibrator             u:object_r:exported_default_prop:s0 exact string
+ro.hardware.virtual_device       u:object_r:exported_default_prop:s0 exact string
+ro.hardware.vulkan               u:object_r:exported_default_prop:s0 exact string
+
+ro.hwui.use_vulkan u:object_r:exported_default_prop:s0 exact bool
+
+ro.kernel.qemu             u:object_r:exported_default_prop:s0 exact bool
+ro.kernel.qemu.            u:object_r:exported_default_prop:s0
+ro.kernel.android.bootanim u:object_r:exported_default_prop:s0 exact int
+ro.kernel.ebpf.supported   u:object_r:exported_default_prop:s0 exact bool
+
+ro.oem.key1 u:object_r:exported_default_prop:s0 exact string
+
+ro.product.vndk.version u:object_r:vndk_prop:s0 exact string
+
+ro.vndk.lite    u:object_r:vndk_prop:s0 exact bool
+ro.vndk.version u:object_r:vndk_prop:s0 exact string
+
+ro.vts.coverage u:object_r:vts_config_prop:s0 exact int
+
+vts.native_server.on u:object_r:vts_status_prop:s0 exact bool
+
+wifi.active.interface     u:object_r:wifi_hal_prop:s0 exact string
+wifi.aware.interface      u:object_r:wifi_hal_prop:s0 exact string
+wifi.concurrent.interface u:object_r:wifi_hal_prop:s0 exact string
+wifi.direct.interface     u:object_r:wifi_hal_prop:s0 exact string
+wifi.interface            u:object_r:wifi_hal_prop:s0 exact string
+wlan.driver.status        u:object_r:wifi_hal_prop:s0 exact enum ok unloaded
+
+ro.boot.wificountrycode u:object_r:wifi_config_prop:s0 exact string
+
+ro.apex.updatable u:object_r:exported_default_prop:s0 exact bool
+
+# Property to enable incremental feature
+ro.incremental.enable      u:object_r:incremental_prop:s0
+
+# Properties to configure userspace reboot.
+init.userspace_reboot.is_supported u:object_r:userspace_reboot_config_prop:s0 exact bool
+init.userspace_reboot.sigkill.timeoutmillis u:object_r:userspace_reboot_config_prop:s0 exact int
+init.userspace_reboot.sigterm.timeoutmillis u:object_r:userspace_reboot_config_prop:s0 exact int
+init.userspace_reboot.started.timeoutmillis u:object_r:userspace_reboot_config_prop:s0 exact int
+init.userspace_reboot.userdata_remount.timeoutmillis u:object_r:userspace_reboot_config_prop:s0 exact int
+init.userspace_reboot.watchdog.timeoutmillis u:object_r:userspace_reboot_config_prop:s0 exact int
+
+sys.shutdown.requested u:object_r:exported_system_prop:s0 exact string
+
+# surfaceflinger properties
+ro.surface_flinger.default_composition_dataspace          u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.default_composition_pixel_format       u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.force_hwc_copy_for_virtual_displays    u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.has_HDR_display                        u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.has_wide_color_display                 u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.max_frame_buffer_acquired_buffers      u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.max_graphics_height                    u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.max_graphics_width                     u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.max_virtual_display_dimension          u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.primary_display_orientation            u:object_r:surfaceflinger_prop:s0 exact enum ORIENTATION_0 ORIENTATION_180 ORIENTATION_270 ORIENTATION_90
+ro.surface_flinger.present_time_offset_from_vsync_ns      u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.running_without_sync_framework         u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.start_graphics_allocator_service       u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.use_color_management                   u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.use_context_priority                   u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.use_vr_flinger                         u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.vsync_event_phase_offset_ns            u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.vsync_sf_event_phase_offset_ns         u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.wcg_composition_dataspace              u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.wcg_composition_pixel_format           u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.display_primary_red                    u:object_r:surfaceflinger_prop:s0 exact string
+ro.surface_flinger.display_primary_green                  u:object_r:surfaceflinger_prop:s0 exact string
+ro.surface_flinger.display_primary_blue                   u:object_r:surfaceflinger_prop:s0 exact string
+ro.surface_flinger.display_primary_white                  u:object_r:surfaceflinger_prop:s0 exact string
+ro.surface_flinger.protected_contents                     u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.set_idle_timer_ms                      u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.set_touch_timer_ms                     u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.set_display_power_timer_ms             u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.support_kernel_idle_timer              u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.use_smart_90_for_video                 u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.use_content_detection_for_refresh_rate u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.color_space_agnostic_dataspace         u:object_r:surfaceflinger_prop:s0 exact int
+ro.surface_flinger.refresh_rate_switching                 u:object_r:surfaceflinger_prop:s0 exact bool
+
+ro.sf.disable_triple_buffer u:object_r:surfaceflinger_prop:s0 exact bool
+ro.sf.lcd_density           u:object_r:surfaceflinger_prop:s0 exact int
+
+persist.sys.sf.color_mode       u:object_r:surfaceflinger_color_prop:s0 exact int
+persist.sys.sf.color_saturation u:object_r:surfaceflinger_color_prop:s0 exact string
+persist.sys.sf.native_mode      u:object_r:surfaceflinger_color_prop:s0 exact int
+
+# Binder cache properties.  These are world-readable
+cache_key.app_inactive                   u:object_r:binder_cache_system_server_prop:s0
+cache_key.is_compat_change_enabled       u:object_r:binder_cache_system_server_prop:s0
+cache_key.get_packages_for_uid           u:object_r:binder_cache_system_server_prop:s0
+cache_key.has_system_feature             u:object_r:binder_cache_system_server_prop:s0
+cache_key.is_interactive                 u:object_r:binder_cache_system_server_prop:s0
+cache_key.is_power_save_mode             u:object_r:binder_cache_system_server_prop:s0
+cache_key.is_user_unlocked               u:object_r:binder_cache_system_server_prop:s0
+cache_key.volume_list                    u:object_r:binder_cache_system_server_prop:s0
+cache_key.display_info                   u:object_r:binder_cache_system_server_prop:s0
+cache_key.location_enabled               u:object_r:binder_cache_system_server_prop:s0
+cache_key.package_info                   u:object_r:binder_cache_system_server_prop:s0
+
+cache_key.bluetooth.                     u:object_r:binder_cache_bluetooth_server_prop:s0 prefix string
+cache_key.system_server.                 u:object_r:binder_cache_system_server_prop:s0 prefix string
+cache_key.telephony.                     u:object_r:binder_cache_telephony_server_prop:s0 prefix string
+
+gsm.sim.operator.numeric       u:object_r:telephony_status_prop:s0 exact string
+persist.radio.airplane_mode_on u:object_r:telephony_status_prop:s0 exact bool
+
+ro.com.android.dataroaming        u:object_r:telephony_config_prop:s0 exact bool
+ro.com.android.prov_mobiledata    u:object_r:telephony_config_prop:s0 exact bool
+ro.radio.noril                    u:object_r:telephony_config_prop:s0 exact string
+ro.telephony.call_ring.multiple   u:object_r:telephony_config_prop:s0 exact bool
+ro.telephony.default_cdma_sub     u:object_r:telephony_config_prop:s0 exact int
+ro.telephony.default_network      u:object_r:telephony_config_prop:s0 exact string
+ro.telephony.iwlan_operation_mode u:object_r:telephony_config_prop:s0 exact enum default legacy AP-assisted
+telephony.active_modems.max_count u:object_r:telephony_config_prop:s0 exact int
+telephony.lteOnCdmaDevice         u:object_r:telephony_config_prop:s0 exact int
+persist.dbg.volte_avail_ovr       u:object_r:telephony_config_prop:s0 exact int
+persist.dbg.vt_avail_ovr          u:object_r:telephony_config_prop:s0 exact int
+persist.dbg.wfc_avail_ovr         u:object_r:telephony_config_prop:s0 exact int
+
+# System locale list filter configuration
+ro.localization.locale_filter u:object_r:localization_prop:s0 exact string
+
+# Graphics related properties
+ro.opengles.version u:object_r:graphics_config_prop:s0 exact int
+
+ro.gfx.driver.0        u:object_r:graphics_config_prop:s0 exact string
+ro.gfx.driver.1        u:object_r:graphics_config_prop:s0 exact string
+ro.gfx.angle.supported u:object_r:graphics_config_prop:s0 exact bool
+
+graphics.gpu.profiler.support          u:object_r:graphics_config_prop:s0 exact bool
+graphics.gpu.profiler.vulkan_layer_apk u:object_r:graphics_config_prop:s0 exact string
+    )";
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
index 11db7ec..f71d70a 100644
--- a/libc/system_properties/contexts_split.cpp
+++ b/libc/system_properties/contexts_split.cpp
@@ -114,8 +114,6 @@
 }
 
 // The below two functions are duplicated from label_support.c in libselinux.
-// TODO: Find a location suitable for these functions such that both libc and
-// libselinux can share a common source file.
 
 // The read_spec_entries and read_spec_entry functions may be used to
 // replace sscanf to read entries from spec files. The file and
@@ -271,7 +269,7 @@
     if (!InitializePropertiesFromFile("/system/etc/selinux/plat_property_contexts")) {
       return false;
     }
-    // Don't check for failure here, so we always have a sane list of properties.
+    // Don't check for failure here, since we don't always have all of these partitions.
     // E.g. In case of recovery, the vendor partition will not have mounted and we
     // still need the system / platform properties to function.
     if (access("/vendor/etc/selinux/vendor_property_contexts", R_OK) != -1) {
@@ -326,10 +324,16 @@
   return true;
 }
 
-prop_area* ContextsSplit::GetPropAreaForName(const char* name) {
+PrefixNode* ContextsSplit::GetPrefixNodeForName(const char* name) {
   auto entry = ListFind(prefixes_, [name](PrefixNode* l) {
     return l->prefix[0] == '*' || !strncmp(l->prefix, name, l->prefix_len);
   });
+
+  return entry;
+}
+
+prop_area* ContextsSplit::GetPropAreaForName(const char* name) {
+  auto entry = GetPrefixNodeForName(name);
   if (!entry) {
     return nullptr;
   }
diff --git a/libc/system_properties/include/system_properties/contexts_split.h b/libc/system_properties/include/system_properties/contexts_split.h
index acb18e3..1d954cc 100644
--- a/libc/system_properties/include/system_properties/contexts_split.h
+++ b/libc/system_properties/include/system_properties/contexts_split.h
@@ -47,7 +47,9 @@
   virtual void ResetAccess() override;
   virtual void FreeAndUnmap() override;
 
- private:
+  PrefixNode* GetPrefixNodeForName(const char* name);
+
+ protected:
   bool MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed);
   bool InitializePropertiesFromFile(const char* filename);
   bool InitializeProperties();
diff --git a/libc/system_properties/include/system_properties/prop_trace.h b/libc/system_properties/include/system_properties/prop_trace.h
new file mode 100644
index 0000000..7c65a6d
--- /dev/null
+++ b/libc/system_properties/include/system_properties/prop_trace.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "platform/bionic/macros.h"
+
+#include "prop_info.h"
+
+// Tracing class for sysprop. To begin a trace at a specified point:
+//   SyspropTrace trace ("prop_name", "prop_value");
+// The trace will end when the constructor goes out of scope.
+// For read-only properties (ro.*), also need to pass prop_info struct.
+
+enum class PropertyAction {
+  kPropertyFind = 0,
+  kPropertySet,
+  kPropertyGetReadOnly,
+  kPropertyGetReadWrite,
+};
+
+class __LIBC_HIDDEN__ SyspropTrace {
+ public:
+  explicit SyspropTrace(const char* prop_name, const char* prop_value, const prop_info* pi,
+                        PropertyAction action);
+  ~SyspropTrace();
+
+ private:
+  const char* prop_name_;
+  const char* prop_value_;
+  const prop_info* prop_info_;
+  PropertyAction prop_action_;
+  bool output_trace_;
+
+  BIONIC_DISALLOW_COPY_AND_ASSIGN(SyspropTrace);
+};
diff --git a/libc/system_properties/prop_trace.cpp b/libc/system_properties/prop_trace.cpp
new file mode 100644
index 0000000..ac7ff94
--- /dev/null
+++ b/libc/system_properties/prop_trace.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#include "system_properties/prop_trace.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "private/CachedProperty.h"
+#include "private/bionic_lock.h"
+#include "private/bionic_systrace.h"
+
+#include <async_safe/log.h>
+#include <cutils/trace.h>  // For ATRACE_TAG_SYSPROP.
+
+#define PROP_TRACE_MSG_LENGTH 1024
+
+static bool should_trace_prop(const char* prop_name) {
+  // Should not trace kTraceTagsProp to avoid infinite recursion.
+  // Because the following g_trace_enable_flags.Get() will get the property value
+  // of kTraceTagsProp again, which in turn invokes should_trace_prop() here.
+  if (prop_name == nullptr || !strcmp(prop_name, kTraceTagsProp)) {
+    return false;
+  }
+
+  return should_trace(ATRACE_TAG_SYSPROP);
+}
+
+static void sysprop_trace_end() {
+  int trace_marker_fd = get_trace_marker_fd();
+  if (trace_marker_fd == -1) {
+    return;
+  }
+
+  TEMP_FAILURE_RETRY(write(trace_marker_fd, "E|", 2));
+}
+
+static void get_sysprop_trace_end(const prop_info* pi, const char* prop_value,
+                                  bool read_only = false) {
+  const char* output_value;
+  char message[PROP_TRACE_MSG_LENGTH];
+
+  if (read_only) {
+    if (pi->is_long()) {
+      output_value = pi->long_value();
+    } else {
+      output_value = pi->value;
+    }
+  } else {
+    output_value = prop_value;
+  }
+
+  snprintf(message, sizeof(message), "prop_get: %s, value: %s", pi->name,
+           output_value ? output_value : "null_value");
+  output_trace(message, 'E');  // 'E' for end.
+}
+
+SyspropTrace::SyspropTrace(const char* prop_name, const char* prop_value, const prop_info* pi,
+                           PropertyAction action)
+    : prop_name_(prop_name),
+      prop_value_(prop_value),
+      prop_info_(pi),
+      prop_action_(action),
+      output_trace_(false) {
+  if (!should_trace_prop(prop_name)) {
+    return;
+  }
+
+  char message[PROP_TRACE_MSG_LENGTH];
+  if (prop_action_ == PropertyAction::kPropertyFind) {
+    snprintf(message, sizeof(message), "prop_find: %s", prop_name_);
+  } else if (prop_action_ == PropertyAction::kPropertySet) {
+    snprintf(message, sizeof(message), "prop_set: %s, value: %s", prop_name_,
+             prop_value_ ? prop_value_ : "null_value");
+  } else {
+    // For property get, the prop_value_ will be resolved then printed in the destructor.
+    snprintf(message, sizeof(message), "prop_get: %s", prop_name_);
+  }
+
+  output_trace(message, 'B');  // 'B' for begin.
+  output_trace_ = true;
+}
+
+SyspropTrace::~SyspropTrace() {
+  if (!output_trace_) {
+    return;
+  }
+  if (prop_action_ == PropertyAction::kPropertyFind ||
+      prop_action_ == PropertyAction::kPropertySet) {
+    sysprop_trace_end();
+  } else if (prop_action_ == PropertyAction::kPropertyGetReadOnly) {
+    get_sysprop_trace_end(prop_info_, prop_value_, true /* read_only */);
+  } else if (prop_action_ == PropertyAction::kPropertyGetReadWrite) {
+    get_sysprop_trace_end(prop_info_, prop_value_, false /* read_only */);
+  }
+  output_trace_ = false;
+}
diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp
index 8404778..3fd20b7 100644
--- a/libc/system_properties/system_properties.cpp
+++ b/libc/system_properties/system_properties.cpp
@@ -46,6 +46,7 @@
 #include "system_properties/context_node.h"
 #include "system_properties/prop_area.h"
 #include "system_properties/prop_info.h"
+#include "system_properties/prop_trace.h"
 
 #define SERIAL_DIRTY(serial) ((serial)&1)
 #define SERIAL_VALUE_LEN(serial) ((serial) >> 24)
@@ -127,6 +128,9 @@
     return nullptr;
   }
 
+  SyspropTrace trace(name, nullptr /* prop_value */, nullptr /* prop_info */,
+                     PropertyAction::kPropertyFind);
+
   prop_area* pa = contexts_->GetPropAreaForName(name);
   if (!pa) {
     async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
@@ -201,6 +205,10 @@
   // Read only properties don't need to copy the value to a temporary buffer, since it can never
   // change.  We use relaxed memory order on the serial load for the same reason.
   if (is_read_only(pi->name)) {
+    // The 2nd argument is not required for read-only property tracing, as the
+    // value can be obtained via pi->value or pi->long_value().
+    SyspropTrace trace(pi->name, nullptr /* prop_value */, pi /* prop_info */,
+                       PropertyAction::kPropertyGetReadOnly);
     uint32_t serial = load_const_atomic(&pi->serial, memory_order_relaxed);
     if (pi->is_long()) {
       callback(cookie, pi->name, pi->long_value(), serial);
@@ -211,6 +219,8 @@
   }
 
   char value_buf[PROP_VALUE_MAX];
+  SyspropTrace trace(pi->name, value_buf, pi /* prop_info */,
+                     PropertyAction::kPropertyGetReadWrite);
   uint32_t serial = ReadMutablePropertyValue(pi, value_buf);
   callback(cookie, pi->name, value_buf, serial);
 }
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index 4de0181..d8d1982 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -182,9 +182,9 @@
   '_ctype_',
   '__libc_init',
 ])
-# POSIX has some stuff that's too stupid for words (a64l) or not actually
-# implemented in glibc unless you count always failing with ENOSYS as
-# being implemented (fattach). Other stuff (fmtmsg) isn't used in any
+# POSIX has some stuff that's unusable in the modern world (a64l) or not
+# actually implemented in glibc unless you count always failing with ENOSYS
+# as being implemented (fattach). Other stuff (fmtmsg) isn't used in any
 # codebase I have access to, internal or external.
 in_posix_and_glibc_but_dead_or_useless = set([
   'a64l', # obsolete
diff --git a/libc/tools/generate-NOTICE.py b/libc/tools/generate-NOTICE.py
index 7218445..b6deb9c 100755
--- a/libc/tools/generate-NOTICE.py
+++ b/libc/tools/generate-NOTICE.py
@@ -26,6 +26,7 @@
     uninteresting_extensions = [
         ".bp",
         ".map",
+        ".md",
         ".mk",
         ".py",
         ".pyc",
@@ -34,7 +35,7 @@
     ]
     if os.path.splitext(path)[1] in uninteresting_extensions:
         return False
-    if path.endswith("/notice") or path.endswith("/readme"):
+    if path.endswith("/notice") or path.endswith("/readme") or path.endswith("/pylintrc"):
         return False
     return True
 
@@ -137,7 +138,7 @@
 
     if not "Copyright" in content:
         if "public domain" in content.lower():
-            warn("ignoring public domain file %s" % path)
+            warn_verbose("ignoring public domain file %s" % path)
             return
         warn('no copyright notice found in "%s" (%d lines)' % (path, len(lines)))
         return
diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index ba7e2ca..89eeb44 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -56,12 +56,12 @@
   return priorities
 
 
-def merge_names(base_names, whitelist_names, blacklist_names):
-  if bool(blacklist_names - base_names):
-    raise RuntimeError("Blacklist item not in bionic - aborting " + str(
-        blacklist_names - base_names))
+def merge_names(base_names, allowlist_names, blocklist_names):
+  if bool(blocklist_names - base_names):
+    raise RuntimeError("blocklist item not in bionic - aborting " + str(
+        blocklist_names - base_names))
 
-  return (base_names - blacklist_names) | whitelist_names
+  return (base_names - blocklist_names) | allowlist_names
 
 
 def extract_priority_syscalls(syscalls, priorities):
@@ -230,19 +230,19 @@
 def gen_policy(name_modifier, out_dir, base_syscall_file, syscall_files, syscall_NRs, priority_file):
   for arch in SupportedArchitectures:
     base_names = load_syscall_names_from_file(base_syscall_file, arch)
-    whitelist_names = set()
-    blacklist_names = set()
+    allowlist_names = set()
+    blocklist_names = set()
     for f in syscall_files:
-      if "blacklist" in f.lower():
-        blacklist_names |= load_syscall_names_from_file(f, arch)
+      if "blocklist" in f.lower():
+        blocklist_names |= load_syscall_names_from_file(f, arch)
       else:
-        whitelist_names |= load_syscall_names_from_file(f, arch)
+        allowlist_names |= load_syscall_names_from_file(f, arch)
     priorities = []
     if priority_file:
       priorities = load_syscall_priorities_from_file(priority_file)
 
     allowed_syscalls = []
-    for name in merge_names(base_names, whitelist_names, blacklist_names):
+    for name in merge_names(base_names, allowlist_names, blocklist_names):
       try:
         allowed_syscalls.append((name, syscall_NRs[arch][name]))
       except:
@@ -274,8 +274,8 @@
                       help=("The path of the input files. In order to "
                             "simplify the build rules, it can take any of the "
                             "following files: \n"
-                            "* /blacklist.*\.txt$/ syscall blacklist.\n"
-                            "* /whitelist.*\.txt$/ syscall whitelist.\n"
+                            "* /blocklist.*\.txt$/ syscall blocklist.\n"
+                            "* /allowlist.*\.txt$/ syscall allowlist.\n"
                             "* /priority.txt$/ priorities for bpf rules.\n"
                             "* otherwise, syscall name-number mapping.\n"))
   args = parser.parse_args()
diff --git a/libc/tools/pylintrc b/libc/tools/pylintrc
deleted file mode 100644
index 2481b12..0000000
--- a/libc/tools/pylintrc
+++ /dev/null
@@ -1,280 +0,0 @@
-[MASTER]
-
-# Specify a configuration file.
-#rcfile=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-#init-hook=
-
-# Profiled execution.
-profile=no
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=CVS
-
-# Pickle collected data for later comparisons.
-persistent=yes
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-
-[MESSAGES CONTROL]
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time. See also the "--disable" option for examples.
-#enable=
-
-# Disable the message, report, category or checker with the given id(s). You
-# can either give multiple identifiers separated by comma (,) or put this
-# option multiple times (only on the command line, not in the configuration
-# file where it should appear only once).You can also use "--disable=all" to
-# disable everything first and then reenable specific checks. For example, if
-# you want to run only the similarities checker, you can use "--disable=all
-# --enable=similarities". If you want to run only the classes checker, but have
-# no Warning level messages displayed, use"--disable=all --enable=classes
-# --disable=W"
-disable=missing-docstring,invalid-name,no-self-use,fixme,design
-
-
-[REPORTS]
-
-# Set the output format. Available formats are text, parseable, colorized, msvs
-# (visual studio) and html. You can also give a reporter class, eg
-# mypackage.mymodule.MyReporterClass.
-output-format=text
-
-# Put messages in a separate file for each module / package specified on the
-# command line instead of printing them on stdout. Reports (if any) will be
-# written in a file name "pylint_global.[txt|html]".
-files-output=no
-
-# Tells whether to display a full report or only the messages
-reports=yes
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Add a comment according to your evaluation note. This is used by the global
-# evaluation report (RP0004).
-comment=no
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details
-#msg-template=
-
-
-[BASIC]
-
-# Required attributes for module, separated by a comma
-required-attributes=
-
-# List of builtins function names that should not be used, separated by a comma
-bad-functions=map,filter,apply,input
-
-# Regular expression which should only match correct module names
-module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-
-# Regular expression which should only match correct module level names
-const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
-
-# Regular expression which should only match correct class names
-class-rgx=[A-Z_][a-zA-Z0-9]+$
-
-# Regular expression which should only match correct function names
-function-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct method names
-method-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct instance attribute names
-attr-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct argument names
-argument-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct variable names
-variable-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match correct attribute names in class
-# bodies
-class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
-
-# Regular expression which should only match correct list comprehension /
-# generator expression variable names
-inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,j,k,ex,Run,_
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,bar,baz,toto,tutu,tata
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=__.*__
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-
-[TYPECHECK]
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# List of classes names for which member attributes should not be checked
-# (useful for classes with attributes dynamically set).
-ignored-classes=SQLObject
-
-# When zope mode is activated, add a predefined set of Zope acquired attributes
-# to generated-members.
-zope=no
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E0201 when accessed. Python regular
-# expressions are accepted.
-generated-members=REQUEST,acl_users,aq_parent
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
-
-
-[SIMILARITIES]
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-
-[VARIABLES]
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# A regular expression matching the beginning of the name of dummy variables
-# (i.e. not used).
-dummy-variables-rgx=_$|dummy
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-
-[FORMAT]
-
-# Maximum number of characters on a single line.
-max-line-length=100
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )?<?https?://\S+>?$
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-# List of optional constructs for which whitespace checking is disabled
-no-space-check=trailing-comma,dict-separator
-
-# Maximum number of lines in a module
-max-module-lines=1000
-
-# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
-# tab).
-indent-string='  '
-
-
-[IMPORTS]
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=regsub,TERMIOS,Bastion,rexec
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=5
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=_.*
-
-# Maximum number of locals for function / method body
-max-locals=15
-
-# Maximum number of return / yield for function / method body
-max-returns=6
-
-# Maximum number of branch for function / method body
-max-branches=12
-
-# Maximum number of statements in function / method body
-max-statements=50
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=7
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=2
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-
-[CLASSES]
-
-# List of interface methods to ignore, separated by a comma. This is used for
-# instance to not check methods defines in Zope's Interface base class.
-ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,__new__,setUp
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=mcs
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
diff --git a/libc/tools/test_genseccomp.py b/libc/tools/test_genseccomp.py
index 0c2699a..812218e 100755
--- a/libc/tools/test_genseccomp.py
+++ b/libc/tools/test_genseccomp.py
@@ -29,20 +29,20 @@
 int         fchown:fchown(int, uid_t, gid_t)    arm64,x86_64
     """))
 
-    whitelist = cStringIO.StringIO(textwrap.dedent("""\
+    allowlist = cStringIO.StringIO(textwrap.dedent("""\
 ssize_t     read(int, void*, size_t)        all
     """))
 
     empty = cStringIO.StringIO(textwrap.dedent("""\
     """))
 
-    names = genseccomp.get_names([bionic, whitelist, empty], "arm")
+    names = genseccomp.get_names([bionic, allowlist, empty], "arm")
     bionic.seek(0)
-    whitelist.seek(0)
+    allowlist.seek(0)
     empty.seek(0)
-    names64 = genseccomp.get_names([bionic, whitelist, empty], "arm64")
+    names64 = genseccomp.get_names([bionic, allowlist, empty], "arm64")
     bionic.seek(0)
-    whitelist.seek(0)
+    allowlist.seek(0)
     empty.seek(0)
 
     self.assertIn("fchown", names64)
@@ -52,45 +52,45 @@
     self.assertIn("read", names)
     self.assertIn("read", names64)
 
-    # Blacklist item must be in bionic
-    blacklist = cStringIO.StringIO(textwrap.dedent("""\
+    # Blocklist item must be in bionic
+    blocklist = cStringIO.StringIO(textwrap.dedent("""\
 int         fchown2:fchown2(int, uid_t, gid_t)    arm64,x86_64
     """))
     with self.assertRaises(RuntimeError):
-      genseccomp.get_names([bionic, whitelist, blacklist], "arm")
+      genseccomp.get_names([bionic, allowlist, blocklist], "arm")
     bionic.seek(0)
-    whitelist.seek(0)
-    blacklist.seek(0)
+    allowlist.seek(0)
+    blocklist.seek(0)
 
-    # Test blacklist item is removed
-    blacklist = cStringIO.StringIO(textwrap.dedent("""\
+    # Test blocklist item is removed
+    blocklist = cStringIO.StringIO(textwrap.dedent("""\
 int         fchown:fchown(int, uid_t, gid_t)    arm64,x86_64
     """))
-    names = genseccomp.get_names([bionic, whitelist, blacklist], "arm64")
+    names = genseccomp.get_names([bionic, allowlist, blocklist], "arm64")
     bionic.seek(0)
-    whitelist.seek(0)
-    blacklist.seek(0)
+    allowlist.seek(0)
+    blocklist.seek(0)
     self.assertIn("read", names)
     self.assertNotIn("fchown", names)
 
-    # Blacklist item must not be in whitelist
-    whitelist = cStringIO.StringIO(textwrap.dedent("""\
+    # Blocklist item must not be in allowlist
+    allowlist = cStringIO.StringIO(textwrap.dedent("""\
 int         fchown:fchown(int, uid_t, gid_t)    arm64,x86_64
     """))
     with self.assertRaises(RuntimeError):
-      genseccomp.get_names([empty, whitelist, blacklist], "arm")
+      genseccomp.get_names([empty, allowlist, blocklist], "arm")
     empty.seek(0)
-    whitelist.seek(0)
-    blacklist.seek(0)
+    allowlist.seek(0)
+    blocklist.seek(0)
 
-    # No dups in bionic and whitelist
-    whitelist = cStringIO.StringIO(textwrap.dedent("""\
+    # No dups in bionic and allowlist
+    allowlist = cStringIO.StringIO(textwrap.dedent("""\
 int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) arm,x86
     """))
     with self.assertRaises(RuntimeError):
-      genseccomp.get_names([bionic, whitelist, empty], "arm")
+      genseccomp.get_names([bionic, allowlist, empty], "arm")
     bionic.seek(0)
-    whitelist.seek(0)
+    allowlist.seek(0)
     empty.seek(0)
 
   def test_convert_names_to_NRs(self):
@@ -186,14 +186,14 @@
     int         fchown:fchown(int, uid_t, gid_t)    arm64,x86_64
     """))
 
-    whitelist = cStringIO.StringIO(textwrap.dedent("""\
+    allowlist = cStringIO.StringIO(textwrap.dedent("""\
     ssize_t     read(int, void*, size_t)        all
     """))
 
-    blacklist = cStringIO.StringIO(textwrap.dedent("""\
+    blocklist = cStringIO.StringIO(textwrap.dedent("""\
     """))
 
-    syscall_files = [syscalls, whitelist, blacklist]
+    syscall_files = [syscalls, allowlist, blocklist]
     output = genseccomp.construct_bpf(syscall_files, "arm", self.get_headers("arm"),
                                       self.get_switches("arm"))
 
diff --git a/libc/tzcode/bionic.cpp b/libc/tzcode/bionic.cpp
index 6d84303..e134aaa 100644
--- a/libc/tzcode/bionic.cpp
+++ b/libc/tzcode/bionic.cpp
@@ -90,12 +90,12 @@
 // byte[12] tzdata_version  -- "tzdata2012f\0"
 // int index_offset
 // int data_offset
-// int zonetab_offset
+// int final_offset
 struct bionic_tzdata_header_t {
   char tzdata_version[12];
   int32_t index_offset;
   int32_t data_offset;
-  int32_t zonetab_offset;
+  int32_t final_offset;
 };
 static constexpr size_t NAME_LENGTH = 40;
 struct index_entry_t {
@@ -105,12 +105,18 @@
   int32_t unused; // Was raw GMT offset; always 0 since tzdata2014f (L).
 };
 
+// Returns -2 for a soft failure (where the caller should try another file),
+// -1 for a hard failure (where the caller should give up), and >= 0 is a
+// file descriptor whose offset points to the data for the given olson id in
+// the given file (and *entry_length is the size of the data).
 static int __bionic_open_tzdata_path(const char* path,
                                      const char* olson_id,
                                      int32_t* entry_length) {
   int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC));
   if (fd == -1) {
-    return -2; // Distinguish failure to find any data from failure to find a specific id.
+    // We don't log here, because this is quite common --- current devices
+    // aren't expected to have the old APK tzdata, for example.
+    return -2;
   }
 
   bionic_tzdata_header_t header = {};
@@ -119,49 +125,49 @@
     fprintf(stderr, "%s: could not read header of \"%s\": %s\n",
             __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
     close(fd);
-    return -1;
+    return -2;
   }
 
   if (strncmp(header.tzdata_version, "tzdata", 6) != 0 || header.tzdata_version[11] != 0) {
     fprintf(stderr, "%s: bad magic in \"%s\": \"%.6s\"\n", __FUNCTION__, path, header.tzdata_version);
     close(fd);
-    return -1;
+    return -2;
   }
 
   if (TEMP_FAILURE_RETRY(lseek(fd, ntohl(header.index_offset), SEEK_SET)) == -1) {
     fprintf(stderr, "%s: couldn't seek to index in \"%s\": %s\n", __FUNCTION__, path, strerror(errno));
     close(fd);
-    return -1;
+    return -2;
   }
 
   if (ntohl(header.index_offset) > ntohl(header.data_offset)) {
     fprintf(stderr, "%s: invalid data and index offsets in \"%s\": %u %u\n",
             __FUNCTION__, path, ntohl(header.data_offset), ntohl(header.index_offset));
     close(fd);
-    return -1;
+    return -2;
   }
   const size_t index_size = ntohl(header.data_offset) - ntohl(header.index_offset);
   if ((index_size % sizeof(index_entry_t)) != 0) {
     fprintf(stderr, "%s: invalid index size in \"%s\": %zd\n", __FUNCTION__, path, index_size);
     close(fd);
-    return -1;
+    return -2;
   }
 
-  off_t specific_zone_offset = -1;
   char* index = reinterpret_cast<char*>(malloc(index_size));
   if (index == nullptr) {
     fprintf(stderr, "%s: couldn't allocate %zd-byte index for \"%s\"\n", __FUNCTION__, index_size, path);
     close(fd);
-    return -1;
+    return -2;
   }
   if (TEMP_FAILURE_RETRY(read(fd, index, index_size)) != static_cast<ssize_t>(index_size)) {
     fprintf(stderr, "%s: could not read index of \"%s\": %s\n",
             __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
     free(index);
     close(fd);
-    return -1;
+    return -2;
   }
 
+  off_t specific_zone_offset = -1;
   size_t id_count = index_size / sizeof(index_entry_t);
   index_entry_t* entry = reinterpret_cast<index_entry_t*>(index);
   for (size_t i = 0; i < id_count; ++i) {
@@ -180,6 +186,9 @@
   free(index);
 
   if (specific_zone_offset == -1) {
+    // We found a valid tzdata file, but didn't find the requested id in it.
+    // Give up now, and don't try fallback tzdata files. We don't log here
+    // because for all we know the given olson id was nonsense.
     close(fd);
     return -1;
   }
@@ -188,11 +197,9 @@
     fprintf(stderr, "%s: could not seek to %ld in \"%s\": %s\n",
             __FUNCTION__, specific_zone_offset, path, strerror(errno));
     close(fd);
-    return -1;
+    return -2;
   }
 
-  // TODO: check that there's TZ_MAGIC at this offset, so we can fall back to the other file if not.
-
   return fd;
 }
 
@@ -204,8 +211,9 @@
   //    tried first because it allows us to test that the time zone updates
   //    via APK mechanism still works even on devices with the time zone
   //    module.
+  //    TODO: remove this when those devices are no longer supported.
   // 2: The time zone data module which contains the main copy. This is the
-  //    common case.
+  //    common case for current devices.
   // 3: The ultimate fallback: the non-updatable copy in /system.
 
 #if defined(__ANDROID__)
@@ -214,15 +222,15 @@
 
   fd = __bionic_open_tzdata_path("/data/misc/zoneinfo/current/tzdata",
                                  olson_id, entry_length);
-  if (fd >= 0) return fd;
+  if (fd >= -1) return fd;
 
   fd = __bionic_open_tzdata_path("/apex/com.android.tzdata/etc/tz/tzdata",
                                  olson_id, entry_length);
-  if (fd >= 0) return fd;
+  if (fd >= -1) return fd;
 
   fd = __bionic_open_tzdata_path("/system/usr/share/zoneinfo/tzdata",
                                  olson_id, entry_length);
-  if (fd >= 0) return fd;
+  if (fd >= -1) return fd;
 #else
   // On the host, we don't expect the hard-coded locations above to exist, and
   // we're not worried about security so we trust $ANDROID_DATA,
@@ -232,17 +240,17 @@
   char* path = make_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata");
   fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
   free(path);
-  if (fd >= 0) return fd;
+  if (fd >= -1) return fd;
 
   path = make_path("ANDROID_TZDATA_ROOT", "/etc/tz/tzdata");
   fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
   free(path);
-  if (fd >= 0) return fd;
+  if (fd >= -1) return fd;
 
   path = make_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata");
   fd = __bionic_open_tzdata_path(path, olson_id, entry_length);
   free(path);
-  if (fd >= 0) return fd;
+  if (fd >= -1) return fd;
 #endif
 
   // Not finding any tzdata is more serious that not finding a specific zone,
@@ -253,5 +261,6 @@
     fprintf(stderr, "%s: couldn't find any tzdata when looking for %s!\n", __FUNCTION__, olson_id);
   }
 
+  // Otherwise we were successful.
   return fd;
 }
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index 41eaa9b..7e8e234 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -95,9 +95,22 @@
     int century;
     int relyear;
 };
+
+static char gmt[] = { "GMT" };
+static char utc[] = { "UTC" };
+/* RFC-822/RFC-2822 */
+static const char * const nast[5] = {
+       "EST",    "CST",    "MST",    "PST",    "\0\0\0"
+};
+static const char * const nadt[5] = {
+       "EDT",    "CDT",    "MDT",    "PDT",    "\0\0\0"
+};
+
 static  int _conv_num(const unsigned char **, int *, int, int);
 static  unsigned char *_strptime(const unsigned char *, const char *, struct tm *,
         struct century_relyear *);
+static	const u_char *_find_string(const u_char *, int *, const char * const *,
+	    const char * const *, int);
 
 
 char *
@@ -113,9 +126,10 @@
 _strptime(const unsigned char *buf, const char *fmt, struct tm *tm, struct century_relyear *cr)
 {
     unsigned char c;
-    const unsigned char *bp;
+    const unsigned char *bp, *ep;
     size_t len = 0;
-    int alt_format, i;
+    int alt_format, i, offs;
+    int neg = 0;
 
     bp = (unsigned char *)buf;
     while ((c = *fmt) != '\0') {
@@ -432,6 +446,108 @@
                 return (NULL);
             break;
 
+		case 'Z':
+			tzset();
+			if (strncmp((const char *)bp, gmt, 3) == 0) {
+				tm->tm_isdst = 0;
+				tm->tm_gmtoff = 0;
+				tm->tm_zone = gmt;
+				bp += 3;
+			} else if (strncmp((const char *)bp, utc, 3) == 0) {
+				tm->tm_isdst = 0;
+				tm->tm_gmtoff = 0;
+				tm->tm_zone = utc;
+				bp += 3;
+			} else {
+				ep = _find_string(bp, &i,
+						 (const char * const *)tzname,
+						  NULL, 2);
+				if (ep == NULL)
+					return (NULL);
+
+				tm->tm_isdst = i;
+				tm->tm_gmtoff = -(timezone);
+				tm->tm_zone = tzname[i];
+				bp = ep;
+			}
+			continue;
+
+		case 'z':
+			/*
+			 * We recognize all ISO 8601 formats:
+			 * Z	= Zulu time/UTC
+			 * [+-]hhmm
+			 * [+-]hh:mm
+			 * [+-]hh
+			 * We recognize all RFC-822/RFC-2822 formats:
+			 * UT|GMT
+			 *          North American : UTC offsets
+			 * E[DS]T = Eastern : -4 | -5
+			 * C[DS]T = Central : -5 | -6
+			 * M[DS]T = Mountain: -6 | -7
+			 * P[DS]T = Pacific : -7 | -8
+			 */
+			while (isspace(*bp))
+				bp++;
+
+			switch (*bp++) {
+			case 'G':
+				if (*bp++ != 'M')
+					return NULL;
+				/*FALLTHROUGH*/
+			case 'U':
+				if (*bp++ != 'T')
+					return NULL;
+				/*FALLTHROUGH*/
+			case 'Z':
+				tm->tm_isdst = 0;
+				tm->tm_gmtoff = 0;
+				tm->tm_zone = utc;
+				continue;
+			case '+':
+				neg = 0;
+				break;
+			case '-':
+				neg = 1;
+				break;
+			default:
+				--bp;
+				ep = _find_string(bp, &i, nast, NULL, 4);
+				if (ep != NULL) {
+					tm->tm_gmtoff = (-5 - i) * SECSPERHOUR;
+					tm->tm_zone = (char *)nast[i];
+					bp = ep;
+					continue;
+				}
+				ep = _find_string(bp, &i, nadt, NULL, 4);
+				if (ep != NULL) {
+					tm->tm_isdst = 1;
+					tm->tm_gmtoff = (-4 - i) * SECSPERHOUR;
+					tm->tm_zone = (char *)nadt[i];
+					bp = ep;
+					continue;
+				}
+				return NULL;
+			}
+			if (!isdigit(bp[0]) || !isdigit(bp[1]))
+				return NULL;
+			offs = ((bp[0]-'0') * 10 + (bp[1]-'0')) * SECSPERHOUR;
+			bp += 2;
+			if (*bp == ':')
+				bp++;
+			if (isdigit(*bp)) {
+				offs += (*bp++ - '0') * 10 * SECSPERMIN;
+				if (!isdigit(*bp))
+					return NULL;
+				offs += (*bp++ - '0') * SECSPERMIN;
+			}
+			if (neg)
+				offs = -offs;
+			tm->tm_isdst = 0;	/* XXX */
+			tm->tm_gmtoff = offs;
+			tm->tm_zone = NULL;	/* XXX */
+			continue;
+
         /*
          * Miscellaneous conversions.
          */
@@ -468,28 +584,49 @@
     return (unsigned char*)bp;
 }
 
-
 static int
 _conv_num(const unsigned char **buf, int *dest, int llim, int ulim)
 {
-    int result = 0;
-    int rulim = ulim;
+	int result = 0;
+	int rulim = ulim;
 
-    if (**buf < '0' || **buf > '9')
-        return (0);
+	if (**buf < '0' || **buf > '9')
+		return (0);
 
-    /* we use rulim to break out of the loop when we run out of digits */
-    do {
-        result *= 10;
-        result += *(*buf)++ - '0';
-        rulim /= 10;
-    } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
+	/* we use rulim to break out of the loop when we run out of digits */
+	do {
+		result *= 10;
+		result += *(*buf)++ - '0';
+		rulim /= 10;
+	} while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
 
-    if (result < llim || result > ulim)
-        return (0);
+	if (result < llim || result > ulim)
+		return (0);
 
-    *dest = result;
-    return (1);
+	*dest = result;
+	return (1);
+}
+
+static const u_char *
+_find_string(const u_char *bp, int *tgt, const char * const *n1,
+		const char * const *n2, int c)
+{
+	int i;
+	unsigned int len;
+
+	/* check full name - then abbreviated ones */
+	for (; n1 != NULL; n1 = n2, n2 = NULL) {
+		for (i = 0; i < c; i++, n1++) {
+			len = strlen(*n1);
+			if (strncasecmp(*n1, (const char *)bp, len) == 0) {
+				*tgt = i;
+				return bp + len;
+			}
+		}
+	}
+
+	/* Nothing matched */
+	return NULL;
 }
 
 char* strptime_l(const char* buf, const char* fmt, struct tm* tm, locale_t l) {
diff --git a/libc/upstream-netbsd/lib/libc/gen/utmp.c b/libc/upstream-netbsd/lib/libc/gen/utmp.c
deleted file mode 100644
index 9fb0799..0000000
--- a/libc/upstream-netbsd/lib/libc/gen/utmp.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*	$NetBSD: utmp.c,v 1.10 2011/10/15 23:00:02 christos Exp $	 */
-
-/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Christos Zoulas.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
-
-#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: utmp.c,v 1.10 2011/10/15 23:00:02 christos Exp $");
-#endif /* LIBC_SCCS and not lint */
-
-#include "namespace.h"
-#include <sys/types.h>
-#include <sys/param.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <utmp.h>
-#include <sys/stat.h>
-
-static struct utmp utmp;
-static FILE *ut;
-static char utfile[MAXPATHLEN] = _PATH_UTMP;
-
-void
-setutent(void)
-{
-	if (ut == NULL)
-		return;
-	(void)fseeko(ut, (off_t)0, SEEK_SET);
-}
-
-struct utmp *
-getutent(void)
-{
-	if (ut == NULL) {
-		struct stat st;
-		off_t numentries;
-		if ((ut = fopen(utfile, "re")) == NULL)
-			return NULL;
-		if (fstat(fileno(ut), &st) == -1)
-			goto out;
-		/*
-		 * If we have a an old version utmp file bail.
-		 */
-		numentries = st.st_size / sizeof(utmp);
-		if ((off_t)(numentries * sizeof(utmp)) != st.st_size)
-			goto out;
-	}
-	if (fread(&utmp, sizeof(utmp), 1, ut) == 1)
-		return &utmp;
-out:
-	(void)fclose(ut);
-	return NULL;
-}
-
-void
-endutent(void)
-{
-	if (ut != NULL) {
-		(void)fclose(ut);
-		ut = NULL;
-	}
-}
-
-int
-utmpname(const char *fname)
-{
-	size_t len = strlen(fname);
-
-	if (len >= sizeof(utfile))
-		return 0;
-
-	/* must not end in x! */
-	if (fname[len - 1] == 'x')
-		return 0;
-
-	(void)strlcpy(utfile, fname, sizeof(utfile));
-	endutent();
-	return 1;
-}
diff --git a/libc/upstream-netbsd/lib/libc/stdlib/_rand48.c b/libc/upstream-netbsd/lib/libc/stdlib/_rand48.c
index 0468026..6e3e223 100644
--- a/libc/upstream-netbsd/lib/libc/stdlib/_rand48.c
+++ b/libc/upstream-netbsd/lib/libc/stdlib/_rand48.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: _rand48.c,v 1.7 2005/06/12 05:21:27 lukem Exp $	*/
+/*	$NetBSD: _rand48.c,v 1.10 2020/02/23 09:53:42 kamil Exp $	*/
 
 /*
  * Copyright (c) 1993 Martin Birgmeier
@@ -15,7 +15,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: _rand48.c,v 1.7 2005/06/12 05:21:27 lukem Exp $");
+__RCSID("$NetBSD: _rand48.c,v 1.10 2020/02/23 09:53:42 kamil Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 #include <assert.h>
@@ -42,15 +42,17 @@
 
 	_DIAGASSERT(xseed != NULL);
 
-	accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0] +
-	 (unsigned long) __rand48_add;
+	accu = (unsigned long) __rand48_mult[0] * (unsigned long) xseed[0];
+	accu += (unsigned long) __rand48_add;
 	temp[0] = (unsigned short) accu;	/* lower 16 bits */
 	accu >>= sizeof(unsigned short) * 8;
-	accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1] +
-	 (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
+	accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[1];
+	accu += (unsigned long) __rand48_mult[1] * (unsigned long) xseed[0];
 	temp[1] = (unsigned short) accu;	/* middle 16 bits */
 	accu >>= sizeof(unsigned short) * 8;
-	accu += __rand48_mult[0] * xseed[2] + __rand48_mult[1] * xseed[1] + __rand48_mult[2] * xseed[0];
+	accu += (unsigned long) __rand48_mult[0] * (unsigned long) xseed[2];
+	accu += (unsigned long) __rand48_mult[1] * (unsigned long) xseed[1];
+	accu += (unsigned long) __rand48_mult[2] * (unsigned long) xseed[0];
 	xseed[0] = temp[0];
 	xseed[1] = temp[1];
 	xseed[2] = (unsigned short) accu;
diff --git a/libc/upstream-openbsd/android/include/arc4random.h b/libc/upstream-openbsd/android/include/arc4random.h
index 5f0b15e..96f94be 100644
--- a/libc/upstream-openbsd/android/include/arc4random.h
+++ b/libc/upstream-openbsd/android/include/arc4random.h
@@ -36,14 +36,6 @@
 //#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
 //#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
 
-#ifdef __GLIBC__
-extern void *__dso_handle;
-extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
-#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
-#else
-#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
-#endif
-
 static inline void _getentropy_fail(void) {
     async_safe_fatal("getentropy failed: %s", strerror(errno));
 }
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 878f71c..2fc5046 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -38,6 +38,8 @@
 /* Ignore all __warn_references in OpenBSD. */
 #define __warn_references(sym,msg)
 
+#define PROTO_NORMAL(x)
+
 /* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
  * Additionally, we changed the numeric/digit type from N to D for libcxx.
  */
@@ -70,3 +72,7 @@
 
 __LIBC_HIDDEN__ extern char* __findenv(const char*, int, int*);
 __LIBC_HIDDEN__ extern char* _mktemp(char*);
+
+// Only OpenBSD has this at the moment, and we're more likely to just say
+// "malloc is always calloc", so we don't expose this as libc API.
+__LIBC_HIDDEN__ void* recallocarray(void*, size_t, size_t, size_t);
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h
index 9e1cea0..8d621b0 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoa.h
@@ -112,7 +112,18 @@
 extern float  strtof ANSI((CONST char *, char **));
 extern double strtod ANSI((CONST char *, char **));
 extern int __strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
+char	*__hdtoa(double, const char *, int, int *, int *, char **);
+char	*__hldtoa(long double, const char *, int, int *, int *, char **);
+char	*__ldtoa(long double *, int, int, int *, int *, char **);
 
+PROTO_NORMAL(__dtoa);
+PROTO_NORMAL(__gdtoa);
+PROTO_NORMAL(__freedtoa);
+PROTO_NORMAL(__hdtoa);
+PROTO_NORMAL(__hldtoa);
+PROTO_NORMAL(__ldtoa);
+
+__BEGIN_HIDDEN_DECLS
 extern char*	__g_ddfmt  ANSI((char*, double*, int, size_t));
 extern char*	__g_dfmt   ANSI((char*, double*, int, size_t));
 extern char*	__g_ffmt   ANSI((char*, float*,  int, size_t));
@@ -148,6 +159,7 @@
 #define __strtopx(s,se,x) strtorx(s,se,1,x)
 #define __strtopxL(s,se,x) strtorxL(s,se,1,x)
 #endif
+__END_HIDDEN_DECLS
 
 #ifdef __cplusplus
 }
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
index 0f3de12..823f2a9 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
@@ -463,7 +463,6 @@
 #define FREE_DTOA_LOCK(n)	/*nothing*/
 #else
 #include "thread_private.h"
-extern void *__dtoa_locks[];
 #define ACQUIRE_DTOA_LOCK(n)	_MUTEX_LOCK(&__dtoa_locks[n])
 #define FREE_DTOA_LOCK(n)	_MUTEX_UNLOCK(&__dtoa_locks[n])
 #endif
@@ -567,6 +566,7 @@
 #define trailz __trailz_D2A
 #define ulp __ulp_D2A
 
+__BEGIN_HIDDEN_DECLS
  extern char *dtoa_result;
  extern CONST double bigtens[], tens[], tinytens[];
  extern unsigned char hexdig[];
@@ -586,8 +586,6 @@
  extern Bigint *d2b ANSI((double, int*, int*));
  extern void decrement ANSI((Bigint*));
  extern Bigint *diff ANSI((Bigint*, Bigint*));
- extern char *dtoa ANSI((double d, int mode, int ndigits,
-			int *decpt, int *sign, char **rve));
  extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t));
  extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
  extern void __hexdig_init_D2A(Void);
@@ -610,10 +608,10 @@
  extern Bigint *set_ones ANSI((Bigint*, int));
  extern char *strcp ANSI((char*, const char*));
  extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*));
- extern double strtod ANSI((const char *s00, char **se));
  extern Bigint *sum ANSI((Bigint*, Bigint*));
  extern int trailz ANSI((Bigint*));
  extern double ulp ANSI((U*));
+__END_HIDDEN_DECLS
 
 #ifdef __cplusplus
 }
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c b/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
index f521f15..d48c9ed 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gethex.c
@@ -57,11 +57,8 @@
 	static unsigned char *decimalpoint_cache;
 	if (!(s0 = decimalpoint_cache)) {
 		s0 = (unsigned char*)localeconv()->decimal_point;
-		if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
-			strlcpy(decimalpoint_cache, s0, strlen(s0) + 1);
-			s0 = decimalpoint_cache;
-			}
-		}
+		decimalpoint_cache = strdup(s0);
+	}
 	decimalpoint = s0;
 #endif
 #endif
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c b/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
index 45caef4..4a7f798 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/hdtoa.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: hdtoa.c,v 1.3 2015/09/14 12:49:33 guenther Exp $	*/
+/*	$OpenBSD: hdtoa.c,v 1.5 2020/05/31 12:27:19 mortimer Exp $	*/
 /*-
  * Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
@@ -112,7 +112,7 @@
  *
  * Note that the C99 standard does not specify what the leading digit
  * should be for non-zero numbers.  For instance, 0x1.3p3 is the same
- * as 0x2.6p2 is the same as 0x4.cp3.  This implementation chooses the
+ * as 0x2.6p2 is the same as 0x4.cp1.  This implementation chooses the
  * first digit so that subsequent digits are aligned on nibble
  * boundaries (before rounding).
  *
@@ -225,6 +225,7 @@
 	struct ieee_ext *p = (struct ieee_ext *)&e;
 	char *s, *s0;
 	int bufsize;
+	int fbits = 0;
 
 	*sign = p->ext_sign;
 
@@ -273,23 +274,24 @@
 	 */
 	for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--)
 		*s = 0;
-	for (; s > s0 + sigfigs - (EXT_FRACLBITS / 4) - 1 && s > s0; s--) {
+
+	for (fbits = EXT_FRACLBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
 		*s = p->ext_fracl & 0xf;
 		p->ext_fracl >>= 4;
 	}
-#ifdef EXT_FRACHMBITS
-	for (; s > s0; s--) {
-		*s = p->ext_frachm & 0xf;
-		p->ext_frachm >>= 4;
-	}
-#endif
 #ifdef EXT_FRACLMBITS
-	for (; s > s0; s--) {
+	for (fbits = EXT_FRACLMBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
 		*s = p->ext_fraclm & 0xf;
 		p->ext_fraclm >>= 4;
 	}
 #endif
-	for (; s > s0; s--) {
+#ifdef EXT_FRACHMBITS
+	for (fbits = EXT_FRACHMBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
+		*s = p->ext_frachm & 0xf;
+		p->ext_frachm >>= 4;
+	}
+#endif
+	for (fbits = EXT_FRACHBITS / 4; fbits > 0 && s > s0; s--, fbits--) {
 		*s = p->ext_frach & 0xf;
 		p->ext_frach >>= 4;
 	}
@@ -300,7 +302,7 @@
 	 * (partial) nibble, which is dealt with by the next
 	 * statement.  We also tack on the implicit normalization bit.
 	 */
-	*s = p->ext_frach | (1U << ((LDBL_MANT_DIG - 1) % 4));
+	*s = (p->ext_frach | (1U << ((LDBL_MANT_DIG - 1) % 4))) & 0xf;
 
 	/* If ndigits < 0, we are expected to auto-size the precision. */
 	if (ndigits < 0) {
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
index b149f07..79a3104 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/misc.c
@@ -40,6 +40,10 @@
 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
 #endif
 
+#ifdef MULTIPLE_THREADS
+extern void *__dtoa_locks[];
+#endif
+
  Bigint *
 Balloc
 #ifdef KR_headers
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c b/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
index ac2283c..0fb37fd 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/strtod.c
@@ -114,10 +114,7 @@
 	static int dplen;
 	if (!(s0 = decimalpoint_cache)) {
 		s0 = localeconv()->decimal_point;
-		if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
-			strlcpy(decimalpoint_cache, s0, strlen(s0) + 1);
-			s0 = decimalpoint_cache;
-			}
+		decimalpoint_cache = strdup(s0);
 		dplen = strlen(s0);
 		}
 	decimalpoint = (char*)s0;
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c b/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c
index 753f6bf..defb474 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/strtodg.c
@@ -363,10 +363,7 @@
 	static int dplen;
 	if (!(s0 = decimalpoint_cache)) {
 		s0 = localeconv()->decimal_point;
-		if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
-			strlcpy(decimalpoint_cache, s0, strlen(s0) + 1);
-			s0 = decimalpoint_cache;
-			}
+		decimalpoint_cache = strdup(s0);
 		dplen = strlen(s0);
 		}
 	decimalpoint = (char*)s0;
diff --git a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
index 0d0f18f..d7afd5f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
+++ b/libc/upstream-openbsd/lib/libc/gen/fnmatch.c
@@ -1,8 +1,8 @@
-/*	$OpenBSD: fnmatch.c,v 1.19 2015/08/01 18:11:08 millert Exp $	*/
+/*	$OpenBSD: fnmatch.c,v 1.22 2020/03/13 03:25:45 djm Exp $	*/
 
 /* Copyright (c) 2011, VMware, Inc.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *     * Redistributions of source code must retain the above copyright
@@ -13,7 +13,7 @@
  *     * Neither the name of the VMware, Inc. nor the names of its contributors
  *       may be used to endorse or promote products derived from this software
  *       without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -27,7 +27,7 @@
  */
 
 /*
- * Copyright (c) 2008 Todd C. Miller <millert@openbsd.org>
+ * Copyright (c) 2008, 2016 Todd C. Miller <millert@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -51,9 +51,9 @@
  * Filename pattern matches defined in section 2.13, "Pattern Matching Notation"
  * from chapter 2. "Shell Command Language"
  *   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
- * where; 1. A bracket expression starting with an unquoted <circumflex> '^' 
- * character CONTINUES to specify a non-matching list; 2. an explicit <period> '.' 
- * in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading 
+ * where; 1. A bracket expression starting with an unquoted <circumflex> '^'
+ * character CONTINUES to specify a non-matching list; 2. an explicit <period> '.'
+ * in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading
  * <period> in a filename; 3. a <left-square-bracket> '[' which does not introduce
  * a valid bracket expression is treated as an ordinary character; 4. a differing
  * number of consecutive slashes within pattern and string will NOT match;
@@ -62,10 +62,10 @@
  * Bracket expansion defined in section 9.3.5, "RE Bracket Expression",
  * from chapter 9, "Regular Expressions"
  *   http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
- * with no support for collating symbols, equivalence class expressions or 
- * character class expressions.  A partial range expression with a leading 
+ * with no support for collating symbols, equivalence class expressions or
+ * character class expressions.  A partial range expression with a leading
  * hyphen following a valid range expression will match only the ordinary
- * <hyphen> and the ending character (e.g. "[a-m-z]" will match characters 
+ * <hyphen> and the ending character (e.g. "[a-m-z]" will match characters
  * 'a' through 'm', a <hyphen> '-', or a 'z').
  *
  * Supports BSD extensions FNM_LEADING_DIR to match pattern to the end of one
@@ -98,22 +98,21 @@
 static int
 classmatch(const char *pattern, char test, int foldcase, const char **ep)
 {
-	struct cclass *cc;
-	const char *colon;
-	size_t len;
-	int rval = RANGE_NOMATCH;
 	const char * const mismatch = pattern;
+	const char *colon;
+	struct cclass *cc;
+	int rval = RANGE_NOMATCH;
+	size_t len;
 
-	if (*pattern != '[' || pattern[1] != ':') {
+	if (pattern[0] != '[' || pattern[1] != ':') {
 		*ep = mismatch;
-		return(RANGE_ERROR);
+		return RANGE_ERROR;
 	}
-
 	pattern += 2;
 
 	if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') {
 		*ep = mismatch;
-		return(RANGE_ERROR);
+		return RANGE_ERROR;
 	}
 	*ep = colon + 2;
 	len = (size_t)(colon - pattern);
@@ -132,11 +131,11 @@
 		*ep = mismatch;
 		rval = RANGE_ERROR;
 	}
-	return(rval);
+	return rval;
 }
 
 /* Most MBCS/collation/case issues handled here.  Wildcard '*' is not handled.
- * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over, 
+ * EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over,
  * however the "\/" sequence is advanced to '/'.
  *
  * Both pattern and string are **char to support pointer increment of arbitrary
@@ -144,341 +143,347 @@
  */
 static int fnmatch_ch(const char **pattern, const char **string, int flags)
 {
-    const char * const mismatch = *pattern;
-    const int nocase = !!(flags & FNM_CASEFOLD);
-    const int escape = !(flags & FNM_NOESCAPE);
-    const int slash = !!(flags & FNM_PATHNAME);
-    int result = FNM_NOMATCH;
-    const char *startch;
-    int negate;
+	const char * const mismatch = *pattern;
+	const int nocase = !!(flags & FNM_CASEFOLD);
+	const int escape = !(flags & FNM_NOESCAPE);
+	const int slash = !!(flags & FNM_PATHNAME);
+	int result = FNM_NOMATCH;
+	const char *startch;
+	int negate;
 
-    if (**pattern == '[')
-    {
-        ++*pattern;
+	if (**pattern == '[') {
+		++*pattern;
 
-        /* Handle negation, either leading ! or ^ operators (never both) */
-        negate = ((**pattern == '!') || (**pattern == '^'));
-        if (negate)
-            ++*pattern;
+		/* Handle negation, either leading ! or ^ operators */
+		negate = (**pattern == '!') || (**pattern == '^');
+		if (negate)
+			++*pattern;
 
-        /* ']' is an ordinary character at the start of the range pattern */
-        if (**pattern == ']')
-            goto leadingclosebrace;
+		/* ']' is an ordinary char at the start of the range pattern */
+		if (**pattern == ']')
+			goto leadingclosebrace;
 
-        while (**pattern)
-        {
-            if (**pattern == ']') {
-                ++*pattern;
-                /* XXX: Fix for MBCS character width */
-                ++*string;
-                return (result ^ negate);
-            }
+		while (**pattern) {
+			if (**pattern == ']') {
+				++*pattern;
+				/* XXX: Fix for MBCS character width */
+				++*string;
+				return (result ^ negate);
+			}
 
-            if (escape && (**pattern == '\\')) {
-                ++*pattern;
+			if (escape && (**pattern == '\\')) {
+				++*pattern;
 
-                /* Patterns must be terminated with ']', not EOS */
-                if (!**pattern)
-                    break;
-            }
+				/* Patterns must terminate with ']', not EOS */
+				if (!**pattern)
+					break;
+			}
 
-            /* Patterns must be terminated with ']' not '/' */
-            if (slash && (**pattern == '/'))
-                break;
+			/* Patterns must terminate with ']' not '/' */
+			if (slash && (**pattern == '/'))
+				break;
 
-            /* Match character classes. */
-            if (classmatch(*pattern, **string, nocase, pattern)
-                == RANGE_MATCH) {
-                result = 0;
-                continue;
-            }
-            if (!**pattern)
-                break;
+			/* Match character classes. */
+			switch (classmatch(*pattern, **string, nocase, pattern)) {
+			case RANGE_MATCH:
+				result = 0;
+				continue;
+			case RANGE_NOMATCH:
+				/* Valid character class but no match. */
+				continue;
+			default:
+				/* Not a valid character class. */
+				break;
+			}
+			if (!**pattern)
+				break;
 
 leadingclosebrace:
-            /* Look at only well-formed range patterns; 
-             * "x-]" is not allowed unless escaped ("x-\]")
-             * XXX: Fix for locale/MBCS character width
-             */
-            if (((*pattern)[1] == '-') && ((*pattern)[2] != ']'))
-            {
-                startch = *pattern;
-                *pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2;
+			/* Look at only well-formed range patterns;
+			 * "x-]" is not allowed unless escaped ("x-\]")
+			 * XXX: Fix for locale/MBCS character width
+			 */
+			if (((*pattern)[1] == '-') && ((*pattern)[2] != ']')) {
+				startch = *pattern;
+				*pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2;
 
-                /* NOT a properly balanced [expr] pattern, EOS terminated 
-                 * or ranges containing a slash in FNM_PATHNAME mode pattern
-                 * fall out to to the rewind and test '[' literal code path
-                 */
-                if (!**pattern || (slash && (**pattern == '/')))
-                    break;
+				/*
+				 * NOT a properly balanced [expr] pattern, EOS
+				 * terminated or ranges containing a slash in
+				 * FNM_PATHNAME mode pattern fall out to to the
+				 * rewind and test '[' literal code path.
+				 */
+				if (!**pattern || (slash && (**pattern == '/')))
+					break;
 
-                /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
-                if ((**string >= *startch) && (**string <= **pattern))
-                    result = 0;
-                else if (nocase && (isupper((unsigned char)**string) ||
-			    isupper((unsigned char)*startch) ||
-                            isupper((unsigned char)**pattern))
-                            && (tolower((unsigned char)**string) >=
-			        tolower((unsigned char)*startch)) 
-                            && (tolower((unsigned char)**string) <=
-				tolower((unsigned char)**pattern)))
-                    result = 0;
+				/* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+				if ((**string >= *startch) && (**string <= **pattern))
+					result = 0;
+				else if (nocase &&
+				    (isupper((unsigned char)**string) ||
+				     isupper((unsigned char)*startch) ||
+				     isupper((unsigned char)**pattern)) &&
+				    (tolower((unsigned char)**string) >=
+				     tolower((unsigned char)*startch)) &&
+				    (tolower((unsigned char)**string) <=
+				     tolower((unsigned char)**pattern)))
+					result = 0;
 
-                ++*pattern;
-                continue;
-            }
+				++*pattern;
+				continue;
+			}
 
-            /* XXX: handle locale/MBCS comparison, advance by MBCS char width */
-            if ((**string == **pattern))
-                result = 0;
-            else if (nocase && (isupper((unsigned char)**string) ||
-			    isupper((unsigned char)**pattern))
-                            && (tolower((unsigned char)**string) ==
-				tolower((unsigned char)**pattern)))
-                result = 0;
+			/* XXX: handle locale/MBCS comparison, advance by MBCS char width */
+			if ((**string == **pattern))
+				result = 0;
+			else if (nocase && (isupper((unsigned char)**string) ||
+			    isupper((unsigned char)**pattern)) &&
+			    (tolower((unsigned char)**string) ==
+			    tolower((unsigned char)**pattern)))
+				result = 0;
 
-            ++*pattern;
-        }
+			++*pattern;
+		}
+		/*
+		 * NOT a properly balanced [expr] pattern;
+		 * Rewind and reset result to test '[' literal
+		 */
+		*pattern = mismatch;
+		result = FNM_NOMATCH;
+	} else if (**pattern == '?') {
+		/* Optimize '?' match before unescaping **pattern */
+		if (!**string || (slash && (**string == '/')))
+			return FNM_NOMATCH;
+		result = 0;
+		goto fnmatch_ch_success;
+	} else if (escape && (**pattern == '\\') && (*pattern)[1]) {
+		++*pattern;
+	}
 
-        /* NOT a properly balanced [expr] pattern; Rewind
-         * and reset result to test '[' literal
-         */
-        *pattern = mismatch;
-        result = FNM_NOMATCH;
-    }
-    else if (**pattern == '?') {
-        /* Optimize '?' match before unescaping **pattern */
-        if (!**string || (slash && (**string == '/')))
-            return FNM_NOMATCH;
-        result = 0;
-        goto fnmatch_ch_success;
-    }
-    else if (escape && (**pattern == '\\') && (*pattern)[1]) {
-        ++*pattern;
-    }
+	/* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
+	if (**string == **pattern)
+		result = 0;
+	else if (nocase && (isupper((unsigned char)**string) ||
+	    isupper((unsigned char)**pattern)) &&
+	    (tolower((unsigned char)**string) ==
+	    tolower((unsigned char)**pattern)))
+		result = 0;
 
-    /* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
-    if (**string == **pattern)
-        result = 0;
-    else if (nocase && (isupper((unsigned char)**string) ||
-		    isupper((unsigned char)**pattern))
-                    && (tolower((unsigned char)**string) ==
-			tolower((unsigned char)**pattern)))
-        result = 0;
-
-    /* Refuse to advance over trailing slash or nulls
-     */
-    if (!**string || !**pattern || (slash && ((**string == '/') || (**pattern == '/'))))
-        return result;
+	/* Refuse to advance over trailing slash or NULs */
+	if (**string == '\0' || **pattern == '\0' ||
+	    (slash && ((**string == '/') || (**pattern == '/'))))
+		return result;
 
 fnmatch_ch_success:
-    ++*pattern;
-    ++*string;
-    return result;
+	++*pattern;
+	++*string;
+	return result;
 }
 
 
 int fnmatch(const char *pattern, const char *string, int flags)
 {
-    static const char dummystring[2] = {' ', 0};
-    const int escape = !(flags & FNM_NOESCAPE);
-    const int slash = !!(flags & FNM_PATHNAME);
-    const int leading_dir = !!(flags & FNM_LEADING_DIR);
-    const char *strendseg;
-    const char *dummyptr;
-    const char *matchptr;
-    int wild;
-    /* For '*' wild processing only; surpress 'used before initialization'
-     * warnings with dummy initialization values;
-     */
-    const char *strstartseg = NULL;
-    const char *mismatch = NULL;
-    int matchlen = 0;
+	static const char dummystring[2] = {' ', 0};
+	const int escape = !(flags & FNM_NOESCAPE);
+	const int slash = !!(flags & FNM_PATHNAME);
+	const int leading_dir = !!(flags & FNM_LEADING_DIR);
+	const char *dummyptr, *matchptr, *strendseg;
+	int wild;
+	/* For '*' wild processing only; suppress 'used before initialization'
+	 * warnings with dummy initialization values;
+	 */
+	const char *strstartseg = NULL;
+	const char *mismatch = NULL;
+	int matchlen = 0;
 
-    if (*pattern == '*')
-        goto firstsegment;
+	if (*pattern == '*')
+		goto firstsegment;
 
-    while (*pattern && *string)
-    {
-        /* Pre-decode "\/" which has no special significance, and
-         * match balanced slashes, starting a new segment pattern
-         */
-        if (slash && escape && (*pattern == '\\') && (pattern[1] == '/'))
-            ++pattern;
-        if (slash && (*pattern == '/') && (*string == '/')) {
-            ++pattern;
-            ++string;
-        }            
+	while (*pattern && *string) {
+		/*
+		 * Pre-decode "\/" which has no special significance, and
+		 * match balanced slashes, starting a new segment pattern.
+		 */
+		if (slash && escape && (*pattern == '\\') && (pattern[1] == '/'))
+			++pattern;
+		if (slash && (*pattern == '/') && (*string == '/')) {
+			++pattern;
+			++string;
+		}
 
 firstsegment:
-        /* At the beginning of each segment, validate leading period behavior.
-         */
-        if ((flags & FNM_PERIOD) && (*string == '.'))
-        {
-            if (*pattern == '.')
-                ++pattern;
-            else if (escape && (*pattern == '\\') && (pattern[1] == '.'))
-                pattern += 2;
-            else
-                return FNM_NOMATCH;
-            ++string;
-        }
+		/*
+		 * At the beginning of each segment, validate leading period
+		 * behavior.
+		 */
+		if ((flags & FNM_PERIOD) && (*string == '.')) {
+		    if (*pattern == '.')
+			    ++pattern;
+		    else if (escape && (*pattern == '\\') && (pattern[1] == '.'))
+			    pattern += 2;
+		    else
+			    return FNM_NOMATCH;
+		    ++string;
+		}
 
-        /* Determine the end of string segment
-         *
-         * Presumes '/' character is unique, not composite in any MBCS encoding
-         */
-        if (slash) {
-            strendseg = strchr(string, '/');
-            if (!strendseg)
-                strendseg = strchr(string, '\0');
-        }
-        else {
-            strendseg = strchr(string, '\0');
-        }
+		/*
+		 * Determine the end of string segment.  Presumes '/'
+		 * character is unique, not composite in any MBCS encoding
+		 */
+		if (slash) {
+			strendseg = strchr(string, '/');
+			if (!strendseg)
+				strendseg = strchr(string, '\0');
+		} else {
+			strendseg = strchr(string, '\0');
+		}
 
-        /* Allow pattern '*' to be consumed even with no remaining string to match
-         */
-        while (*pattern)
-        {
-            if ((string > strendseg)
-                || ((string == strendseg) && (*pattern != '*')))
-                break;
+		/*
+		 * Allow pattern '*' to be consumed even with no remaining
+		 * string to match.
+		 */
+		while (*pattern) {
+			if ((string > strendseg) ||
+			    ((string == strendseg) && (*pattern != '*')))
+				break;
 
-            if (slash && ((*pattern == '/')
-                           || (escape && (*pattern == '\\')
-                                      && (pattern[1] == '/'))))
-                break;
+			if (slash && ((*pattern == '/') ||
+			    (escape && (*pattern == '\\') && (pattern[1] == '/'))))
+				break;
 
-            /* Reduce groups of '*' and '?' to n '?' matches
-             * followed by one '*' test for simplicity
-             */
-            for (wild = 0; ((*pattern == '*') || (*pattern == '?')); ++pattern)
-            {
-                if (*pattern == '*') {
-                    wild = 1;
-                }
-                else if (string < strendseg) {  /* && (*pattern == '?') */
-                    /* XXX: Advance 1 char for MBCS locale */
-                    ++string;
-                }
-                else {  /* (string >= strendseg) && (*pattern == '?') */
-                    return FNM_NOMATCH;
-                }
-            }
+			/*
+			 * Reduce groups of '*' and '?' to n '?' matches
+			 * followed by one '*' test for simplicity.
+			 */
+			for (wild = 0; (*pattern == '*') || (*pattern == '?'); ++pattern) {
+				if (*pattern == '*') {
+					wild = 1;
+				} else if (string < strendseg) {  /* && (*pattern == '?') */
+					/* XXX: Advance 1 char for MBCS locale */
+					++string;
+				}
+				else {  /* (string >= strendseg) && (*pattern == '?') */
+					return FNM_NOMATCH;
+				}
+			}
 
-            if (wild)
-            {
-                strstartseg = string;
-                mismatch = pattern;
+			if (wild) {
+				strstartseg = string;
+				mismatch = pattern;
 
-                /* Count fixed (non '*') char matches remaining in pattern
-                 * excluding '/' (or "\/") and '*'
-                 */
-                for (matchptr = pattern, matchlen = 0; 1; ++matchlen)
-                {
-                    if ((*matchptr == '\0') 
-                        || (slash && ((*matchptr == '/')
-                                      || (escape && (*matchptr == '\\')
-                                                 && (matchptr[1] == '/')))))
-                    {
-                        /* Compare precisely this many trailing string chars,
-                         * the resulting match needs no wildcard loop
-                         */
-                        /* XXX: Adjust for MBCS */
-                        if (string + matchlen > strendseg)
-                            return FNM_NOMATCH;
+				/*
+				 * Count fixed (non '*') char matches remaining
+				 * in pattern * excluding '/' (or "\/") and '*'.
+				 */
+				for (matchptr = pattern, matchlen = 0; 1; ++matchlen) {
+					if ((*matchptr == '\0') ||
+					    (slash && ((*matchptr == '/') ||
+					    (escape && (*matchptr == '\\') &&
+					    (matchptr[1] == '/'))))) {
+						/* Compare precisely this many
+						 * trailing string chars, the
+						 * resulting match needs no
+						 * wildcard loop.
+						 */
+						/* XXX: Adjust for MBCS */
+						if (string + matchlen > strendseg)
+							return FNM_NOMATCH;
 
-                        string = strendseg - matchlen;
-                        wild = 0;
-                        break;
-                    }
+						string = strendseg - matchlen;
+						wild = 0;
+						break;
+					}
 
-                    if (*matchptr == '*')
-                    {
-                        /* Ensure at least this many trailing string chars remain
-                         * for the first comparison
-                         */
-                        /* XXX: Adjust for MBCS */
-                        if (string + matchlen > strendseg)
-                            return FNM_NOMATCH;
+					if (*matchptr == '*') {
+						/*
+						 * Ensure at least this many
+						 * trailing string chars remain
+						 * for the first comparison.
+						 */
+						/* XXX: Adjust for MBCS */
+						if (string + matchlen > strendseg)
+							return FNM_NOMATCH;
 
-                        /* Begin first wild comparison at the current position */
-                        break;
-                    }
+						/*
+						 * Begin first wild comparison
+						 * at the current position.
+						 */
+						break;
+					}
 
-                    /* Skip forward in pattern by a single character match
-                     * Use a dummy fnmatch_ch() test to count one "[range]" escape
-                     */ 
-                    /* XXX: Adjust for MBCS */
-                    if (escape && (*matchptr == '\\') && matchptr[1]) {
-                        matchptr += 2;
-                    }
-                    else if (*matchptr == '[') {
-                        dummyptr = dummystring;
-                        fnmatch_ch(&matchptr, &dummyptr, flags);
-                    }
-                    else {
-                        ++matchptr;
-                    }
-                }
-            }
+					/*
+					 * Skip forward in pattern by a single
+					 * character match Use a dummy
+					 * fnmatch_ch() test to count one
+					 * "[range]" escape.
+					 */
+					/* XXX: Adjust for MBCS */
+					if (escape && (*matchptr == '\\') &&
+					    matchptr[1]) {
+						matchptr += 2;
+					} else if (*matchptr == '[') {
+						dummyptr = dummystring;
+						fnmatch_ch(&matchptr, &dummyptr,
+						    flags);
+					} else {
+						++matchptr;
+					}
+				}
+			}
 
-            /* Incrementally match string against the pattern
-             */
-            while (*pattern && (string < strendseg))
-            {
-                /* Success; begin a new wild pattern search
-                 */
-                if (*pattern == '*')
-                    break;
+			/* Incrementally match string against the pattern. */
+			while (*pattern && (string < strendseg)) {
+				/* Success; begin a new wild pattern search. */
+				if (*pattern == '*')
+					break;
 
-                if (slash && ((*string == '/')
-                              || (*pattern == '/')
-                              || (escape && (*pattern == '\\')
-                                         && (pattern[1] == '/'))))
-                    break;
+				if (slash && ((*string == '/') ||
+				    (*pattern == '/') || (escape &&
+				    (*pattern == '\\') && (pattern[1] == '/'))))
+					break;
 
-                /* Compare ch's (the pattern is advanced over "\/" to the '/',
-                 * but slashes will mismatch, and are not consumed)
-                 */
-                if (!fnmatch_ch(&pattern, &string, flags))
-                    continue;
+				/*
+				 * Compare ch's (the pattern is advanced over
+				 * "\/" to the '/', but slashes will mismatch,
+				 * and are not consumed).
+				 */
+				if (!fnmatch_ch(&pattern, &string, flags))
+					continue;
 
-                /* Failed to match, loop against next char offset of string segment 
-                 * until not enough string chars remain to match the fixed pattern
-                 */
-                if (wild) {
-                    /* XXX: Advance 1 char for MBCS locale */
-                    string = ++strstartseg;
-                    if (string + matchlen > strendseg)
-                        return FNM_NOMATCH;
+				/*
+				 * Failed to match, loop against next char
+				 * offset of string segment until not enough
+				 * string chars remain to match the fixed
+				 * pattern.
+				 */
+				if (wild) {
+					/* XXX: Advance 1 char for MBCS locale */
+					string = ++strstartseg;
+					if (string + matchlen > strendseg)
+						return FNM_NOMATCH;
 
-                    pattern = mismatch;
-                    continue;
-                }
-                else
-                    return FNM_NOMATCH;
-            }
-        }
+					pattern = mismatch;
+					continue;
+				} else
+					return FNM_NOMATCH;
+			}
+		}
 
-        if (*string && !((slash || leading_dir) && (*string == '/')))
-            return FNM_NOMATCH;
+		if (*string && !((slash || leading_dir) && (*string == '/')))
+			return FNM_NOMATCH;
 
-        if (*pattern && !(slash && ((*pattern == '/')
-                                    || (escape && (*pattern == '\\')
-                                               && (pattern[1] == '/')))))
-            return FNM_NOMATCH;
+		if (*pattern && !(slash && ((*pattern == '/') ||
+		    (escape && (*pattern == '\\') && (pattern[1] == '/')))))
+			return FNM_NOMATCH;
 
-        if (leading_dir && !*pattern && *string == '/')
-            return 0;
-    }
+		if (leading_dir && !*pattern && *string == '/')
+			return 0;
+	}
 
-    /* Where both pattern and string are at EOS, declare success
-     */
-    if (!*string && !*pattern)
-        return 0;
+	/* Where both pattern and string are at EOS, declare success.  */
+	if (!*string && !*pattern)
+		return 0;
 
-    /* pattern didn't match to the end of string */
-    return FNM_NOMATCH;
+	/* Pattern didn't match to the end of string. */
+	return FNM_NOMATCH;
 }
diff --git a/libc/upstream-openbsd/lib/libc/locale/mbtowc.c b/libc/upstream-openbsd/lib/libc/locale/mbtowc.c
index 920f4bf..4399ed8 100644
--- a/libc/upstream-openbsd/lib/libc/locale/mbtowc.c
+++ b/libc/upstream-openbsd/lib/libc/locale/mbtowc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: mbtowc.c,v 1.2 2012/12/05 23:20:00 deraadt Exp $ */
+/*	$OpenBSD: mbtowc.c,v 1.3 2016/02/27 14:02:13 schwarze Exp $ */
 
 /*-
  * Copyright (c) 2002-2004 Tim J. Robbins.
@@ -44,7 +44,14 @@
 		return (0);
 	}
 	rval = mbrtowc(pwc, s, n, &mbs);
-	if (rval == (size_t)-1 || rval == (size_t)-2)
-		return (-1);
-	return ((int)rval);
+
+	switch (rval) {
+	case (size_t)-2:
+		errno = EILSEQ;
+		/* FALLTHROUGH */
+	case (size_t)-1:
+		return -1;
+	default:
+		return (int)rval;
+	}
 }
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fgetln.c b/libc/upstream-openbsd/lib/libc/stdio/fgetln.c
index 1109cf2..903dbd6 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fgetln.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fgetln.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fgetln.c,v 1.13 2015/01/05 21:58:52 millert Exp $ */
+/*	$OpenBSD: fgetln.c,v 1.17 2017/03/17 14:53:08 deraadt Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -46,7 +46,7 @@
 
 	if (fp->_lb._size >= newsize)
 		return (0);
-	if ((p = realloc(fp->_lb._base, newsize)) == NULL)
+	if ((p = recallocarray(fp->_lb._base, fp->_lb._size, newsize, 1)) == NULL)
 		return (-1);
 	fp->_lb._base = p;
 	fp->_lb._size = newsize;
@@ -76,7 +76,7 @@
 		goto error;
 
 	/* look for a newline in the input */
-	if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
+	if ((p = memchr(fp->_p, '\n', fp->_r)) != NULL) {
 		/*
 		 * Found one.  Flag buffer as modified to keep fseek from
 		 * `optimising' a backward seek, in case the user stomps on
@@ -112,12 +112,14 @@
 		 */
 		if (__slbexpand(fp, len + OPTIMISTIC))
 			goto error;
-		(void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
-		    len - off);
+		(void)memcpy(fp->_lb._base + off, fp->_p, len - off);
 		off = len;
-		if (__srefill(fp))
-			break;	/* EOF or error: return partial line */
-		if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
+		if (__srefill(fp)) {
+			if (fp->_flags & __SEOF)
+				break;
+			goto error;
+		}
+		if ((p = memchr(fp->_p, '\n', fp->_r)) == NULL)
 			continue;
 
 		/* got it: finish up the line (like code above) */
@@ -126,8 +128,7 @@
 		len += diff;
 		if (__slbexpand(fp, len))
 			goto error;
-		(void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
-		    diff);
+		(void)memcpy(fp->_lb._base + off, fp->_p, diff);
 		fp->_r -= diff;
 		fp->_p = p;
 		break;
@@ -142,3 +143,4 @@
 	*lenp = 0;
 	return (NULL);
 }
+DEF_WEAK(fgetln);
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fputwc.c b/libc/upstream-openbsd/lib/libc/stdio/fputwc.c
index 829c22c..e156922 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fputwc.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fputwc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fputwc.c,v 1.6 2015/10/01 02:32:07 guenther Exp $	*/
+/*	$OpenBSD: fputwc.c,v 1.7 2016/01/26 13:57:02 schwarze Exp $	*/
 /* $NetBSD: fputwc.c,v 1.3 2003/03/07 07:11:37 tshiozak Exp $ */
 
 /*-
@@ -62,7 +62,7 @@
 
 	size = wcrtomb(buf, wc, st);
 	if (size == (size_t)-1) {
-		errno = EILSEQ;
+		fp->_flags |= __SERR;
 		return WEOF;
 	}
 
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c
index 1088991..ba58f9d 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fvwrite.c,v 1.17 2009/11/09 00:18:27 kurt Exp $ */
+/*	$OpenBSD: fvwrite.c,v 1.20 2017/03/17 16:06:33 millert Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -35,6 +35,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <unistd.h>
 #include "local.h"
 #include "fvwrite.h"
 
@@ -63,7 +64,7 @@
 	}
 
 #define	MIN(a, b) ((a) < (b) ? (a) : (b))
-#define	COPY(n)	  (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
+#define	COPY(n)	  (void)memcpy(fp->_p, p, n)
 
 	iov = uio->uio_iov;
 	p = iov->iov_base;
@@ -105,15 +106,14 @@
 			if ((fp->_flags & (__SALC | __SSTR)) ==
 			    (__SALC | __SSTR) && fp->_w < len) {
 				size_t blen = fp->_p - fp->_bf._base;
+				int pgmsk = getpagesize() - 1;
 				unsigned char *_base;
 				int _size;
 
-				/* Allocate space exponentially. */
-				_size = fp->_bf._size;
-				do {
-					_size = (_size << 1) + 1;
-				} while (_size < blen + len);
-				_base = realloc(fp->_bf._base, _size + 1);
+				/* Round up to nearest page. */
+				_size = ((blen + len + 1 + pgmsk) & ~pgmsk) - 1;
+				_base = recallocarray(fp->_bf._base,
+				    fp->_bf._size + 1, _size + 1, 1);
 				if (_base == NULL)
 					goto err;
 				fp->_w += _size - fp->_bf._size;
@@ -164,7 +164,7 @@
 		do {
 			GETIOV(nlknown = 0);
 			if (!nlknown) {
-				nl = memchr((void *)p, '\n', len);
+				nl = memchr(p, '\n', len);
 				nldist = nl ? nl + 1 - p : len + 1;
 				nlknown = 1;
 			}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fwide.c b/libc/upstream-openbsd/lib/libc/stdio/fwide.c
index 27ca0f8..4b93d59 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fwide.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fwide.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fwide.c,v 1.5 2015/08/31 02:53:57 guenther Exp $	*/
+/*	$OpenBSD: fwide.c,v 1.6 2019/12/03 05:03:37 asou Exp $	*/
 /* $NetBSD: fwide.c,v 1.2 2003/01/18 11:29:54 thorpej Exp $ */
 
 /*-
@@ -51,8 +51,10 @@
 
 	FLOCKFILE(fp);
 	wcio = WCIO_GET(fp);
-	if (!wcio)
+	if (!wcio) {
+		FUNLOCKFILE(fp);
 		return 0; /* XXX */
+	}
 
 	if (wcio->wcio_mode == 0 && mode != 0)
 		wcio->wcio_mode = mode;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/getdelim.c b/libc/upstream-openbsd/lib/libc/stdio/getdelim.c
index 58ff0a1..d709a3d 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/getdelim.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/getdelim.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: getdelim.c,v 1.4 2015/08/31 02:53:57 guenther Exp $	*/
+/*	$OpenBSD: getdelim.c,v 1.6 2017/04/13 18:36:51 brynet Exp $	*/
 /* $NetBSD: getdelim.c,v 1.13 2011/07/22 23:12:30 joerg Exp $ */
 
 /*
@@ -73,7 +73,7 @@
 		}
 
 		/* Scan through looking for the separator */
-		p = memchr(fp->_p, sep, (size_t)fp->_r);
+		p = memchr(fp->_p, sep, fp->_r);
 		if (p == NULL)
 			len = fp->_r;
 		else
@@ -103,7 +103,7 @@
 				newlen++;
 			}
 
-			newb = realloc(*buf, newlen);
+			newb = recallocarray(*buf, *buflen, newlen, 1);
 			if (newb == NULL)
 				goto error;
 			*buf = newb;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
index f708acc..6ee5a5c 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_memstream.c,v 1.6 2015/08/31 02:53:57 guenther Exp $	*/
+/*	$OpenBSD: open_memstream.c,v 1.8 2019/05/02 08:30:10 yasuoka Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -50,7 +50,7 @@
 
 		if (sz < end + 1)
 			sz = end + 1;
-		p = realloc(st->string, sz);
+		p = recallocarray(st->string, st->size, sz, 1);
 		if (!p)
 			return (-1);
 		bzero(p + st->size, sz - st->size);
@@ -76,7 +76,7 @@
 memstream_seek(void *v, fpos_t off, int whence)
 {
 	struct state	*st = v;
-	ssize_t		 base = 0;
+	size_t		 base = 0;
 
 	switch (whence) {
 	case SEEK_SET:
@@ -89,7 +89,7 @@
 		break;
 	}
 
-	if (off > SIZE_MAX - base || off < -base) {
+	if ((off > 0 && off > SIZE_MAX - base) || (off < 0 && base < -off)) {
 		errno = EOVERFLOW;
 		return (-1);
 	}
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c
index 98cdb45..c2e17e7 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vasprintf.c
@@ -1,7 +1,7 @@
-/*	$OpenBSD: vasprintf.c,v 1.19 2015/12/28 22:08:18 mmcc Exp $	*/
+/*	$OpenBSD: vasprintf.c,v 1.23 2019/01/25 00:19:25 millert Exp $	*/
 
 /*
- * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1997 Todd C. Miller <millert@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -20,31 +20,40 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <unistd.h>
 #include "local.h"
 
+#define	INITIAL_SIZE	128
+
 int
 vasprintf(char **str, const char *fmt, __va_list ap)
 {
 	int ret;
 	FILE f;
 	struct __sfileext fext;
-	unsigned char *_base;
+	const int pgsz = getpagesize();
 
 	_FILEEXT_SETUP(&f, &fext);
 	f._file = -1;
 	f._flags = __SWR | __SSTR | __SALC;
-	f._bf._base = f._p = malloc(128);
+	f._bf._base = f._p = malloc(INITIAL_SIZE);
 	if (f._bf._base == NULL)
 		goto err;
-	f._bf._size = f._w = 127;		/* Leave room for the NUL */
+	f._bf._size = f._w = INITIAL_SIZE - 1;	/* leave room for the NUL */
 	ret = __vfprintf(&f, fmt, ap);
 	if (ret == -1)
 		goto err;
 	*f._p = '\0';
-	_base = realloc(f._bf._base, ret + 1);
-	if (_base == NULL)
-		goto err;
-	*str = (char *)_base;
+	if (ret + 1 > INITIAL_SIZE && ret + 1 < pgsz / 2) {
+		/* midsize allocations can try to conserve memory */
+		unsigned char *_base = recallocarray(f._bf._base,
+		    f._bf._size + 1, ret + 1, 1);
+
+		if (_base == NULL)
+			goto err;
+		*str = (char *)_base;
+	} else
+		*str = (char *)f._bf._base;
 	return (ret);
 
 err:
diff --git a/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c b/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c
index e76fcd4..ad4ab0a 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/vdprintf.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: vdprintf.c,v 1.2 2015/08/31 02:53:57 guenther Exp $	*/
+/*	$OpenBSD: vdprintf.c,v 1.3 2019/03/03 16:41:41 semarie Exp $	*/
 /*	$FreeBSD: src/lib/libc/stdio/vdprintf.c,v 1.4 2012/11/17 01:49:40 svnexp Exp $ */
 
 /*-
@@ -69,6 +69,6 @@
 	if ((ret = __vfprintf(&f, fmt, ap)) < 0)
 		return ret;
 
-	return fflush(&f) ? EOF : ret;
+	return __sflush(&f) ? EOF : ret;
 }
 DEF_WEAK(vdprintf);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c b/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c
new file mode 100644
index 0000000..a2f37fe
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/stdlib/recallocarray.c
@@ -0,0 +1,81 @@
+/*	$OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $	*/
+/*
+ * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
+{
+	size_t oldsize, newsize;
+	void *newptr;
+
+	if (ptr == NULL)
+		return calloc(newnmemb, size);
+
+	if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    newnmemb > 0 && SIZE_MAX / newnmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	newsize = newnmemb * size;
+
+	if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
+		errno = EINVAL;
+		return NULL;
+	}
+	oldsize = oldnmemb * size;
+	
+	/*
+	 * Don't bother too much if we're shrinking just a bit,
+	 * we do not shrink for series of small steps, oh well.
+	 */
+	if (newsize <= oldsize) {
+		size_t d = oldsize - newsize;
+
+		if (d < oldsize / 2 && d < getpagesize()) {
+			memset((char *)ptr + newsize, 0, d);
+			return ptr;
+		}
+	}
+
+	newptr = malloc(newsize);
+	if (newptr == NULL)
+		return NULL;
+
+	if (newsize > oldsize) {
+		memcpy(newptr, ptr, oldsize);
+		memset((char *)newptr + oldsize, 0, newsize - oldsize);
+	} else
+		memcpy(newptr, ptr, newsize);
+
+	explicit_bzero(ptr, oldsize);
+	free(ptr);
+
+	return newptr;
+}
+DEF_WEAK(recallocarray);
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
index e55a1fe..15c550b 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: setenv.c,v 1.16 2015/09/13 08:31:47 guenther Exp $ */
+/*	$OpenBSD: setenv.c,v 1.19 2016/09/21 04:38:56 guenther Exp $ */
 /*
  * Copyright (c) 1987 Regents of the University of California.
  * All rights reserved.
@@ -32,7 +32,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-extern char **environ;
 static char **lastenv;				/* last value of environ */
 
 /*
@@ -44,7 +43,7 @@
 putenv(char *str)
 {
 	char **P, *cp;
-	size_t cnt;
+	size_t cnt = 0;
 	int offset = 0;
 
 	for (cp = str; *cp && *cp != '='; ++cp)
@@ -66,13 +65,15 @@
 	}
 
 	/* create new slot for string */
-	for (P = environ; *P != NULL; P++)
-		;
-	cnt = P - environ;
+	if (environ != NULL) {
+		for (P = environ; *P != NULL; P++)
+			;
+		cnt = P - environ;
+	}
 	P = reallocarray(lastenv, cnt + 2, sizeof(char *));
 	if (!P)
 		return (-1);
-	if (lastenv != environ)
+	if (lastenv != environ && environ != NULL)
 		memcpy(P, environ, cnt * sizeof(char *));
 	lastenv = environ = P;
 	environ[cnt] = str;
@@ -123,22 +124,24 @@
 					break;
 		}
 	} else {					/* create new slot */
-		size_t cnt;
+		size_t cnt = 0;
 
-		for (P = environ; *P != NULL; P++)
-			;
-		cnt = P - environ;
+		if (environ != NULL) {
+			for (P = environ; *P != NULL; P++)
+				;
+			cnt = P - environ;
+		}
 		P = reallocarray(lastenv, cnt + 2, sizeof(char *));
 		if (!P)
 			return (-1);
-		if (lastenv != environ)
+		if (lastenv != environ && environ != NULL)
 			memcpy(P, environ, cnt * sizeof(char *));
 		lastenv = environ = P;
 		offset = cnt;
 		environ[cnt + 1] = NULL;
 	}
 	if (!(environ[offset] =			/* name + `=' + value */
-	    malloc((size_t)((int)(np - name) + l_value + 2))))
+	    malloc((int)(np - name) + l_value + 2)))
 		return (-1);
 	for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
 		;
diff --git a/libc/upstream-openbsd/lib/libc/string/memmem.c b/libc/upstream-openbsd/lib/libc/string/memmem.c
new file mode 100644
index 0000000..3b180b4
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/string/memmem.c
@@ -0,0 +1,184 @@
+/*	$OpenBSD: memmem.c,v 1.5 2020/04/16 12:39:28 claudio Exp $ */
+
+/*
+ * Copyright (c) 2005-2020 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+static char *
+twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
+	for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
+		if (hw == nw) return (char *)h-2;
+	return hw == nw ? (char *)h-2 : 0;
+}
+
+static char *
+threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
+	for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
+		if (hw == nw) return (char *)h-3;
+	return hw == nw ? (char *)h-3 : 0;
+}
+
+static char *
+fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
+{
+	uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
+	uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
+	for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
+		if (hw == nw) return (char *)h-4;
+	return hw == nw ? (char *)h-4 : 0;
+}
+
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#define BITOP(a,b,op) \
+ ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
+
+/*
+ * Maxime Crochemore and Dominique Perrin, Two-way string-matching,
+ * Journal of the ACM, 38(3):651-675, July 1991.
+ */
+static char *
+twoway_memmem(const unsigned char *h, const unsigned char *z,
+    const unsigned char *n, size_t l)
+{
+	size_t i, ip, jp, k, p, ms, p0, mem, mem0;
+	size_t byteset[32 / sizeof(size_t)] = { 0 };
+	size_t shift[256];
+
+	/* Computing length of needle and fill shift table */
+	for (i=0; i<l; i++)
+		BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
+
+	/* Compute maximal suffix */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] > n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	ms = ip;
+	p0 = p;
+
+	/* And with the opposite comparison */
+	ip = -1; jp = 0; k = p = 1;
+	while (jp+k<l) {
+		if (n[ip+k] == n[jp+k]) {
+			if (k == p) {
+				jp += p;
+				k = 1;
+			} else k++;
+		} else if (n[ip+k] < n[jp+k]) {
+			jp += k;
+			k = 1;
+			p = jp - ip;
+		} else {
+			ip = jp++;
+			k = p = 1;
+		}
+	}
+	if (ip+1 > ms+1) ms = ip;
+	else p = p0;
+
+	/* Periodic needle? */
+	if (memcmp(n, n+p, ms+1)) {
+		mem0 = 0;
+		p = MAX(ms, l-ms-1) + 1;
+	} else mem0 = l-p;
+	mem = 0;
+
+	/* Search loop */
+	for (;;) {
+		/* If remainder of haystack is shorter than needle, done */
+		if (z-h < l) return 0;
+
+		/* Check last byte first; advance by shift on mismatch */
+		if (BITOP(byteset, h[l-1], &)) {
+			k = l-shift[h[l-1]];
+			if (k) {
+				if (k < mem) k = mem;
+				h += k;
+				mem = 0;
+				continue;
+			}
+		} else {
+			h += l;
+			mem = 0;
+			continue;
+		}
+
+		/* Compare right half */
+		for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
+		if (k < l) {
+			h += k-ms;
+			mem = 0;
+			continue;
+		}
+		/* Compare left half */
+		for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
+		if (k <= mem) return (char *)h;
+		h += p;
+		mem = mem0;
+	}
+}
+
+void *
+memmem(const void *h0, size_t k, const void *n0, size_t l)
+{
+	const unsigned char *h = h0, *n = n0;
+
+	/* Return immediately on empty needle */
+	if (!l) return (void *)h;
+
+	/* Return immediately when needle is longer than haystack */
+	if (k<l) return 0;
+
+	/* Use faster algorithms for short needles */
+	h = memchr(h0, *n, k);
+	if (!h || l==1) return (void *)h;
+	k -= h - (const unsigned char *)h0;
+	if (k<l) return 0;
+	if (l==2) return twobyte_memmem(h, k, n);
+	if (l==3) return threebyte_memmem(h, k, n);
+	if (l==4) return fourbyte_memmem(h, k, n);
+
+	return twoway_memmem(h, h+k, n, l);
+}
+DEF_WEAK(memmem);
diff --git a/libc/upstream-openbsd/lib/libc/string/strstr.c b/libc/upstream-openbsd/lib/libc/string/strstr.c
index 079d69d..241a080 100644
--- a/libc/upstream-openbsd/lib/libc/string/strstr.c
+++ b/libc/upstream-openbsd/lib/libc/string/strstr.c
@@ -1,7 +1,7 @@
-/*	$OpenBSD: strstr.c,v 1.8 2018/04/30 07:44:56 denis Exp $ */
+/*	$OpenBSD: strstr.c,v 1.9 2020/04/16 12:37:52 claudio Exp $ */
 
 /*
- * Copyright (c) 2005-2014 Rich Felker
+ * Copyright (c) 2005-2018 Rich Felker
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -24,13 +24,8 @@
  */
 
 #include <string.h>
-#include <stdlib.h>
 #include <stdint.h>
 
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
 static char *
 twobyte_strstr(const unsigned char *h, const unsigned char *n)
 {
@@ -146,11 +141,8 @@
 		/* Check last byte first; advance by shift on mismatch */
 		if (BITOP(byteset, h[l-1], &)) {
 			k = l-shift[h[l-1]];
-#ifdef DEBUG
-			printf("adv by %zu (on %c) at [%s] (%zu;l=%zu)\n", k, h[l-1], h, shift[h[l-1]], l);
-#endif
 			if (k) {
-				if (mem0 && mem && k < p) k = l-p;
+				if (k < mem) k = mem;
 				h += k;
 				mem = 0;
 				continue;
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 8e3a3fc..6a3a82e 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -25,6 +25,8 @@
 
     stl: "none",
     system_shared_libs: [],
+    header_libs: ["libc_headers"],
+    export_header_lib_headers: ["libc_headers"],
 
     sanitize: {
         never: true,
@@ -97,6 +99,7 @@
 
     nocrt: true,
     system_shared_libs: [],
+    header_libs: ["libc_headers"],
 
     // Opt out of native_coverage when opting out of system_shared_libs
     native_coverage: false,
@@ -175,6 +178,7 @@
 
     nocrt: true,
     system_shared_libs: [],
+    header_libs: ["libc_headers"],
 
     // Opt out of native_coverage when opting out of system_shared_libs
     native_coverage: false,
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index d371577..898bc43 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -57,7 +57,10 @@
 
 // Backtraces for the first 4k file descriptors ought to be enough to diagnose an fd leak.
 static constexpr size_t kFdTableSize = 4096;
-static constexpr size_t kStackDepth = 10;
+
+// 32 frames, plus two to skip from fdtrack itself.
+static constexpr size_t kStackDepth = 34;
+static constexpr size_t kStackFrameSkip = 2;
 
 static bool installed = false;
 static std::array<FdEntry, kFdTableSize> stack_traces [[clang::no_destroy]];
@@ -134,15 +137,14 @@
       continue;
     }
 
-    constexpr size_t frame_skip = 2;
-    for (size_t i = frame_skip; i < entry->backtrace.size(); ++i) {
-      size_t j = i - frame_skip;
+    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;
     }
 
-    bool should_continue =
-        callback(fd, function_names, function_offsets, entry->backtrace.size() - frame_skip, arg);
+    bool should_continue = callback(fd, function_names, function_offsets,
+                                    entry->backtrace.size() - kStackFrameSkip, arg);
 
     entry->mutex.unlock();
 
diff --git a/libm/Android.bp b/libm/Android.bp
index 1c4fe55..6a348e1 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -1,5 +1,3 @@
-bionic_coverage = false
-
 //
 // libm.so and libm.a for target.
 //
@@ -488,7 +486,6 @@
     include_dirs: ["bionic/libc"],
     system_shared_libs: ["libc"],
 
-    native_coverage: bionic_coverage,
     sanitize: {
         address: false,
         fuzzer: false,
diff --git a/libm/x86/e_acos.S b/libm/x86/e_acos.S
index fa61853..04b1787 100644
--- a/libm/x86/e_acos.S
+++ b/libm/x86/e_acos.S
@@ -1925,5 +1925,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,6112
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/e_asin.S b/libm/x86/e_asin.S
index 5d7f331..6a3ff8e 100644
--- a/libm/x86/e_asin.S
+++ b/libm/x86/e_asin.S
@@ -1999,5 +1999,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,6096
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/e_atan2.S b/libm/x86/e_atan2.S
index 1efdf65..e491396 100644
--- a/libm/x86/e_atan2.S
+++ b/libm/x86/e_atan2.S
@@ -1217,5 +1217,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,3024
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/e_cosh.S b/libm/x86/e_cosh.S
index ecea8f4..567a9d0 100644
--- a/libm/x86/e_cosh.S
+++ b/libm/x86/e_cosh.S
@@ -1345,5 +1345,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,4256
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/e_hypot.S b/libm/x86/e_hypot.S
index 6a143e5..8422024 100644
--- a/libm/x86/e_hypot.S
+++ b/libm/x86/e_hypot.S
@@ -216,5 +216,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,32
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/e_log10.S b/libm/x86/e_log10.S
index 09b2952..473cea3 100644
--- a/libm/x86/e_log10.S
+++ b/libm/x86/e_log10.S
@@ -791,5 +791,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,2160
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/e_sinh.S b/libm/x86/e_sinh.S
index d6b04b5..b9a2930 100644
--- a/libm/x86/e_sinh.S
+++ b/libm/x86/e_sinh.S
@@ -1403,5 +1403,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,4280
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/libm_reduce_pi04l.S b/libm/x86/libm_reduce_pi04l.S
index af6a7d0..25976ea 100644
--- a/libm/x86/libm_reduce_pi04l.S
+++ b/libm/x86/libm_reduce_pi04l.S
@@ -3714,5 +3714,5 @@
 	.type	__4onpi_31l,@object
 	.size	__4onpi_31l,6444
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/libm_sincos_huge.S b/libm/x86/libm_sincos_huge.S
index b43d193..4601b87 100644
--- a/libm/x86/libm_sincos_huge.S
+++ b/libm/x86/libm_sincos_huge.S
@@ -664,5 +664,5 @@
 	.size	_ones,16
 	.data
 	.hidden __libm_reduce_pi04l
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/libm_tancot_huge.S b/libm/x86/libm_tancot_huge.S
index 80f16d5..cdaa820 100644
--- a/libm/x86/libm_tancot_huge.S
+++ b/libm/x86/libm_tancot_huge.S
@@ -746,5 +746,5 @@
 	.size	_GP,144
 	.data
 	.hidden __libm_reduce_pi04l
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_atan.S b/libm/x86/s_atan.S
index c4413f1..71ca4db 100644
--- a/libm/x86/s_atan.S
+++ b/libm/x86/s_atan.S
@@ -930,5 +930,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,2704
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_cbrt.S b/libm/x86/s_cbrt.S
index 0c98c99..53d3cc2 100644
--- a/libm/x86/s_cbrt.S
+++ b/libm/x86/s_cbrt.S
@@ -734,5 +734,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,2000
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_cos.S b/libm/x86/s_cos.S
index fd5ef5d..e47c63e 100644
--- a/libm/x86/s_cos.S
+++ b/libm/x86/s_cos.S
@@ -888,5 +888,5 @@
 	.size	static_const_table,2256
 	.data
 	.hidden __libm_sincos_huge
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_expm1.S b/libm/x86/s_expm1.S
index 1f9e87b..1816f59 100644
--- a/libm/x86/s_expm1.S
+++ b/libm/x86/s_expm1.S
@@ -698,5 +698,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,1296
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_log1p.S b/libm/x86/s_log1p.S
index 7a6d845..de7b87b 100644
--- a/libm/x86/s_log1p.S
+++ b/libm/x86/s_log1p.S
@@ -823,5 +823,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,2192
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_sin.S b/libm/x86/s_sin.S
index 1e6cbd4..74d1b86 100644
--- a/libm/x86/s_sin.S
+++ b/libm/x86/s_sin.S
@@ -903,5 +903,5 @@
 	.size	static_const_table,2288
 	.data
 	.hidden __libm_sincos_huge
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_tan.S b/libm/x86/s_tan.S
index 3ee2107..7935efe 100644
--- a/libm/x86/s_tan.S
+++ b/libm/x86/s_tan.S
@@ -1762,5 +1762,5 @@
 	.size	static_const_table,5872
 	.data
 	.hidden __libm_tancot_huge
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86/s_tanh.S b/libm/x86/s_tanh.S
index 737bcbb..777519f 100644
--- a/libm/x86/s_tanh.S
+++ b/libm/x86/s_tanh.S
@@ -1357,5 +1357,5 @@
 	.type	static_const_table,@object
 	.size	static_const_table,4280
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 # End
diff --git a/libm/x86_64/e_acos.S b/libm/x86_64/e_acos.S
index d83c66b..57c910e 100644
--- a/libm/x86_64/e_acos.S
+++ b/libm/x86_64/e_acos.S
@@ -1934,7 +1934,7 @@
 	.type	ONE_BY_2,@object
 	.size	ONE_BY_2,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/e_asin.S b/libm/x86_64/e_asin.S
index 9f41c7c..4242543 100644
--- a/libm/x86_64/e_asin.S
+++ b/libm/x86_64/e_asin.S
@@ -2013,7 +2013,7 @@
 	.type	cv,@object
 	.size	cv,24
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/e_atan2.S b/libm/x86_64/e_atan2.S
index f9baea9..f0ba43c 100644
--- a/libm/x86_64/e_atan2.S
+++ b/libm/x86_64/e_atan2.S
@@ -1219,7 +1219,7 @@
 	.type	EXPMASK,@object
 	.size	EXPMASK,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/e_cosh.S b/libm/x86_64/e_cosh.S
index 8cdbca6..97cb389 100644
--- a/libm/x86_64/e_cosh.S
+++ b/libm/x86_64/e_cosh.S
@@ -1349,7 +1349,7 @@
 	.type	ONEMASK,@object
 	.size	ONEMASK,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/e_hypot.S b/libm/x86_64/e_hypot.S
index 089b2b4..e46669f 100644
--- a/libm/x86_64/e_hypot.S
+++ b/libm/x86_64/e_hypot.S
@@ -191,7 +191,7 @@
 	.type	static_const_table,@object
 	.size	static_const_table,32
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/e_log10.S b/libm/x86_64/e_log10.S
index 4f43a36..86f86ce 100644
--- a/libm/x86_64/e_log10.S
+++ b/libm/x86_64/e_log10.S
@@ -784,7 +784,7 @@
 	.type	coeff,@object
 	.size	coeff,48
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/e_sinh.S b/libm/x86_64/e_sinh.S
index 4d8db63..d5f7b16 100644
--- a/libm/x86_64/e_sinh.S
+++ b/libm/x86_64/e_sinh.S
@@ -1407,7 +1407,7 @@
 	.type	HALFMASK,@object
 	.size	HALFMASK,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_atan.S b/libm/x86_64/s_atan.S
index 2453e10..d0e5d72 100644
--- a/libm/x86_64/s_atan.S
+++ b/libm/x86_64/s_atan.S
@@ -904,7 +904,7 @@
 	.type	SGNMASK,@object
 	.size	SGNMASK,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_cbrt.S b/libm/x86_64/s_cbrt.S
index 4aa4373..6b00f56 100644
--- a/libm/x86_64/s_cbrt.S
+++ b/libm/x86_64/s_cbrt.S
@@ -731,7 +731,7 @@
 	.type	NEG_INF,@object
 	.size	NEG_INF,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_cos.S b/libm/x86_64/s_cos.S
index ab5a0e1..3d9e402 100644
--- a/libm/x86_64/s_cos.S
+++ b/libm/x86_64/s_cos.S
@@ -1248,7 +1248,7 @@
 	.type	NEG_ZERO,@object
 	.size	NEG_ZERO,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_expm1.S b/libm/x86_64/s_expm1.S
index 9da1d9d..4b22f5a 100644
--- a/libm/x86_64/s_expm1.S
+++ b/libm/x86_64/s_expm1.S
@@ -704,7 +704,7 @@
 	.type	HIGHMASK,@object
 	.size	HIGHMASK,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_log1p.S b/libm/x86_64/s_log1p.S
index 1ff2d39..27fab74 100644
--- a/libm/x86_64/s_log1p.S
+++ b/libm/x86_64/s_log1p.S
@@ -806,7 +806,7 @@
 	.type	coeff2,@object
 	.size	coeff2,48
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_sin.S b/libm/x86_64/s_sin.S
index 2f93a34..fb54a2a 100644
--- a/libm/x86_64/s_sin.S
+++ b/libm/x86_64/s_sin.S
@@ -1273,7 +1273,7 @@
 	.type	NEG_ZERO,@object
 	.size	NEG_ZERO,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_tan.S b/libm/x86_64/s_tan.S
index 74cb044..4fa12e3 100644
--- a/libm/x86_64/s_tan.S
+++ b/libm/x86_64/s_tan.S
@@ -2212,7 +2212,7 @@
 	.type	NEG_ZERO,@object
 	.size	NEG_ZERO,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/libm/x86_64/s_tanh.S b/libm/x86_64/s_tanh.S
index 2c8f9bf..a76a5c2 100644
--- a/libm/x86_64/s_tanh.S
+++ b/libm/x86_64/s_tanh.S
@@ -1369,7 +1369,7 @@
 	.type	TWOMASK,@object
 	.size	TWOMASK,8
 	.data
-	.section .note.GNU-stack, ""
+	.section .note.GNU-stack, "",@progbits
 // -- Begin DWARF2 SEGMENT .eh_frame
 	.section .eh_frame,"a",@progbits
 .eh_frame_seg:
diff --git a/linker/Android.bp b/linker/Android.bp
index f75088d..08b2c7b 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -46,6 +46,8 @@
 
     prefix_symbols: "__dlwrap_",
 
+    header_libs: ["libc_headers"],
+
     // We need to access Bionic private headers in the linker.
     include_dirs: ["bionic/libc"],
 }
@@ -408,6 +410,7 @@
 
     nocrt: true,
     system_shared_libs: [],
+    header_libs: ["libc_headers"],
 
     // Opt out of native_coverage when opting out of system_shared_libs
     native_coverage: false,
diff --git a/linker/ld.config.format.md b/linker/ld.config.format.md
index f9fbcde..a16efa4 100644
--- a/linker/ld.config.format.md
+++ b/linker/ld.config.format.md
@@ -80,7 +80,9 @@
 namespace.ns.links = default
 namespace.ns.link.default.shared_libs = libc.so:libdl.so:libm.so:libstdc++.so
 
-# This defines what libraries are allowed to be loaded from ns1
+# [Deprecated] This defines what libraries are allowed to be loaded from ns1
 namespace.ns1.whitelisted = libsomething.so
+# This defines what libraries are allowed to be loaded from ns1
+namespace.ns1.allowed_libs = libsomething2.so
 ```
 
diff --git a/linker/linker.cpp b/linker/linker.cpp
index f241677..302e4b3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -186,10 +186,10 @@
   return false;
 }
 
-// TODO(dimitry): The grey-list is a workaround for http://b/26394120 ---
+// TODO(dimitry): The exempt-list is a workaround for http://b/26394120 ---
 // gradually remove libraries from this list until it is gone.
-static bool is_greylisted(android_namespace_t* ns, const char* name, const soinfo* needed_by) {
-  static const char* const kLibraryGreyList[] = {
+static bool is_exempt_lib(android_namespace_t* ns, const char* name, const soinfo* needed_by) {
+  static const char* const kLibraryExemptList[] = {
     "libandroid_runtime.so",
     "libbinder.so",
     "libcrypto.so",
@@ -206,13 +206,13 @@
     nullptr
   };
 
-  // If you're targeting N, you don't get the greylist.
-  if (g_greylist_disabled || get_application_target_sdk_version() >= 24) {
+  // If you're targeting N, you don't get the exempt-list.
+  if (get_application_target_sdk_version() >= 24) {
     return false;
   }
 
   // if the library needed by a system library - implicitly assume it
-  // is greylisted unless it is in the list of shared libraries for one or
+  // is exempt unless it is in the list of shared libraries for one or
   // more linked namespaces
   if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) {
     return !maybe_accessible_via_namespace_links(ns, name);
@@ -224,8 +224,8 @@
     name = basename(name);
   }
 
-  for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) {
-    if (strcmp(name, kLibraryGreyList[i]) == 0) {
+  for (size_t i = 0; kLibraryExemptList[i] != nullptr; ++i) {
+    if (strcmp(name, kLibraryExemptList[i]) == 0) {
       return true;
     }
   }
@@ -311,6 +311,10 @@
     }
   }
 
+  if (si->has_min_version(6) && si->get_gap_size()) {
+    munmap(reinterpret_cast<void*>(si->get_gap_start()), si->get_gap_size());
+  }
+
   TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si);
 
   if (!solist_remove_soinfo(si)) {
@@ -498,10 +502,10 @@
 
   static deleter_t deleter;
 
-  static LoadTask* create(const char* name,
-                          soinfo* needed_by,
-                          android_namespace_t* start_from,
-                          std::unordered_map<const soinfo*, ElfReader>* readers_map) {
+  // needed_by is NULL iff dlopen is called from memory that isn't part of any known soinfo.
+  static LoadTask* create(const char* _Nonnull name, soinfo* _Nullable needed_by,
+                          android_namespace_t* _Nonnull start_from,
+                          std::unordered_map<const soinfo*, ElfReader>* _Nonnull readers_map) {
     LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc();
     return new (ptr) LoadTask(name, needed_by, start_from, readers_map);
   }
@@ -563,6 +567,11 @@
     return start_from_;
   }
 
+  void remove_cached_elf_reader() {
+    CHECK(si_ != nullptr);
+    (*elf_readers_map_).erase(si_);
+  }
+
   const ElfReader& get_elf_reader() const {
     CHECK(si_ != nullptr);
     return (*elf_readers_map_)[si_];
@@ -594,6 +603,8 @@
     si_->load_bias = elf_reader.load_bias();
     si_->phnum = elf_reader.phdr_count();
     si_->phdr = elf_reader.loaded_phdr();
+    si_->set_gap_start(elf_reader.gap_start());
+    si_->set_gap_size(elf_reader.gap_size());
 
     return true;
   }
@@ -621,7 +632,7 @@
   bool close_fd_;
   off64_t file_offset_;
   std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_;
-  // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list)
+  // TODO(dimitry): needed by workaround for http://b/26394120 (the exempt-list)
   bool is_dt_needed_;
   // END OF WORKAROUND
   const android_namespace_t* const start_from_;
@@ -1001,47 +1012,24 @@
 
   // If the name contains a slash, we should attempt to open it directly and not search the paths.
   if (strchr(name, '/') != nullptr) {
-    int fd = -1;
-
-    if (strstr(name, kZipFileSeparator) != nullptr) {
-      fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath);
-    }
-
-    if (fd == -1) {
-      fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
-      if (fd != -1) {
-        *file_offset = 0;
-        if (!realpath_fd(fd, realpath)) {
-          if (!is_first_stage_init()) {
-            PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.",
-                  name);
-          }
-          *realpath = name;
-        }
-      }
-    }
-
-    return fd;
+    return open_library_at_path(zip_archive_cache, name, file_offset, realpath);
   }
 
-  // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path
+  // LD_LIBRARY_PATH has the highest priority. We don't have to check accessibility when searching
+  // the namespace's path lists, because anything found on a namespace path list should always be
+  // accessible.
   int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath);
+
+  // Try the DT_RUNPATH, and verify that the library is accessible.
   if (fd == -1 && needed_by != nullptr) {
     fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
-    // Check if the library is accessible
     if (fd != -1 && !ns->is_accessible(*realpath)) {
       close(fd);
       fd = -1;
     }
   }
 
-#if !defined(__ANDROID_APEX__)
-  if (fd == -1) {
-    std::vector<std::string> bootstrap_paths = { std::string(kSystemLibDir) + "/bootstrap" };
-    fd = open_library_on_paths(zip_archive_cache, name, file_offset, bootstrap_paths, realpath);
-  }
-#endif
-
+  // Finally search the namespace's main search path list.
   if (fd == -1) {
     fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath);
   }
@@ -1199,12 +1187,12 @@
   // do not check accessibility using realpath if fd is located on tmpfs
   // this enables use of memfd_create() for apps
   if ((fs_stat.f_type != TMPFS_MAGIC) && (!ns->is_accessible(realpath))) {
-    // TODO(dimitry): workaround for http://b/26394120 - the grey-list
+    // TODO(dimitry): workaround for http://b/26394120 - the exempt-list
 
     // TODO(dimitry) before O release: add a namespace attribute to have this enabled
     // only for classloader-namespaces
     const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr;
-    if (is_greylisted(ns, name, needed_by)) {
+    if (is_exempt_lib(ns, name, needed_by)) {
       // print warning only if needed by non-system library
       if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) {
         const soinfo* needed_or_dlopened_by = task->get_needed_by();
@@ -1243,16 +1231,14 @@
   }
 
   soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags);
-  if (si == nullptr) {
-    return false;
-  }
 
   task->set_soinfo(si);
 
   // Read the ELF header and some of the segments.
   if (!task->read(realpath.c_str(), file_stat.st_size)) {
-    soinfo_free(si);
+    task->remove_cached_elf_reader();
     task->set_soinfo(nullptr);
+    soinfo_free(si);
     return false;
   }
 
@@ -1298,14 +1284,13 @@
   soinfo* needed_by = task->get_needed_by();
   const android_dlextinfo* extinfo = task->get_extinfo();
 
-  off64_t file_offset;
-  std::string realpath;
   if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) {
-    file_offset = 0;
+    off64_t file_offset = 0;
     if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) {
       file_offset = extinfo->library_fd_offset;
     }
 
+    std::string realpath;
     if (!realpath_fd(extinfo->library_fd, &realpath)) {
       if (!is_first_stage_init()) {
         PRINT(
@@ -1323,10 +1308,12 @@
 
   LD_LOG(kLogDlopen,
          "load_library(ns=%s, task=%s, flags=0x%x, search_linked_namespaces=%d): calling "
-         "open_library with realpath=%s",
-         ns->get_name(), name, rtld_flags, search_linked_namespaces, realpath.c_str());
+         "open_library",
+         ns->get_name(), name, rtld_flags, search_linked_namespaces);
 
   // Open the file.
+  off64_t file_offset;
+  std::string realpath;
   int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath);
   if (fd == -1) {
     if (task->is_dt_needed()) {
@@ -1437,11 +1424,11 @@
                                   LoadTask* task,
                                   ZipArchiveCache* zip_archive_cache,
                                   LoadTaskList* load_tasks,
-                                  int rtld_flags,
-                                  bool search_linked_namespaces) {
+                                  int rtld_flags) {
   soinfo* candidate;
 
-  if (find_loaded_library_by_soname(ns, task->get_name(), search_linked_namespaces, &candidate)) {
+  if (find_loaded_library_by_soname(ns, task->get_name(), true /* search_linked_namespaces */,
+                                    &candidate)) {
     LD_LOG(kLogDlopen,
            "find_library_internal(ns=%s, task=%s): Already loaded (by soname): %s",
            ns->get_name(), task->get_name(), candidate->get_realpath());
@@ -1454,54 +1441,49 @@
   TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder... ]",
         task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate);
 
-  if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, search_linked_namespaces)) {
+  if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags,
+                   true /* search_linked_namespaces */)) {
     return true;
   }
 
-  // TODO(dimitry): workaround for http://b/26394120 (the grey-list)
-  if (ns->is_greylist_enabled() && is_greylisted(ns, task->get_name(), task->get_needed_by())) {
-    // For the libs in the greylist, switch to the default namespace and then
+  // TODO(dimitry): workaround for http://b/26394120 (the exempt-list)
+  if (ns->is_exempt_list_enabled() && is_exempt_lib(ns, task->get_name(), task->get_needed_by())) {
+    // For the libs in the exempt-list, switch to the default namespace and then
     // try the load again from there. The library could be loaded from the
     // default namespace or from another namespace (e.g. runtime) that is linked
     // from the default namespace.
     LD_LOG(kLogDlopen,
-           "find_library_internal(ns=%s, task=%s): Greylisted library - trying namespace %s",
+           "find_library_internal(ns=%s, task=%s): Exempt system library - trying namespace %s",
            ns->get_name(), task->get_name(), g_default_namespace.get_name());
     ns = &g_default_namespace;
     if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags,
-                     search_linked_namespaces)) {
+                     true /* search_linked_namespaces */)) {
       return true;
     }
   }
   // END OF WORKAROUND
 
-  if (search_linked_namespaces) {
-    // if a library was not found - look into linked namespaces
-    // preserve current dlerror in the case it fails.
-    DlErrorRestorer dlerror_restorer;
-    LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Trying %zu linked namespaces",
-           ns->get_name(), task->get_name(), ns->linked_namespaces().size());
-    for (auto& linked_namespace : ns->linked_namespaces()) {
-      if (find_library_in_linked_namespace(linked_namespace, task)) {
-        if (task->get_soinfo() == nullptr) {
-          // try to load the library - once namespace boundary is crossed
-          // we need to load a library within separate load_group
-          // to avoid using symbols from foreign namespace while.
-          //
-          // However, actual linking is deferred until when the global group
-          // is fully identified and is applied to all namespaces.
-          // Otherwise, the libs in the linked namespace won't get symbols from
-          // the global group.
-          if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) {
-            LD_LOG(
-                kLogDlopen, "find_library_internal(ns=%s, task=%s): Found in linked namespace %s",
-                ns->get_name(), task->get_name(), linked_namespace.linked_namespace()->get_name());
-            return true;
-          }
-        } else {
-          // lib is already loaded
-          return true;
-        }
+  // if a library was not found - look into linked namespaces
+  // preserve current dlerror in the case it fails.
+  DlErrorRestorer dlerror_restorer;
+  LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Trying %zu linked namespaces",
+         ns->get_name(), task->get_name(), ns->linked_namespaces().size());
+  for (auto& linked_namespace : ns->linked_namespaces()) {
+    if (find_library_in_linked_namespace(linked_namespace, task)) {
+      // Library is already loaded.
+      if (task->get_soinfo() != nullptr) {
+        // n.b. This code path runs when find_library_in_linked_namespace found an already-loaded
+        // library by soname. That should only be possible with a exempt-list lookup, where we
+        // switch the namespace, because otherwise, find_library_in_linked_namespace is duplicating
+        // the soname scan done in this function's first call to find_loaded_library_by_soname.
+        return true;
+      }
+
+      if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks,
+                       rtld_flags, false /* search_linked_namespaces */)) {
+        LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Found in linked namespace %s",
+               ns->get_name(), task->get_name(), linked_namespace.linked_namespace()->get_name());
+        return true;
       }
     }
   }
@@ -1538,7 +1520,6 @@
                     int rtld_flags,
                     const android_dlextinfo* extinfo,
                     bool add_as_children,
-                    bool search_linked_namespaces,
                     std::vector<android_namespace_t*>* namespaces) {
   // Step 0: prepare.
   std::unordered_map<const soinfo*, ElfReader> readers_map;
@@ -1594,8 +1575,7 @@
                                task,
                                &zip_archive_cache,
                                &load_tasks,
-                               rtld_flags,
-                               search_linked_namespaces || is_dt_needed)) {
+                               rtld_flags)) {
       return false;
     }
 
@@ -1837,8 +1817,7 @@
                              0,
                              rtld_flags,
                              extinfo,
-                             false /* add_as_children */,
-                             true /* search_linked_namespaces */)) {
+                             false /* add_as_children */)) {
     if (si != nullptr) {
       soinfo_unload(si);
     }
@@ -2404,6 +2383,21 @@
   }
 }
 
+std::vector<std::string> fix_lib_paths(std::vector<std::string> paths) {
+  // For the bootstrap linker, insert /system/${LIB}/bootstrap in front of /system/${LIB} in any
+  // namespace search path. The bootstrap linker should prefer to use the bootstrap bionic libraries
+  // (e.g. libc.so).
+#if !defined(__ANDROID_APEX__)
+  for (size_t i = 0; i < paths.size(); ++i) {
+    if (paths[i] == kSystemLibDir) {
+      paths.insert(paths.begin() + i, std::string(kSystemLibDir) + "/bootstrap");
+      ++i;
+    }
+  }
+#endif
+  return paths;
+}
+
 android_namespace_t* create_namespace(const void* caller_addr,
                                       const char* name,
                                       const char* ld_library_path,
@@ -2432,7 +2426,7 @@
   android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t();
   ns->set_name(name);
   ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0);
-  ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0);
+  ns->set_exempt_list_enabled((type & ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED) != 0);
   ns->set_also_used_as_anonymous((type & ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS) != 0);
 
   if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) {
@@ -3174,7 +3168,7 @@
   DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p",
         reinterpret_cast<void*>(base), strtab_, symtab_);
 
-  // Sanity checks.
+  // Validity checks.
   if (relocating_linker && needed_count != 0) {
     DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries");
     return false;
@@ -3259,9 +3253,8 @@
     // Fail if app is targeting M or above.
     int app_target_api_level = get_application_target_sdk_version();
     if (app_target_api_level >= 23) {
-      DL_ERR_AND_LOG("\"%s\" has text relocations (https://android.googlesource.com/platform/"
-                     "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-"
-                     "Enforced-for-API-level-23)", get_realpath());
+      DL_ERR_AND_LOG("\"%s\" has text relocations (%s#Text-Relocations-Enforced-for-API-level-23)",
+                     get_realpath(), kBionicChangesUrl);
       return false;
     }
     // Make segments writable to allow text relocations to work properly. We will later call
@@ -3385,6 +3378,22 @@
   return ld_config_file_vndk;
 }
 
+bool is_linker_config_expected(const char* executable_path) {
+  // Do not raise message from a host environment which is expected to miss generated linker
+  // configuration.
+#if !defined(__ANDROID__)
+  return false;
+#endif
+
+  if (strcmp(executable_path, "/system/bin/init") == 0) {
+    // Generated linker configuration can be missed from processes executed
+    // with init binary
+    return false;
+  }
+
+  return true;
+}
+
 static std::string get_ld_config_file_path(const char* executable_path) {
 #ifdef USE_LD_CONFIG_FILE
   // This is a debugging/testing only feature. Must not be available on
@@ -3411,10 +3420,11 @@
 
   if (file_exists(kLdGeneratedConfigFilePath)) {
     return kLdGeneratedConfigFilePath;
-  } else {
-    // TODO(b/146386369) : Adjust log level and add more condition to log only when necessary
-    INFO("Warning: failed to find generated linker configuration from \"%s\"",
-         kLdGeneratedConfigFilePath);
+  }
+
+  if (is_linker_config_expected(executable_path)) {
+    DL_WARN("Warning: failed to find generated linker configuration from \"%s\"",
+            kLdGeneratedConfigFilePath);
   }
 
   path = get_ld_config_file_vndk_path();
@@ -3490,7 +3500,7 @@
     ns->set_isolated(ns_config->isolated());
     ns->set_default_library_paths(ns_config->search_paths());
     ns->set_permitted_paths(ns_config->permitted_paths());
-    ns->set_whitelisted_libs(ns_config->whitelisted_libs());
+    ns->set_allowed_libs(ns_config->allowed_libs());
 
     namespaces[ns_config->name()] = ns;
     if (ns_config->visible()) {
diff --git a/linker/linker.h b/linker/linker.h
index 2da1404..3e851da 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -71,6 +71,10 @@
   DISALLOW_COPY_AND_ASSIGN(VersionTracker);
 };
 
+static constexpr const char* kBionicChangesUrl =
+    "https://android.googlesource.com/platform/bionic/+/master/"
+    "android-changes-for-ndk-developers.md";
+
 soinfo* get_libdl_info(const soinfo& linker_si);
 
 soinfo* find_containing_library(const void* p);
@@ -129,10 +133,10 @@
    */
   ANDROID_NAMESPACE_TYPE_SHARED = 2,
 
-  /* This flag instructs linker to enable grey-list workaround for the namespace.
+  /* This flag instructs linker to enable exempt-list workaround for the namespace.
    * See http://b/26394120 for details.
    */
-  ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+  ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED = 0x08000000,
 
   /* This flag instructs linker to use this namespace as the anonymous
    * namespace. There can be only one anonymous namespace in a process. If there
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index 1e2f9a2..5b68b1d 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -27,12 +27,15 @@
  */
 
 #include "linker_block_allocator.h"
+
 #include <inttypes.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <unistd.h>
 
+#include "linker_debug.h"
+
 static constexpr size_t kAllocateSize = PAGE_SIZE * 100;
 static_assert(kAllocateSize % PAGE_SIZE == 0, "Invalid kAllocateSize.");
 
@@ -88,16 +91,10 @@
   }
 
   LinkerBlockAllocatorPage* page = find_page(block);
-
-  if (page == nullptr) {
-    abort();
-  }
+  CHECK(page != nullptr);
 
   ssize_t offset = reinterpret_cast<uint8_t*>(block) - page->bytes;
-
-  if (offset % block_size_ != 0) {
-    abort();
-  }
+  CHECK((offset % block_size_) == 0);
 
   memset(block, 0, block_size_);
 
@@ -114,7 +111,7 @@
 void LinkerBlockAllocator::protect_all(int prot) {
   for (LinkerBlockAllocatorPage* page = page_list_; page != nullptr; page = page->next) {
     if (mprotect(page, kAllocateSize, prot) == -1) {
-      abort();
+      async_safe_fatal("mprotect(%p, %zu, %d) failed: %m", page, kAllocateSize, prot);
     }
   }
 }
@@ -125,10 +122,7 @@
 
   LinkerBlockAllocatorPage* page = reinterpret_cast<LinkerBlockAllocatorPage*>(
       mmap(nullptr, kAllocateSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0));
-
-  if (page == MAP_FAILED) {
-    abort(); // oom
-  }
+  CHECK(page != MAP_FAILED);
 
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, kAllocateSize, "linker_alloc");
 
@@ -143,9 +137,7 @@
 }
 
 LinkerBlockAllocatorPage* LinkerBlockAllocator::find_page(void* block) {
-  if (block == nullptr) {
-    abort();
-  }
+  CHECK(block != nullptr);
 
   LinkerBlockAllocatorPage* page = page_list_;
   while (page != nullptr) {
@@ -157,7 +149,7 @@
     page = page->next;
   }
 
-  abort();
+  async_safe_fatal("couldn't find page for %p", block);
 }
 
 void LinkerBlockAllocator::purge() {
diff --git a/linker/linker_block_allocator_test.cpp b/linker/linker_block_allocator_test.cpp
index 359eefb..6fb2b26 100644
--- a/linker/linker_block_allocator_test.cpp
+++ b/linker/linker_block_allocator_test.cpp
@@ -47,14 +47,14 @@
  * this one has size below allocator cap which is 2*sizeof(void*)
  */
 struct test_struct_small {
-  char dummy_str[5];
+  char str[5];
 };
 
 /*
  * 1009 byte struct (1009 is prime)
  */
 struct test_struct_larger {
-  char dummy_str[1009];
+  char str[1009];
 };
 
 static size_t kPageSize = sysconf(_SC_PAGE_SIZE);
@@ -131,14 +131,14 @@
   allocator.protect_all(PROT_READ);
   allocator.protect_all(PROT_READ | PROT_WRITE);
   // check access
-  page2_ptr->dummy_str[23] = 27;
-  page1_ptr->dummy_str[13] = 11;
+  page2_ptr->str[23] = 27;
+  page1_ptr->str[13] = 11;
 
   allocator.protect_all(PROT_READ);
   fprintf(stderr, "trying to access protected page");
 
   // this should result in segmentation fault
-  page1_ptr->dummy_str[11] = 7;
+  page1_ptr->str[11] = 7;
 }
 
 TEST(linker_allocator, test_protect) {
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index ada25a5..1771e87 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -325,7 +325,9 @@
           value = "," + value;
           (*properties)[name].append_value(std::move(value));
         } else if (android::base::EndsWith(name, ".paths") ||
-                   android::base::EndsWith(name, ".shared_libs")) {
+                   android::base::EndsWith(name, ".shared_libs") ||
+                   android::base::EndsWith(name, ".whitelisted") ||
+                   android::base::EndsWith(name, ".allowed_libs")) {
           value = ":" + value;
           (*properties)[name].append_value(std::move(value));
         } else {
@@ -563,10 +565,15 @@
     ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
     ns_config->set_visible(properties.get_bool(property_name_prefix + ".visible"));
 
-    std::string whitelisted =
+    std::string allowed_libs =
         properties.get_string(property_name_prefix + ".whitelisted", &lineno);
-    if (!whitelisted.empty()) {
-      ns_config->set_whitelisted_libs(android::base::Split(whitelisted, ":"));
+    const std::string libs = properties.get_string(property_name_prefix + ".allowed_libs", &lineno);
+    if (!allowed_libs.empty() && !libs.empty()) {
+      allowed_libs += ":";
+    }
+    allowed_libs += libs;
+    if (!allowed_libs.empty()) {
+      ns_config->set_allowed_libs(android::base::Split(allowed_libs, ":"));
     }
 
     // these are affected by is_asan flag
diff --git a/linker/linker_config.h b/linker/linker_config.h
index 6733148..fe23ec1 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -98,9 +98,7 @@
     return permitted_paths_;
   }
 
-  const std::vector<std::string>& whitelisted_libs() const {
-    return whitelisted_libs_;
-  }
+  const std::vector<std::string>& allowed_libs() const { return allowed_libs_; }
 
   const std::vector<NamespaceLinkConfig>& links() const {
     return namespace_links_;
@@ -127,16 +125,17 @@
     permitted_paths_ = std::move(permitted_paths);
   }
 
-  void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
-    whitelisted_libs_ = std::move(whitelisted_libs);
+  void set_allowed_libs(std::vector<std::string>&& allowed_libs) {
+    allowed_libs_ = std::move(allowed_libs);
   }
+
  private:
   const std::string name_;
   bool isolated_;
   bool visible_;
   std::vector<std::string> search_paths_;
   std::vector<std::string> permitted_paths_;
-  std::vector<std::string> whitelisted_libs_;
+  std::vector<std::string> allowed_libs_;
   std::vector<NamespaceLinkConfig> namespace_links_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(NamespaceConfig);
diff --git a/linker/linker_config_test.cpp b/linker/linker_config_test.cpp
index 4937056..acdf641 100644
--- a/linker/linker_config_test.cpp
+++ b/linker/linker_config_test.cpp
@@ -47,6 +47,7 @@
 #define ARCH_SUFFIX ""
 #endif
 
+// clang-format off
 static const char* config_str =
   "# comment \n"
   "dir.test = /data/local/tmp\n"
@@ -88,8 +89,12 @@
   "namespace.vndk_in_system.visible = true\n"
   "namespace.vndk_in_system.search.paths = /system/${LIB}\n"
   "namespace.vndk_in_system.permitted.paths = /system/${LIB}\n"
-  "namespace.vndk_in_system.whitelisted = libz.so:libyuv.so:libtinyxml2.so\n"
+  "namespace.vndk_in_system.whitelisted = libz.so:libyuv.so\n"
+  "namespace.vndk_in_system.whitelisted += libtinyxml2.so\n"
+  "namespace.vndk_in_system.allowed_libs = libfoo.so:libbar.so\n"
+  "namespace.vndk_in_system.allowed_libs += libtinyxml3.so\n"
   "\n";
+// clang-format on
 
 static bool write_version(const std::string& path, uint32_t version) {
   std::string content = android::base::StringPrintf("%d", version);
@@ -212,9 +217,9 @@
   ASSERT_TRUE(ns_vndk_links[0].allow_all_shared_libs());
 
   ASSERT_TRUE(ns_vndk_in_system != nullptr) << "vndk_in_system namespace was not found";
-  ASSERT_EQ(
-      std::vector<std::string>({"libz.so", "libyuv.so", "libtinyxml2.so"}),
-      ns_vndk_in_system->whitelisted_libs());
+  ASSERT_EQ(std::vector<std::string>({"libz.so", "libyuv.so", "libtinyxml2.so", "libfoo.so",
+                                      "libbar.so", "libtinyxml3.so"}),
+            ns_vndk_in_system->allowed_libs());
 }
 
 TEST(linker_config, smoke) {
diff --git a/linker/linker_debuggerd_android.cpp b/linker/linker_debuggerd_android.cpp
index 42ea2b7..203e441 100644
--- a/linker/linker_debuggerd_android.cpp
+++ b/linker/linker_debuggerd_android.cpp
@@ -33,18 +33,27 @@
 
 #include "linker_gdb_support.h"
 
+#if defined(__ANDROID_APEX__)
+static debugger_process_info get_process_info() {
+  return {
+      .abort_msg = __libc_shared_globals()->abort_msg,
+      .fdsan_table = &__libc_shared_globals()->fd_table,
+      .gwp_asan_state = __libc_shared_globals()->gwp_asan_state,
+      .gwp_asan_metadata = __libc_shared_globals()->gwp_asan_metadata,
+      .scudo_stack_depot = __libc_shared_globals()->scudo_stack_depot,
+      .scudo_region_info = __libc_shared_globals()->scudo_region_info,
+  };
+}
+#endif
+
 void linker_debuggerd_init() {
+  // There may be a version mismatch between the bootstrap linker and the crash_dump in the APEX,
+  // so don't pass in any process info from the bootstrap linker.
   debuggerd_callbacks_t callbacks = {
-    .get_abort_message = []() {
-      return __libc_shared_globals()->abort_msg;
-    },
-    .post_dump = &notify_gdb_of_libraries,
-    .get_gwp_asan_state = []() {
-      return __libc_shared_globals()->gwp_asan_state;
-    },
-    .get_gwp_asan_metadata = []() {
-      return __libc_shared_globals()->gwp_asan_metadata;
-    },
+#if defined(__ANDROID_APEX__)
+      .get_process_info = get_process_info,
+#endif
+      .post_dump = notify_gdb_of_libraries,
   };
   debuggerd_init(&callbacks);
 }
diff --git a/linker/linker_globals.cpp b/linker/linker_globals.cpp
index bcc2a1e..31da02c 100644
--- a/linker/linker_globals.cpp
+++ b/linker/linker_globals.cpp
@@ -50,7 +50,7 @@
   return sizeof(__linker_dl_err_buf);
 }
 
-void DL_WARN_documented_change(int api_level, const char* doc_link, const char* fmt, ...) {
+void DL_WARN_documented_change(int api_level, const char* doc_fragment, const char* fmt, ...) {
   std::string result{"Warning: "};
 
   va_list ap;
@@ -60,8 +60,9 @@
 
   android::base::StringAppendF(&result,
                                " and will not work when the app moves to API level %d or later "
-                               "(https://android.googlesource.com/platform/bionic/+/master/%s) "
-                               "(allowing for now because this app's target API level is still %d)",
-                               api_level, doc_link, get_application_target_sdk_version());
+                               "(%s#%s) (allowing for now because this app's target API level is "
+                               "still %d)",
+                               api_level, kBionicChangesUrl, doc_fragment,
+                               get_application_target_sdk_version());
   DL_WARN("%s", result.c_str());
 }
diff --git a/linker/linker_logger.cpp b/linker/linker_logger.cpp
index ec07a55..165b85d 100644
--- a/linker/linker_logger.cpp
+++ b/linker/linker_logger.cpp
@@ -41,7 +41,6 @@
 #include "private/CachedProperty.h"
 
 LinkerLogger g_linker_logger;
-bool g_greylist_disabled = false;
 
 static uint32_t ParseProperty(const std::string& value) {
   if (value.empty()) {
@@ -91,15 +90,6 @@
     return;
   }
 
-  // This is a convenient place to check whether the greylist should be disabled for testing.
-  static CachedProperty greylist_disabled("debug.ld.greylist_disabled");
-  bool old_value = g_greylist_disabled;
-  g_greylist_disabled = (strcmp(greylist_disabled.Get(), "true") == 0);
-  if (g_greylist_disabled != old_value) {
-    async_safe_format_log(ANDROID_LOG_INFO, "linker", "%s greylist",
-                          g_greylist_disabled ? "Disabling" : "Enabling");
-  }
-
   flags_ = 0;
 
   // For logging, check the flag applied to all processes first.
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index fedbc05..f3820a2 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -63,7 +63,3 @@
 
 extern LinkerLogger g_linker_logger;
 extern char** g_argv;
-
-// If the system property debug.ld.greylist_disabled is true, we'll not use the greylist
-// regardless of API level.
-extern bool g_greylist_disabled;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 98af54a..41bb4ba 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -460,7 +460,6 @@
                       RTLD_GLOBAL,
                       nullptr,
                       true /* add_as_children */,
-                      true /* search_linked_namespaces */,
                       &namespaces)) {
     __linker_cannot_link(g_argv[0]);
   } else if (needed_libraries_count == 0) {
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 47d4bdb..724f43c 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -63,7 +63,6 @@
                     int rtld_flags,
                     const android_dlextinfo* extinfo,
                     bool add_as_children,
-                    bool search_linked_namespaces,
                     std::vector<android_namespace_t*>* namespaces = nullptr);
 
 void solist_add_soinfo(soinfo* si);
diff --git a/linker/linker_namespaces.cpp b/linker/linker_namespaces.cpp
index b993689..5182129 100644
--- a/linker/linker_namespaces.cpp
+++ b/linker/linker_namespaces.cpp
@@ -39,10 +39,9 @@
     return true;
   }
 
-  if (!whitelisted_libs_.empty()) {
+  if (!allowed_libs_.empty()) {
     const char *lib_name = basename(file.c_str());
-    if (std::find(whitelisted_libs_.begin(), whitelisted_libs_.end(),
-                  lib_name) == whitelisted_libs_.end()) {
+    if (std::find(allowed_libs_.begin(), allowed_libs_.end(), lib_name) == allowed_libs_.end()) {
       return false;
     }
   }
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 9561bb4..77b6622 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -34,6 +34,8 @@
 #include <vector>
 #include <unordered_set>
 
+std::vector<std::string> fix_lib_paths(std::vector<std::string> paths);
+
 struct android_namespace_t;
 
 struct android_namespace_link_t {
@@ -74,7 +76,7 @@
  public:
   android_namespace_t() :
     is_isolated_(false),
-    is_greylist_enabled_(false),
+    is_exempt_list_enabled_(false),
     is_also_used_as_anonymous_(false) {}
 
   const char* get_name() const { return name_.c_str(); }
@@ -83,8 +85,8 @@
   bool is_isolated() const { return is_isolated_; }
   void set_isolated(bool isolated) { is_isolated_ = isolated; }
 
-  bool is_greylist_enabled() const { return is_greylist_enabled_; }
-  void set_greylist_enabled(bool enabled) { is_greylist_enabled_ = enabled; }
+  bool is_exempt_list_enabled() const { return is_exempt_list_enabled_; }
+  void set_exempt_list_enabled(bool enabled) { is_exempt_list_enabled_ = enabled; }
 
   bool is_also_used_as_anonymous() const { return is_also_used_as_anonymous_; }
   void set_also_used_as_anonymous(bool yes) { is_also_used_as_anonymous_ = yes; }
@@ -100,10 +102,10 @@
     return default_library_paths_;
   }
   void set_default_library_paths(std::vector<std::string>&& library_paths) {
-    default_library_paths_ = std::move(library_paths);
+    default_library_paths_ = fix_lib_paths(std::move(library_paths));
   }
   void set_default_library_paths(const std::vector<std::string>& library_paths) {
-    default_library_paths_ = library_paths;
+    default_library_paths_ = fix_lib_paths(library_paths);
   }
 
   const std::vector<std::string>& get_permitted_paths() const {
@@ -116,14 +118,12 @@
     permitted_paths_ = permitted_paths;
   }
 
-  const std::vector<std::string>& get_whitelisted_libs() const {
-    return whitelisted_libs_;
+  const std::vector<std::string>& get_allowed_libs() const { return allowed_libs_; }
+  void set_allowed_libs(std::vector<std::string>&& allowed_libs) {
+    allowed_libs_ = std::move(allowed_libs);
   }
-  void set_whitelisted_libs(std::vector<std::string>&& whitelisted_libs) {
-    whitelisted_libs_ = std::move(whitelisted_libs);
-  }
-  void set_whitelisted_libs(const std::vector<std::string>& whitelisted_libs) {
-    whitelisted_libs_ = whitelisted_libs;
+  void set_allowed_libs(const std::vector<std::string>& allowed_libs) {
+    allowed_libs_ = allowed_libs;
   }
 
   const std::vector<android_namespace_link_t>& linked_namespaces() const {
@@ -169,12 +169,12 @@
  private:
   std::string name_;
   bool is_isolated_;
-  bool is_greylist_enabled_;
+  bool is_exempt_list_enabled_;
   bool is_also_used_as_anonymous_;
   std::vector<std::string> ld_library_paths_;
   std::vector<std::string> default_library_paths_;
   std::vector<std::string> permitted_paths_;
-  std::vector<std::string> whitelisted_libs_;
+  std::vector<std::string> allowed_libs_;
   // Loader looks into linked namespace if it was not able
   // to find a library in this namespace. Note that library
   // lookup in linked namespaces are limited by the list of
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 9b7a461..1e89094 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -520,7 +520,8 @@
 
 // Reserve a virtual address range such that if it's limits were extended to the next 2**align
 // boundary, it would not overlap with any existing mappings.
-static void* ReserveAligned(size_t size, size_t align) {
+static void* ReserveWithAlignmentPadding(size_t size, size_t align, void** out_gap_start,
+                                         size_t* out_gap_size) {
   int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
   if (align == PAGE_SIZE) {
     void* mmap_ptr = mmap(nullptr, size, PROT_NONE, mmap_flags, -1, 0);
@@ -530,6 +531,15 @@
     return mmap_ptr;
   }
 
+  // Minimum alignment of shared library gap. For efficiency, this should match the second level
+  // page size of the platform.
+#if defined(__LP64__)
+  constexpr size_t kGapAlignment = 1ul << 21;  // 2MB
+#else
+  constexpr size_t kGapAlignment = 0;
+#endif
+  // Maximum gap size, in the units of kGapAlignment.
+  constexpr size_t kMaxGapUnits = 32;
   // Allocate enough space so that the end of the desired region aligned up is still inside the
   // mapping.
   size_t mmap_size = align_up(size, align) + align - PAGE_SIZE;
@@ -538,16 +548,49 @@
   if (mmap_ptr == MAP_FAILED) {
     return nullptr;
   }
+  size_t gap_size = 0;
+  size_t first_byte = reinterpret_cast<size_t>(align_up(mmap_ptr, align));
+  size_t last_byte = reinterpret_cast<size_t>(align_down(mmap_ptr + mmap_size, align) - 1);
+  if (kGapAlignment && first_byte / kGapAlignment != last_byte / kGapAlignment) {
+    // This library crosses a 2MB boundary and will fragment a new huge page.
+    // Lets take advantage of that and insert a random number of inaccessible huge pages before that
+    // to improve address randomization and make it harder to locate this library code by probing.
+    munmap(mmap_ptr, mmap_size);
+    align = std::max(align, kGapAlignment);
+    gap_size =
+        kGapAlignment * (is_first_stage_init() ? 1 : arc4random_uniform(kMaxGapUnits - 1) + 1);
+    mmap_size = align_up(size + gap_size, align) + align - PAGE_SIZE;
+    mmap_ptr = reinterpret_cast<uint8_t*>(mmap(nullptr, mmap_size, PROT_NONE, mmap_flags, -1, 0));
+    if (mmap_ptr == MAP_FAILED) {
+      return nullptr;
+    }
+  }
+
+  uint8_t *gap_end, *gap_start;
+  if (gap_size) {
+    gap_end = align_down(mmap_ptr + mmap_size, kGapAlignment);
+    gap_start = gap_end - gap_size;
+  } else {
+    gap_start = gap_end = mmap_ptr + mmap_size;
+  }
 
   uint8_t* first = align_up(mmap_ptr, align);
-  uint8_t* last = align_down(mmap_ptr + mmap_size, align) - size;
+  uint8_t* last = align_down(gap_start, align) - size;
 
   // arc4random* is not available in first stage init because /dev/urandom hasn't yet been
   // created. Don't randomize then.
   size_t n = is_first_stage_init() ? 0 : arc4random_uniform((last - first) / PAGE_SIZE + 1);
   uint8_t* start = first + n * PAGE_SIZE;
+  // Unmap the extra space around the allocation.
+  // Keep it mapped PROT_NONE on 64-bit targets where address space is plentiful to make it harder
+  // to defeat ASLR by probing for readable memory mappings.
   munmap(mmap_ptr, start - mmap_ptr);
-  munmap(start + size, mmap_ptr + mmap_size - (start + size));
+  munmap(start + size, gap_start - (start + size));
+  if (gap_end != mmap_ptr + mmap_size) {
+    munmap(gap_end, mmap_ptr + mmap_size - gap_end);
+  }
+  *out_gap_start = gap_start;
+  *out_gap_size = gap_size;
   return start;
 }
 
@@ -571,13 +614,15 @@
              load_size_ - address_space->reserved_size, load_size_, name_.c_str());
       return false;
     }
-    start = ReserveAligned(load_size_, kLibraryAlignment);
+    start = ReserveWithAlignmentPadding(load_size_, kLibraryAlignment, &gap_start_, &gap_size_);
     if (start == nullptr) {
       DL_ERR("couldn't reserve %zd bytes of address space for \"%s\"", load_size_, name_.c_str());
       return false;
     }
   } else {
     start = address_space->start_addr;
+    gap_start_ = nullptr;
+    gap_size_ = 0;
     mapped_by_caller_ = true;
 
     // Update the reserved address space to subtract the space used by this library.
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 5d1cfc2..4cb48f5 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -49,6 +49,8 @@
   size_t phdr_count() const { return phdr_num_; }
   ElfW(Addr) load_start() const { return reinterpret_cast<ElfW(Addr)>(load_start_); }
   size_t load_size() const { return load_size_; }
+  ElfW(Addr) gap_start() const { return reinterpret_cast<ElfW(Addr)>(gap_start_); }
+  size_t gap_size() const { return gap_size_; }
   ElfW(Addr) load_bias() const { return load_bias_; }
   const ElfW(Phdr)* loaded_phdr() const { return loaded_phdr_; }
   const ElfW(Dyn)* dynamic() const { return dynamic_; }
@@ -96,6 +98,10 @@
   void* load_start_;
   // Size in bytes of reserved address space.
   size_t load_size_;
+  // First page of inaccessible gap mapping reserved for this DSO.
+  void* gap_start_;
+  // Size in bytes of the gap mapping.
+  size_t gap_size_;
   // Load bias.
   ElfW(Addr) load_bias_;
 
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 4f67003..60fd242 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -900,6 +900,24 @@
   g_soinfo_handles_map[handle_] = this;
 }
 
+void soinfo::set_gap_start(ElfW(Addr) gap_start) {
+  CHECK(has_min_version(6));
+  gap_start_ = gap_start;
+}
+ElfW(Addr) soinfo::get_gap_start() const {
+  CHECK(has_min_version(6));
+  return gap_start_;
+}
+
+void soinfo::set_gap_size(size_t gap_size) {
+  CHECK(has_min_version(6));
+  gap_size_ = gap_size;
+}
+size_t soinfo::get_gap_size() const {
+  CHECK(has_min_version(6));
+  return gap_size_;
+}
+
 // TODO(dimitry): Move SymbolName methods to a separate file.
 
 uint32_t calculate_elf_hash(const char* name) {
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index e1a3c30..7372a51 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -66,7 +66,7 @@
 #define FLAG_PRELINKED        0x00000400 // prelink_image has successfully processed this soinfo
 #define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
 
-#define SOINFO_VERSION 5
+#define SOINFO_VERSION 6
 
 ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr);
 
@@ -345,6 +345,12 @@
 
   SymbolLookupLib get_lookup_lib();
 
+  void set_gap_start(ElfW(Addr) gap_start);
+  ElfW(Addr) get_gap_start() const;
+
+  void set_gap_size(size_t gap_size);
+  size_t get_gap_size() const;
+
  private:
   bool is_image_linked() const;
   void set_image_linked();
@@ -423,6 +429,10 @@
   // version >= 5
   std::unique_ptr<soinfo_tls> tls_;
   std::vector<TlsDynamicResolverArg> tlsdesc_args_;
+
+  // version >= 6
+  ElfW(Addr) gap_start_;
+  size_t gap_size_;
 };
 
 // This function is used by dlvsym() to calculate hash of sym_ver
diff --git a/linker/linker_tls.cpp b/linker/linker_tls.cpp
index d2edbb3..97892f4 100644
--- a/linker/linker_tls.cpp
+++ b/linker/linker_tls.cpp
@@ -128,6 +128,8 @@
 void linker_finalize_static_tls() {
   g_static_tls_finished = true;
   __libc_shared_globals()->static_tls_layout.finish_layout();
+  TlsModules& modules = __libc_shared_globals()->tls_modules;
+  modules.static_module_count = modules.module_count;
 }
 
 void register_soinfo_tls(soinfo* si) {
diff --git a/linker/linker_translate_path.cpp b/linker/linker_translate_path.cpp
index df7d0aa..4f3fdfb 100644
--- a/linker/linker_translate_path.cpp
+++ b/linker/linker_translate_path.cpp
@@ -31,13 +31,14 @@
 #include "linker_utils.h"
 
 #if defined(__LP64__)
-static const char* const kSystemLibDir        = "/system/lib64";
-static const char* const kI18nApexLibDir      = "/apex/com.android.i18n/lib64";
+#define APEX_LIB(apex, name) \
+  { "/system/lib64/" name, "/apex/" apex "/lib64/" name }
 #else
-static const char* const kSystemLibDir        = "/system/lib";
-static const char* const kI18nApexLibDir      = "/apex/com.android.i18n/lib";
+#define APEX_LIB(apex, name) \
+  { "/system/lib/" name, "/apex/" apex "/lib/" name }
 #endif
 
+
 // Workaround for dlopen(/system/lib(64)/<soname>) when .so is in /apex. http://b/121248172
 /**
  * Translate /system path to /apex path if needed
@@ -47,27 +48,22 @@
  * return true if translation is needed
  */
 bool translateSystemPathToApexPath(const char* name, std::string* out_name_to_apex) {
-  static const char* const kSystemToArtApexLibs[] = {
-      "libicuuc.so",
-      "libicui18n.so",
+  static constexpr const char* kPathTranslationQ[][2] = {
+      APEX_LIB("com.android.i18n", "libicui18n.so"),
+      APEX_LIB("com.android.i18n", "libicuuc.so")
   };
-  // New mapping for new apex should be added below
 
-  // Nothing to do if target sdk version is Q or above
-  if (get_application_target_sdk_version() >= 29) {
+  if (name == nullptr) {
     return false;
   }
 
-  // If the path isn't /system/lib, there's nothing to do.
-  if (name == nullptr || dirname(name) != kSystemLibDir) {
-    return false;
-  }
+  auto comparator = [name](auto p) { return strcmp(name, p[0]) == 0; };
 
-  const char* base_name = basename(name);
-
-  for (const char* soname : kSystemToArtApexLibs) {
-    if (strcmp(base_name, soname) == 0) {
-      *out_name_to_apex = std::string(kI18nApexLibDir) + "/" + base_name;
+  if (get_application_target_sdk_version() < __ANDROID_API_Q__) {
+    if (auto it =
+            std::find_if(std::begin(kPathTranslationQ), std::end(kPathTranslationQ), comparator);
+        it != std::end(kPathTranslationQ)) {
+      *out_name_to_apex = (*it)[1];
       return true;
     }
   }
diff --git a/tests/Android.bp b/tests/Android.bp
index 8b1eebc..586ef34 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -22,6 +22,12 @@
         darwin: {
             enabled: false,
         },
+        android: {
+            header_libs: ["bionic_libc_platform_headers"],
+        },
+        linux_bionic: {
+            header_libs: ["bionic_libc_platform_headers"],
+        },
     },
     cflags: [
         "-fstack-protector-all",
@@ -38,17 +44,24 @@
         // For glibc.
         "-D__STDC_LIMIT_MACROS",
     ],
-    header_libs: ["bionic_libc_platform_headers"],
-    // Make the bionic tests implicitly test bionic's shadow call stack support.
+    // Ensure that the tests exercise shadow call stack support and
+    // the hint space PAC/BTI instructions.
     arch: {
         arm64: {
-           cflags: ["-fsanitize=shadow-call-stack"],
+            cflags: [
+                "-fsanitize=shadow-call-stack",
+                // Disable this option for now: see b/151372823
+                //"-mbranch-protection=standard",
+            ],
         },
     },
     stl: "libc++",
     sanitize: {
         address: false,
     },
+
+    // Use the bootstrap version of bionic because some tests call private APIs
+    // that aren't exposed by the APEX bionic stubs.
     bootstrap: true,
 
     product_variables: {
@@ -59,6 +72,217 @@
 }
 
 // -----------------------------------------------------------------------------
+// Prebuilt shared libraries for use in tests.
+// -----------------------------------------------------------------------------
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-rw_load_segment",
+    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-rw_load_segment.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-rw_load_segment.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-rw_load_segment.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-rw_load_segment.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-unaligned_shdr_offset",
+    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-unaligned_shdr_offset.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-unaligned_shdr_offset.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-unaligned_shdr_offset.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-unaligned_shdr_offset.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-zero_shentsize",
+    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-zero_shentsize.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shentsize.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shentsize.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shentsize.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-zero_shstrndx",
+    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-zero_shstrndx.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shstrndx.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shstrndx.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shstrndx.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-empty_shdr_table",
+    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-empty_shdr_table.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-empty_shdr_table.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-empty_shdr_table.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-empty_shdr_table.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-zero_shdr_table_offset",
+    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-zero_shdr_table_offset.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_offset.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shdr_table_offset.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_offset.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-zero_shdr_table_content",
+    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-zero_shdr_table_content.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-zero_shdr_table_content.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-zero_shdr_table_content.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-zero_shdr_table_content.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-textrels",
+    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-textrels.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-textrels.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-textrels.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-textrels.so"],
+        },
+    },
+}
+
+cc_prebuilt_test_library_shared {
+    name: "libtest_invalid-textrels2",
+    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-textrels2.so"],
+        },
+        arm64: {
+            srcs: ["prebuilt-elf-files/arm64/libtest_invalid-textrels2.so"],
+        },
+        x86: {
+            srcs: ["prebuilt-elf-files/x86/libtest_invalid-textrels2.so"],
+        },
+        x86_64: {
+            srcs: ["prebuilt-elf-files/x86_64/libtest_invalid-textrels2.so"],
+        },
+    },
+}
+
+// -----------------------------------------------------------------------------
 // All standard tests.
 // -----------------------------------------------------------------------------
 
@@ -109,6 +333,7 @@
         "glob_test.cpp",
         "grp_pwd_test.cpp",
         "grp_pwd_file_test.cpp",
+        "heap_tagging_level_test.cpp",
         "iconv_test.cpp",
         "ifaddrs_test.cpp",
         "ifunc_test.cpp",
@@ -167,6 +392,7 @@
         "strings_nofortify_test.cpp",
         "strings_test.cpp",
         "sstream_test.cpp",
+        "sys_auxv_test.cpp",
         "sys_epoll_test.cpp",
         "sys_mman_test.cpp",
         "sys_msg_test.cpp",
@@ -196,6 +422,7 @@
         "sys_uio_test.cpp",
         "sys_un_test.cpp",
         "sys_vfs_test.cpp",
+        "sys_wait_test.cpp",
         "sys_xattr_test.cpp",
         "system_properties_test.cpp",
         "system_properties_test2.cpp",
@@ -222,9 +449,6 @@
                 "libprocinfo",
                 "libsystemproperties",
             ],
-            srcs: [
-                "tagged_pointers_test.cpp",
-            ],
         },
     },
 
@@ -724,15 +948,15 @@
         "libtest_with_dependency_loop",
         "libtest_with_dependency",
         "libtest_indirect_thread_local_dtor",
-        "libtest_invalid-empty_shdr_table.so",
-        "libtest_invalid-rw_load_segment.so",
-        "libtest_invalid-unaligned_shdr_offset.so",
-        "libtest_invalid-zero_shdr_table_content.so",
-        "libtest_invalid-zero_shdr_table_offset.so",
-        "libtest_invalid-zero_shentsize.so",
-        "libtest_invalid-zero_shstrndx.so",
-        "libtest_invalid-textrels.so",
-        "libtest_invalid-textrels2.so",
+        "libtest_invalid-empty_shdr_table",
+        "libtest_invalid-rw_load_segment",
+        "libtest_invalid-unaligned_shdr_offset",
+        "libtest_invalid-zero_shdr_table_content",
+        "libtest_invalid-zero_shdr_table_offset",
+        "libtest_invalid-zero_shentsize",
+        "libtest_invalid-zero_shstrndx",
+        "libtest_invalid-textrels",
+        "libtest_invalid-textrels2",
         "libtest_thread_local_dtor",
         "libtest_thread_local_dtor2",
         "preinit_getauxval_test_helper",
@@ -773,17 +997,6 @@
 }
 
 cc_test {
-    name: "bionic-unit-tests-scudo",
-    defaults: [
-        "bionic_unit_tests_defaults",
-    ],
-
-    shared_libs: [
-        "libc_scudo",
-    ],
-}
-
-cc_test {
     name: "bionic-stress-tests",
     defaults: [
         "bionic_tests_defaults",
diff --git a/tests/Android.build.prebuilt.mk b/tests/Android.build.prebuilt.mk
deleted file mode 100644
index de8f5e6..0000000
--- a/tests/Android.build.prebuilt.mk
+++ /dev/null
@@ -1,30 +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 $(CLEAR_VARS)
-LOCAL_MULTILIB := both
-LOCAL_MODULE := $(bionic_tests_module)
-LOCAL_MODULE_PATH_32 := $($(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_DATA_NATIVE_TESTS)/bionic-loader-test-libs/prebuilt-elf-files
-LOCAL_MODULE_PATH_64 := $(TARGET_OUT_DATA_NATIVE_TESTS)/bionic-loader-test-libs/prebuilt-elf-files
-LOCAL_MODULE_CLASS := EXECUTABLES
-
-LOCAL_SRC_FILES_arm := prebuilt-elf-files/arm/$(bionic_tests_module)
-LOCAL_SRC_FILES_arm64 := prebuilt-elf-files/arm64/$(bionic_tests_module)
-LOCAL_SRC_FILES_x86 := prebuilt-elf-files/x86/$(bionic_tests_module)
-LOCAL_SRC_FILES_x86_64 := prebuilt-elf-files/x86_64/$(bionic_tests_module)
-include $(BUILD_PREBUILT)
-bionic-loader-test-libs-target: $(LOCAL_MODULE)
-.PHONY: bionic-loader-test-libs-target
diff --git a/tests/Android.mk b/tests/Android.mk
index b5571e3..5ad4045 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -16,43 +16,6 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# TODO(dimitry): replace with define once https://android-review.googlesource.com/247466 is reverted
-# https://github.com/google/kati/issues/83 is currently blocking it.
-
-# Move prebuilt test elf-files to $(TARGET_OUT_NATIVE_TESTS)
-bionic_tests_module := libtest_invalid-rw_load_segment.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-unaligned_shdr_offset.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shentsize.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shstrndx.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-empty_shdr_table.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shdr_table_offset.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-zero_shdr_table_content.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-textrels.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-bionic_tests_module := libtest_invalid-textrels2.so
-include $(LOCAL_PATH)/Android.build.prebuilt.mk
-
-ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-build_host := true
-else
-build_host := false
-endif
-
 ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
 
 # -----------------------------------------------------------------------------
diff --git a/tests/bionic_allocator_test.cpp b/tests/bionic_allocator_test.cpp
index f710907..fdcf868 100644
--- a/tests/bionic_allocator_test.cpp
+++ b/tests/bionic_allocator_test.cpp
@@ -42,19 +42,19 @@
  * this one has size below allocator cap which is 2*sizeof(void*)
  */
 struct test_struct_small {
-  char dummy_str[5];
+  char str[5];
 };
 
 struct test_struct_large {
-  char dummy_str[1009];
+  char str[1009];
 };
 
 struct test_struct_huge {
-  char dummy_str[73939];
+  char str[73939];
 };
 
 struct test_struct_512 {
-  char dummy_str[503];
+  char str[503];
 };
 
 };
diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp
index 792f917..e0ae3af 100644
--- a/tests/cfi_test.cpp
+++ b/tests/cfi_test.cpp
@@ -95,9 +95,6 @@
   EXPECT_EQ(get_global_address(), get_last_address());
   EXPECT_EQ(c, get_count());
 
-  // CFI check for a stack address. This is always invalid and gets the process killed.
-  EXPECT_DEATH(__cfi_slowpath(45, reinterpret_cast<void*>(&c)), "");
-
   // CFI check for a heap address.
   // 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
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 715f9c8..0d17284 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -18,17 +18,24 @@
 #error "Non-clang isn't supported"
 #endif
 
+//
 // Clang compile-time and run-time tests for Bionic's FORTIFY.
 //
-// This file is compiled in two configurations ways to give us a sane set of tests for clang's
-// FORTIFY implementation.
+
+// This file is compiled in two configurations to give us reasonable coverage of clang's
+// FORTIFY implementation:
 //
-// One configuration uses clang's diagnostic consumer
+// 1. For compile-time checks, we use clang's diagnostic consumer
 // (https://clang.llvm.org/doxygen/classclang_1_1VerifyDiagnosticConsumer.html#details)
 // to check diagnostics (e.g. the expected-* comments everywhere).
 //
-// Please note that this test does things like leaking memory. That's WAI.
+// 2. For run-time checks, we build and run as regular gtests.
 
+// Note that these tests do things like leaking memory. That's WAI.
+
+//
+// Configuration for the compile-time checks. (These comments have side effects!)
+//
 // Silence all "from 'diagnose_if'" `note`s from anywhere, including headers; they're uninteresting
 // for this test case, and their line numbers may change over time.
 // expected-note@* 0+{{from 'diagnose_if'}}
@@ -39,8 +46,8 @@
 // And finally, all explicitly-unavailable-here complaints from headers are
 // uninteresting
 // expected-note@* 0+{{has been explicitly marked unavailable here}}
-
-// Note that some of these diags come from clang itself, while others come from
+//
+// Note that some of these diagnostics come from clang itself, while others come from
 // `diagnose_if`s sprinkled throughout Bionic.
 
 #ifndef _FORTIFY_SOURCE
diff --git a/tests/dirent_test.cpp b/tests/dirent_test.cpp
index 378aea4..56929d1 100644
--- a/tests/dirent_test.cpp
+++ b/tests/dirent_test.cpp
@@ -113,6 +113,18 @@
   ASSERT_EQ(unsorted_name_list, unsorted_name_list_at64);
 }
 
+static int is_version_filter(const dirent* de) {
+  return !strcmp(de->d_name, "version");
+}
+
+TEST(dirent, scandir_filter) {
+  dirent** entries;
+  errno = 0;
+  ASSERT_EQ(1, scandir("/proc", &entries, is_version_filter, nullptr));
+  ASSERT_STREQ("version", entries[0]->d_name);
+  free(entries);
+}
+
 TEST(dirent, scandir_ENOENT) {
   dirent** entries;
   errno = 0;
diff --git a/tests/dlext_private.h b/tests/dlext_private.h
index b338ae0..262af4c 100644
--- a/tests/dlext_private.h
+++ b/tests/dlext_private.h
@@ -56,10 +56,10 @@
    */
   ANDROID_NAMESPACE_TYPE_SHARED = 2,
 
-  /* This flag instructs linker to enable grey-list workaround for the namespace.
+  /* This flag instructs linker to enable exempt-list workaround for the namespace.
    * See http://b/26394120 for details.
    */
-  ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+  ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED = 0x08000000,
 
   ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
                                            ANDROID_NAMESPACE_TYPE_ISOLATED,
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 293c17b..01bf8ab 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -237,6 +237,24 @@
   ASSERT_TRUE(dlopen(nullptr, RTLD_NOW) != nullptr);
 }
 
+// Test system path translation for backward compatibility. http://b/130219528
+TEST(dlfcn, dlopen_system_libicuuc_android_api_level_28) {
+  android_set_application_target_sdk_version(28);
+  ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicuuc.so", RTLD_NOW) != nullptr);
+  ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicui18n.so", RTLD_NOW) != nullptr);
+}
+
+TEST(dlfcn, dlopen_system_libicuuc_android_api_level_29) {
+  android_set_application_target_sdk_version(29);
+  ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicuuc.so", RTLD_NOW) == nullptr);
+  ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicui18n.so", RTLD_NOW) == nullptr);
+}
+
+TEST(dlfcn, dlopen_system_libicuuc_android_api_level_current) {
+  ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicuuc.so", RTLD_NOW) == nullptr);
+  ASSERT_TRUE(dlopen(PATH_TO_SYSTEM_LIB "libicui18n.so", RTLD_NOW) == nullptr);
+}
+
 TEST(dlfcn, dlopen_from_zip_absolute_path) {
   const std::string lib_zip_path = "/libdlext_test_zip/libdlext_test_zip_zipaligned.zip";
   const std::string lib_path = GetTestlibRoot() + lib_zip_path;
@@ -1210,7 +1228,7 @@
             dlerror());
 }
 
-TEST(dlext, ns_greylist_enabled) {
+TEST(dlext, ns_exempt_list_enabled) {
   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
 
   const std::string ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
@@ -1219,7 +1237,7 @@
           android_create_namespace("namespace",
                                    nullptr,
                                    ns_search_path.c_str(),
-                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED,
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED,
                                    nullptr,
                                    nullptr);
 
@@ -1229,26 +1247,26 @@
   extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
   extinfo.library_namespace = ns;
 
-  // An app targeting M can open libnativehelper.so because it's on the greylist.
+  // An app targeting M can open libnativehelper.so because it's on the exempt-list.
   android_set_application_target_sdk_version(23);
   void* handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle != nullptr) << dlerror();
 
-  // Check that loader did not load another copy of libdl.so while loading greylisted library.
+  // Check that loader did not load another copy of libdl.so while loading exempted library.
   void* dlsym_ptr = dlsym(handle, "dlsym");
   ASSERT_TRUE(dlsym_ptr != nullptr) << dlerror();
   ASSERT_EQ(&dlsym, dlsym_ptr);
 
   dlclose(handle);
 
-  // An app targeting N no longer has the greylist.
+  // An app targeting N no longer has the exempt-list.
   android_set_application_target_sdk_version(24);
   handle = android_dlopen_ext("libnativehelper.so", RTLD_NOW, &extinfo);
   ASSERT_TRUE(handle == nullptr);
   ASSERT_STREQ("dlopen failed: library \"libnativehelper.so\" not found", dlerror());
 }
 
-TEST(dlext, ns_greylist_disabled_by_default) {
+TEST(dlext, ns_exempt_list_disabled_by_default) {
   ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
 
   const std::string ns_search_path = GetTestlibRoot() + "/private_namespace_libs";
@@ -2004,7 +2022,7 @@
     }
   }
 
-  // some sanity checks..
+  // Some validity checks.
   ASSERT_TRUE(addr_start > 0);
   ASSERT_TRUE(addr_end > 0);
   ASSERT_TRUE(maps_to_copy.size() > 0);
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index d7b9bae..35e12eb 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1623,9 +1623,7 @@
 #endif //  defined(__arm__)
 
 TEST(dlfcn, dlopen_invalid_rw_load_segment) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-rw_load_segment.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-rw_load_segment.so";
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
   std::string expected_dlerror = std::string("dlopen failed: \"") + libpath + "\": W+E load segments are not allowed";
@@ -1633,9 +1631,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_unaligned_shdr_offset) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-unaligned_shdr_offset.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-unaligned_shdr_offset.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1644,9 +1640,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_zero_shentsize) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-zero_shentsize.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shentsize.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1655,9 +1649,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_zero_shstrndx) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-zero_shstrndx.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shstrndx.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1666,9 +1658,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_empty_shdr_table) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-empty_shdr_table.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-empty_shdr_table.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1677,9 +1667,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_zero_shdr_table_offset) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-zero_shdr_table_offset.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shdr_table_offset.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1688,9 +1676,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_zero_shdr_table_content) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-zero_shdr_table_content.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-zero_shdr_table_content.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1699,9 +1685,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_textrels) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-textrels.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-textrels.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
@@ -1710,9 +1694,7 @@
 }
 
 TEST(dlfcn, dlopen_invalid_textrels2) {
-  const std::string libpath = GetTestlibRoot() +
-                              "/" + kPrebuiltElfDir +
-                              "/libtest_invalid-textrels2.so";
+  const std::string libpath = GetPrebuiltElfDir() + "/libtest_invalid-textrels2.so";
 
   void* handle = dlopen(libpath.c_str(), RTLD_NOW);
   ASSERT_TRUE(handle == nullptr);
diff --git a/tests/fdtrack_test.cpp b/tests/fdtrack_test.cpp
index 44aa033..fe9a61c 100644
--- a/tests/fdtrack_test.cpp
+++ b/tests/fdtrack_test.cpp
@@ -29,11 +29,13 @@
 
 #if defined(__BIONIC__)
 #include "platform/bionic/fdtrack.h"
+#include "platform/bionic/reserved_signals.h"
 #endif
 
 #include <vector>
 
 #include <android-base/cmsg.h>
+#include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 
 using android::base::ReceiveFileDescriptors;
@@ -41,6 +43,18 @@
 using android::base::unique_fd;
 
 #if defined(__BIONIC__)
+void DumpEvent(std::vector<android_fdtrack_event>* events, size_t index) {
+  auto& event = (*events)[index];
+  if (event.type == ANDROID_FDTRACK_EVENT_TYPE_CREATE) {
+    fprintf(stderr, "  event %zu: fd %d created by %s\n", index, event.fd,
+            event.data.create.function_name);
+  } else if (event.type == ANDROID_FDTRACK_EVENT_TYPE_CLOSE) {
+    fprintf(stderr, "  event %zu: fd %d closed\n", index, event.fd);
+  } else {
+    errx(1, "unexpected fdtrack event type: %d", event.type);
+  }
+}
+
 std::vector<android_fdtrack_event> FdtrackRun(void (*func)()) {
   // Each bionic test is run in separate process, so we can safely use a static here.
   static std::vector<android_fdtrack_event> events;
@@ -48,6 +62,7 @@
 
   android_fdtrack_hook_t previous = nullptr;
   android_fdtrack_hook_t hook = [](android_fdtrack_event* event) {
+    raise(BIONIC_SIGNAL_DEBUGGER);
     events.push_back(*event);
   };
 
@@ -66,6 +81,30 @@
     errx(1, "failed to reset hook");
   }
 
+  // Filter out temporary fds created and closed as a result of the call.
+  // (e.g. accept creating a socket to tell netd about the newly accepted socket)
+  size_t i = 0;
+  while (i + 1 < events.size()) {
+    auto& event = events[i];
+    if (event.type == ANDROID_FDTRACK_EVENT_TYPE_CREATE) {
+      for (size_t j = i + 1; j < events.size(); ++j) {
+        if (event.fd == events[j].fd) {
+          if (events[j].type == ANDROID_FDTRACK_EVENT_TYPE_CREATE) {
+            fprintf(stderr, "error: multiple create events for the same fd:\n");
+            DumpEvent(&events, i);
+            DumpEvent(&events, j);
+            exit(1);
+          }
+
+          events.erase(events.begin() + j);
+          events.erase(events.begin() + i);
+          continue;
+        }
+      }
+    }
+    ++i;
+  }
+
   return std::move(events);
 }
 
@@ -146,15 +185,7 @@
       fprintf(stderr, "too many events received: expected %zu, got %zu:\n", expected_fds.size(), \
               events.size());                                                                    \
       for (size_t i = 0; i < events.size(); ++i) {                                               \
-        auto& event = events[i];                                                                 \
-        if (event.type == ANDROID_FDTRACK_EVENT_TYPE_CREATE) {                                   \
-          fprintf(stderr, "  event %zu: fd %d created by %s\n", i, event.fd,                     \
-                  event.data.create.function_name);                                              \
-        } else if (event.type == ANDROID_FDTRACK_EVENT_TYPE_CLOSE) {                             \
-          fprintf(stderr, "  event %zu: fd %d closed\n", i, event.fd);                           \
-        } else {                                                                                 \
-          errx(1, "unexpected fdtrack event type: %d", event.type);                              \
-        }                                                                                        \
+        DumpEvent(&events, i);                                                                   \
       }                                                                                          \
       FAIL();                                                                                    \
       return;                                                                                    \
@@ -216,12 +247,11 @@
 
 FDTRACK_TEST(eventfd, eventfd(0, 0));
 
-#if 0
-// Why is this generating an extra socket/close event?
-FDTRACK_TEST(accept, ({
+#if defined(__BIONIC__)
+static int CreateListener() {
   android_fdtrack_set_enabled(false);
   int listener = socket(AF_INET, SOCK_STREAM, 0);
-  ASSERT_NE(-1, listener);
+  CHECK_NE(-1, listener);
 
   sockaddr_in addr = {
       .sin_family = AF_INET,
@@ -230,21 +260,23 @@
   };
   socklen_t addrlen = sizeof(addr);
 
-  ASSERT_NE(-1, bind(listener, reinterpret_cast<sockaddr*>(&addr), addrlen)) << strerror(errno);
-  ASSERT_NE(-1, getsockname(listener, reinterpret_cast<sockaddr*>(&addr), &addrlen));
-  ASSERT_EQ(static_cast<size_t>(addrlen), sizeof(addr));
-  ASSERT_NE(-1, listen(listener, 1));
+  CHECK_NE(-1, bind(listener, reinterpret_cast<sockaddr*>(&addr), addrlen)) << strerror(errno);
+  CHECK_NE(-1, getsockname(listener, reinterpret_cast<sockaddr*>(&addr), &addrlen));
+  CHECK_EQ(static_cast<size_t>(addrlen), sizeof(addr));
+  CHECK_NE(-1, listen(listener, 1));
 
   int connector = socket(AF_INET, SOCK_STREAM, 0);
-  ASSERT_NE(-1, connector);
-  ASSERT_NE(-1, connect(connector, reinterpret_cast<sockaddr*>(&addr), addrlen));
-
+  CHECK_NE(-1, connector);
+  CHECK_NE(-1, connect(connector, reinterpret_cast<sockaddr*>(&addr), addrlen));
   android_fdtrack_set_enabled(true);
-  int accepted = accept(listener, nullptr, nullptr);
-  accepted;
-}));
+
+  return listener;
+}
 #endif
 
+FDTRACK_TEST_NAME(accept, "accept4", accept(CreateListener(), nullptr, nullptr));
+FDTRACK_TEST(accept4, accept4(CreateListener(), nullptr, nullptr, 0));
+
 FDTRACK_TEST(recvmsg, ({
   android_fdtrack_set_enabled(false);
   int sockets[2];
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index 9a4b781..3ca0223 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -14,14 +14,6 @@
  * limitations under the License.
  */
 
-// -Werror is on whether we like it or not, and we're intentionally doing awful
-// things in this file. GCC is dumb and doesn't have a specific error class for
-// the fortify failures (it's just -Werror), so we can't use anything more
-// constrained than disabling all the warnings in the file :( It also won't let
-// us use system_header in a .cpp file, so we have to #include this from
-// fortify_test_main.cpp.
-#pragma GCC system_header
-
 #include <gtest/gtest.h>
 #include "BionicDeathTest.h"
 
@@ -212,8 +204,9 @@
   foo myfoo;
   volatile int asize = sizeof(myfoo.a) + 1;
   memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
-  ASSERT_FORTIFY(printf("%s", memchr(myfoo.a, 'a', asize)));
-  ASSERT_FORTIFY(printf("%s", memchr(static_cast<const void*>(myfoo.a), 'a', asize)));
+  ASSERT_FORTIFY(printf("%s", static_cast<const char*>(memchr(myfoo.a, 'a', asize))));
+  ASSERT_FORTIFY(printf(
+      "%s", static_cast<const char*>(memchr(static_cast<const void*>(myfoo.a), 'a', asize))));
 #else // __BIONIC__
   GTEST_SKIP() << "glibc is broken";
 #endif // __BIONIC__
@@ -224,8 +217,9 @@
   foo myfoo;
   volatile int asize = sizeof(myfoo.a) + 1;
   memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
-  ASSERT_FORTIFY(printf("%s", memrchr(myfoo.a, 'a', asize)));
-  ASSERT_FORTIFY(printf("%s", memrchr(static_cast<const void*>(myfoo.a), 'a', asize)));
+  ASSERT_FORTIFY(printf("%s", static_cast<const char*>(memrchr(myfoo.a, 'a', asize))));
+  ASSERT_FORTIFY(printf(
+      "%s", static_cast<const char*>(memrchr(static_cast<const void*>(myfoo.a), 'a', asize))));
 #else // __BIONIC__
   GTEST_SKIP() << "glibc is broken";
 #endif // __BIONIC__
diff --git a/tests/ftw_test.cpp b/tests/ftw_test.cpp
index dfc4d72..200ed4b 100644
--- a/tests/ftw_test.cpp
+++ b/tests/ftw_test.cpp
@@ -49,7 +49,7 @@
   ASSERT_EQ(0, close(fd));
 }
 
-void sanity_check_ftw(const char* fpath, const struct stat* sb, int tflag) {
+void smoke_test_ftw(const char* fpath, const struct stat* sb, int tflag) {
   ASSERT_TRUE(fpath != nullptr);
   ASSERT_TRUE(sb != nullptr);
 
@@ -75,28 +75,28 @@
   }
 }
 
-void sanity_check_nftw(const char* fpath, const struct stat* sb, int tflag, FTW* ftwbuf) {
-  sanity_check_ftw(fpath, sb, tflag);
+void smoke_test_nftw(const char* fpath, const struct stat* sb, int tflag, FTW* ftwbuf) {
+  smoke_test_ftw(fpath, sb, tflag);
   ASSERT_EQ('/', fpath[ftwbuf->base - 1]) << fpath;
 }
 
 int check_ftw(const char* fpath, const struct stat* sb, int tflag) {
-  sanity_check_ftw(fpath, sb, tflag);
+  smoke_test_ftw(fpath, sb, tflag);
   return 0;
 }
 
 int check_ftw64(const char* fpath, const struct stat64* sb, int tflag) {
-  sanity_check_ftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag);
+  smoke_test_ftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag);
   return 0;
 }
 
 int check_nftw(const char* fpath, const struct stat* sb, int tflag, FTW* ftwbuf) {
-  sanity_check_nftw(fpath, sb, tflag, ftwbuf);
+  smoke_test_nftw(fpath, sb, tflag, ftwbuf);
   return 0;
 }
 
 int check_nftw64(const char* fpath, const struct stat64* sb, int tflag, FTW* ftwbuf) {
-  sanity_check_nftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag, ftwbuf);
+  smoke_test_nftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag, ftwbuf);
   return 0;
 }
 
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 9c6b0c5..bf65720 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -75,7 +75,11 @@
     EXPECT_STREQ("/", pwd->pw_dir);
   }
 
-  EXPECT_STREQ("/bin/sh", pwd->pw_shell);
+  // This has changed over time and that causes new GSI + old vendor images testing to fail.
+  // This parameter doesn't matter on Android, so simply ignore its value for older vendor images.
+  if (android::base::GetIntProperty("ro.product.first_api_level", 0) >= 30) {
+    EXPECT_STREQ("/bin/sh", pwd->pw_shell);
+  }
 }
 
 static void check_getpwuid(const char* username, uid_t uid, uid_type_t uid_type,
@@ -405,8 +409,8 @@
   }
   expect_range(AID_ISOLATED_START, AID_ISOLATED_END);
 
-  // TODO(73062966): We still don't have a good way to create vendor AIDs in the system or other
-  // non-vendor partitions, therefore we keep this check disabled.
+  // Prior to R, we didn't have a mechanism to create vendor AIDs in the system or other non-vendor
+  // partitions, therefore we disabled the rest of these checks for older API levels.
   if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 29) {
     return;
   }
@@ -462,14 +466,7 @@
       EXPECT_STREQ("/data", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
     }
 
-    // TODO(b/27999086): fix this check with the OEM range
-    // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
-    // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
-    // yet, so therefore we do not check for uid's in the OEM range.
-    if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
-        !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
-      EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
-    }
+    EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
     uids.emplace(pwd->pw_uid);
   }
   endpwent();
@@ -812,14 +809,7 @@
     EXPECT_STREQ(grp->gr_name, grp->gr_mem[0]) << "grp->gr_gid: " << grp->gr_gid;
     EXPECT_TRUE(grp->gr_mem[1] == nullptr) << "grp->gr_gid: " << grp->gr_gid;
 
-    // TODO(b/27999086): fix this check with the OEM range
-    // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
-    // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
-    // yet, so therefore we do not check for gid's in the OEM range.
-    if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
-        !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
-      EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
-    }
+    EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
     gids.emplace(grp->gr_gid);
   }
   endgrent();
@@ -830,6 +820,24 @@
 #endif
 }
 
+TEST(grp, getgrouplist) {
+#if defined(__BIONIC__)
+  // Query the number of groups.
+  int ngroups = 0;
+  ASSERT_EQ(-1, getgrouplist("root", 123, nullptr, &ngroups));
+  ASSERT_EQ(1, ngroups);
+
+  // Query the specific groups (just the one you pass in on Android).
+  ngroups = 8;
+  gid_t groups[ngroups];
+  ASSERT_EQ(1, getgrouplist("root", 123, groups, &ngroups));
+  ASSERT_EQ(1, ngroups);
+  ASSERT_EQ(123u, groups[0]);
+#else
+  GTEST_SKIP() << "bionic-only test (groups too unpredictable)";
+#endif
+}
+
 #if defined(__BIONIC__)
 static void TestAidNamePrefix(const std::string& file_path) {
   std::string file_contents;
diff --git a/tests/gtest_globals.cpp b/tests/gtest_globals.cpp
index 607544a..5b5ede8 100644
--- a/tests/gtest_globals.cpp
+++ b/tests/gtest_globals.cpp
@@ -24,12 +24,13 @@
 #include <string>
 
 std::string GetTestlibRoot() {
-  // Calculate ANDROID_DATA assuming the binary is in "$ANDROID_DATA/somedir/binary-dir/binary"
-  std::string path = android::base::Dirname(android::base::GetExecutablePath()) + "/..";
+  // 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() + "/..";
 
   std::string out_path;
   if (!android::base::Realpath(path.c_str(), &out_path)) {
-    printf("Failed to get realpath for \"%s\"", path.c_str());
+    printf("Failed to get realpath for \"%s\"\n", path.c_str());
     abort();
   }
 
@@ -37,7 +38,7 @@
 
   std::string real_path;
   if (!android::base::Realpath(out_path, &real_path)) {
-    printf("\"%s\": does not exists", out_path.c_str());
+    printf("\"%s\": does not exists\n", out_path.c_str());
     abort();
   }
 
diff --git a/tests/gtest_globals.h b/tests/gtest_globals.h
index b3c7b10..1bebb70 100644
--- a/tests/gtest_globals.h
+++ b/tests/gtest_globals.h
@@ -19,8 +19,10 @@
 
 #include <string>
 
-constexpr const char* kPrebuiltElfDir = "prebuilt-elf-files";
-
 std::string GetTestlibRoot();
 
+inline std::string GetPrebuiltElfDir() {
+  return GetTestlibRoot() + "/prebuilt-elf-files";
+}
+
 #endif  // _BIONIC_TESTS_GTEST_GLOBALS_H
diff --git a/tests/gtest_globals_cts.cpp b/tests/gtest_globals_cts.cpp
index 8e67f29..78bb3ca 100644
--- a/tests/gtest_globals_cts.cpp
+++ b/tests/gtest_globals_cts.cpp
@@ -16,17 +16,6 @@
 
 #include "gtest_globals.h"
 
-#include <string>
-#include <vector>
-
-// Use the normal gtest format so that cts can parse the results.
-extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) {
-  static const char* initial_args[] = {"--gtest_format"};
-  *args = initial_args;
-  *num_args = 1;
-  return true;
-}
-
 std::string GetTestlibRoot() {
   return "/data/local/tmp/lib/bionic-loader-test-libs";
 }
diff --git a/tests/headers/posix/strings_h.c b/tests/headers/posix/strings_h.c
index 0a2fa84..2051c8b 100644
--- a/tests/headers/posix/strings_h.c
+++ b/tests/headers/posix/strings_h.c
@@ -32,6 +32,10 @@
 
 static void strings_h() {
   FUNCTION(ffs, int (*f)(int));
+#if !defined(__GLIBC__)
+  FUNCTION(ffsl, int (*f)(long));
+  FUNCTION(ffsll, int (*f)(long long));
+#endif
   FUNCTION(strcasecmp, int (*f)(const char*, const char*));
   FUNCTION(strcasecmp_l, int (*f)(const char*, const char*, locale_t));
   FUNCTION(strncasecmp, int (*f)(const char*, const char*, size_t));
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
new file mode 100644
index 0000000..05123fd
--- /dev/null
+++ b/tests/heap_tagging_level_test.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+#include <sys/prctl.h>
+
+#if defined(__BIONIC__)
+#include "platform/bionic/malloc.h"
+#include "platform/bionic/mte.h"
+#include "utils.h"
+
+#include "SignalUtils.h"
+
+#include <bionic/malloc_tagged_pointers.h>
+
+static bool KernelSupportsTaggedPointers() {
+#ifdef __aarch64__
+  int res = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
+  return res >= 0 && res & PR_TAGGED_ADDR_ENABLE;
+#else
+  return false;
+#endif
+}
+
+static bool SetHeapTaggingLevel(HeapTaggingLevel level) {
+  return android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &level, sizeof(level));
+}
+#endif
+
+TEST(heap_tagging_level, tagged_pointer_dies) {
+#if defined(__BIONIC__)
+  if (!KernelSupportsTaggedPointers()) {
+    GTEST_SKIP() << "Kernel doesn't support tagged pointers.";
+  }
+
+#ifdef __aarch64__
+  if (mte_supported()) {
+    GTEST_SKIP() << "Tagged pointers are not used on MTE hardware.";
+  }
+
+  void *x = malloc(1);
+
+  // Ensure that `x` has a pointer tag.
+  EXPECT_NE(reinterpret_cast<uintptr_t>(x) >> 56, 0u);
+
+  x = untag_address(x);
+  EXPECT_DEATH(free(x), "Pointer tag for 0x[a-zA-Z0-9]* was truncated");
+
+  EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI));
+  EXPECT_DEATH(free(untag_address(malloc(1))), "Pointer tag for 0x[a-zA-Z0-9]* was truncated");
+
+  x = malloc(1);
+  void *y = malloc(1);
+  // Disable heap tagging.
+  EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
+  // Ensure an older tagged pointer can still be freed.
+  free(x);
+  // Tag mismatch is not detected on old pointers.
+  free(untag_address(y));
+#endif // defined(__aarch64__)
+#else
+  GTEST_SKIP() << "bionic-only test";
+#endif // defined(__BIONIC__)
+}
+
+#if defined(__BIONIC__) && defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
+template <int SiCode> void CheckSiCode(int, siginfo_t* info, void*) {
+  if (info->si_code != SiCode) {
+    _exit(2);
+  }
+  _exit(1);
+}
+
+static bool SetTagCheckingLevel(int level) {
+  int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
+  if (tagged_addr_ctrl < 0) {
+    return false;
+  }
+
+  tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | level;
+  return prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) == 0;
+}
+#endif
+
+TEST(heap_tagging_level, sync_async_bad_accesses_die) {
+#if defined(__BIONIC__) && defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
+  if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) {
+    GTEST_SKIP() << "requires MTE support";
+  }
+
+  std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
+
+  // First, check that memory tagging is enabled and the default tag checking level is async.
+  // We assume that scudo is used on all MTE enabled hardware; scudo inserts a header with a
+  // mismatching tag before each allocation.
+  EXPECT_EXIT(
+      {
+        ScopedSignalHandler ssh(SIGSEGV, CheckSiCode<SEGV_MTEAERR>, SA_SIGINFO);
+        p[-1] = 42;
+      },
+      testing::ExitedWithCode(1), "");
+
+  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_SYNC));
+  EXPECT_EXIT(
+      {
+        ScopedSignalHandler ssh(SIGSEGV, CheckSiCode<SEGV_MTESERR>, SA_SIGINFO);
+        p[-1] = 42;
+      },
+      testing::ExitedWithCode(1), "");
+
+  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_NONE));
+  volatile int oob ATTRIBUTE_UNUSED = p[-1];
+#endif
+}
+
+TEST(heap_tagging_level, none_pointers_untagged) {
+#if defined(__BIONIC__)
+#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
+  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_NONE));
+#endif
+
+  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());
+#else
+  GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
+TEST(heap_tagging_level, tagging_level_transitions) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+  if (!KernelSupportsTaggedPointers()) {
+    GTEST_SKIP() << "Kernel doesn't support tagged pointers.";
+  }
+
+#if defined(ANDROID_EXPERIMENTAL_MTE)
+  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_NONE));
+#endif
+
+  EXPECT_FALSE(SetHeapTaggingLevel(static_cast<HeapTaggingLevel>(12345)));
+
+  if (mte_supported()) {
+    // ASYNC -> ...
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI));
+    EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
+    EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC));
+
+    // SYNC -> ...
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI));
+    EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC));
+    EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
+  } else {
+    // TBI -> ...
+    EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_TBI));
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
+    EXPECT_FALSE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC));
+  }
+
+  // TBI -> NONE on non-MTE, ASYNC -> NONE on MTE.
+  EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
+
+  // NONE -> ...
+  EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_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));
+#else
+  GTEST_SKIP() << "bionic/arm64 only";
+#endif
+}
+
+TEST(heap_tagging_level, tagging_level_transition_sync_none) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+  // We can't test SYNC -> NONE in tagging_level_transitions because we can only make one transition
+  // to NONE (which we use to test ASYNC -> NONE), so we test it here separately.
+  if (!mte_supported()) {
+    GTEST_SKIP() << "requires MTE support";
+  }
+
+#if defined(ANDROID_EXPERIMENTAL_MTE)
+  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_NONE));
+#endif
+
+  EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC));
+  EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
+#else
+  GTEST_SKIP() << "bionic/arm64 only";
+#endif
+}
diff --git a/tests/ifunc_test.cpp b/tests/ifunc_test.cpp
index e69271f..e3c437e 100644
--- a/tests/ifunc_test.cpp
+++ b/tests/ifunc_test.cpp
@@ -44,7 +44,8 @@
 static uint64_t g_hwcap;
 static __ifunc_arg_t g_arg;
 
-extern "C" fn_ptr_t hwcap_resolver(uint64_t hwcap, __ifunc_arg_t* arg) {
+extern "C" fn_ptr_t hwcap_resolver(uint64_t hwcap, __ifunc_arg_t* arg)
+    __attribute__((no_sanitize("hwaddress"))) {
   g_hwcap = hwcap;
   g_arg = *arg;
   return ret42;
diff --git a/tests/leak_test.cpp b/tests/leak_test.cpp
index e0a3d57..4ebf41f 100644
--- a/tests/leak_test.cpp
+++ b/tests/leak_test.cpp
@@ -109,23 +109,21 @@
 
 // http://b/36045112
 TEST(pthread_leak, join) {
+  SKIP_WITH_NATIVE_BRIDGE;  // http://b/37920774
+
   LeakChecker lc;
 
-  for (size_t pass = 0; pass < 2; ++pass) {
-    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_join(thread, nullptr));
-    }
-
-    // A native bridge implementation might need a warm up pass to reach a steady state.
-    // http://b/37920774.
-    if (pass == 0) lc.Reset();
+  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_join(thread, nullptr));
   }
 }
 
 // http://b/36045112
 TEST(pthread_leak, detach) {
+  SKIP_WITH_NATIVE_BRIDGE;  // http://b/37920774
+
   LeakChecker lc;
 
   // Ancient devices with only 2 cores need a lower limit.
@@ -158,8 +156,7 @@
 
     WaitUntilAllThreadsExited(tids, thread_count);
 
-    // A native bridge implementation might need a warm up pass to reach a steady state.
-    // http://b/37920774.
+    // TODO(b/158573595): the test is flaky without the warmup pass.
     if (pass == 0) lc.Reset();
   }
 }
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index c427282..ef4fddd 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -79,6 +79,22 @@
     shared_libs: ["libtest_elftls_shared_var"],
 }
 
+cc_test {
+   name: "thread_exit_cb_helper.cpp",
+   defaults: ["bionic_testlib_defaults"],
+   srcs: ["thread_exit_cb_helper.cpp"],
+   cflags: ["-fno-emulated-tls"],
+}
+
+cc_test {
+   name: "tls_properties_helper",
+   defaults: ["bionic_testlib_defaults"],
+   srcs: ["tls_properties_helper.cpp"],
+   cflags: ["-fno-emulated-tls"],
+   shared_libs: ["libtest_elftls_shared_var"],
+}
+
+
 cc_test_library {
     name: "libtest_elftls_dynamic_filler_1",
     defaults: ["bionic_testlib_defaults"],
@@ -1268,6 +1284,7 @@
     name: "libtest_check_rtld_next_from_library",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["check_rtld_next_from_library.cpp"],
+    native_coverage: false,
 }
 
 // -----------------------------------------------------------------------------
diff --git a/tests/libs/dlopen_b.cpp b/tests/libs/dlopen_b.cpp
index cd81e16..092c96c 100644
--- a/tests/libs/dlopen_b.cpp
+++ b/tests/libs/dlopen_b.cpp
@@ -1,15 +1,14 @@
 #include <dlfcn.h>
 extern "C" void *dlopen_b() {
-  // TODO (dimitry): this is to work around http://b/20049306
-  // remove once it is fixed
-  static int dummy = 0;
+  // Work around for http://b/20049306, which isn't going to be fixed.
+  static int defeat_sibling_call_optimization = 0;
 
   // This is supposed to succeed because this library has DT_RUNPATH
   // for libtest_dt_runpath_x.so which should be taken into account
   // by dlopen.
   void *handle = dlopen("libtest_dt_runpath_x.so", RTLD_NOW);
   if (handle != nullptr) {
-    dummy++;
+    defeat_sibling_call_optimization++;
     return handle;
   }
   return nullptr;
diff --git a/tests/libs/elftls_dynamic.cpp b/tests/libs/elftls_dynamic.cpp
index 6da2f6f..2500484 100644
--- a/tests/libs/elftls_dynamic.cpp
+++ b/tests/libs/elftls_dynamic.cpp
@@ -41,8 +41,8 @@
 // section, but does not have an entry in the dynsym table and whose
 // solib-relative address appears to overlap with the large TLS variable.
 extern "C" void* get_local_addr() {
-  static char dummy[1024];
-  return &dummy[512];
+  static char buf[1024];
+  return &buf[512];
 }
 
 // This variable comes from libtest_elftls_shared_var.so, which is part of
diff --git a/tests/libs/segment_gap_outer.cpp b/tests/libs/segment_gap_outer.cpp
index fb448e7..3ba90d0 100644
--- a/tests/libs/segment_gap_outer.cpp
+++ b/tests/libs/segment_gap_outer.cpp
@@ -1,10 +1,9 @@
 #include <android/dlext.h>
 #include <dlfcn.h>
-#include <jni.h>
 #include <stdlib.h>
 
-extern "C" void text_before_start_of_gap() {}
-char end_of_gap[0x1000];
+extern "C" void __attribute__((section(".custom_text"))) text_before_start_of_gap() {}
+char __attribute__((section(".custom_bss"))) end_of_gap[0x1000];
 
 extern "C" void* get_inner() {
   android_dlextinfo info = {};
diff --git a/tests/libs/segment_gap_outer.lds b/tests/libs/segment_gap_outer.lds
index 0f175af..527f29e 100644
--- a/tests/libs/segment_gap_outer.lds
+++ b/tests/libs/segment_gap_outer.lds
@@ -2,25 +2,25 @@
   # This starts off fairly normal: rodata, text, dynamic, data, bss with
   # appropriate alignment between them.
   . = SIZEOF_HEADERS;
-  .rodata : {}
+  .rodata : {*(.rodata .rodata.*)}
   . = ALIGN(0x1000);
-  .text : {}
+  .text : {*(.text .text.*)}
   . = ALIGN(0x1000);
-  .dynamic : {}
+  .dynamic : {*(.dynamic)}
   . = ALIGN(0x1000);
-  .data : {}
-  .bss : {}
+  .data : {*(.data .data.*)}
+  .bss : {*(.bss .bss.*)}
 
   # Now create the gap. We need a text segment first to prevent the linker from
-  # merging .bss with .bss.end_of_gap.
+  # merging .bss with .custom_bss.
   . = ALIGN(0x1000);
-  .text.text_before_start_of_gap : {
-    *(.text.text_before_start_of_gap);
+  .custom_text : {
+    *(.custom_text);
   }
 
-  # Place end_of_gap at the end of the gap.
+  # Place custom_bss at the end of the gap.
   . = 0x1000000;
-  .bss.end_of_gap : {
-    *(.bss.*end_of_gap*);
+  .custom_bss : {
+    *(.custom_bss);
   }
 }
diff --git a/libc/arch-arm64/mte/bionic/strlen.c b/tests/libs/thread_exit_cb_helper.cpp
similarity index 62%
copy from libc/arch-arm64/mte/bionic/strlen.c
copy to tests/libs/thread_exit_cb_helper.cpp
index de88320..8ec1398 100644
--- a/libc/arch-arm64/mte/bionic/strlen.c
+++ b/tests/libs/thread_exit_cb_helper.cpp
@@ -26,7 +26,41 @@
  * SUCH DAMAGE.
  */
 
-#include <upstream-openbsd/android/include/openbsd-compat.h>
+// Prevent tests from being compiled with glibc because thread_properties.h
+// only exists in Bionic.
+#if defined(__BIONIC__)
 
-#define strlen strlen_mte
-#include <upstream-openbsd/lib/libc/string/strlen.c>
+#include <stdio.h>
+#include <sys/thread_properties.h>
+
+// Helper binary for testing thread_exit_cb registration.
+
+void exit_cb_1() {
+  printf("exit_cb_1 called ");
+}
+
+void exit_cb_2() {
+  printf("exit_cb_2 called ");
+}
+
+void exit_cb_3() {
+  printf("exit_cb_3 called");
+}
+
+void test_register_thread_exit_cb() {
+  // Register the exit-cb in reverse order (3,2,1)
+  // so that they'd be called in 1,2,3 order.
+  __libc_register_thread_exit_callback(&exit_cb_3);
+  __libc_register_thread_exit_callback(&exit_cb_2);
+  __libc_register_thread_exit_callback(&exit_cb_1);
+}
+
+int main() {
+  test_register_thread_exit_cb();
+  return 0;
+}
+#else
+int main() {
+  return 0;
+}
+#endif  // __BIONIC__
diff --git a/tests/libs/tls_properties_helper.cpp b/tests/libs/tls_properties_helper.cpp
new file mode 100644
index 0000000..3f8d118
--- /dev/null
+++ b/tests/libs/tls_properties_helper.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// Prevent tests from being compiled with glibc because thread_properties.h
+// only exists in Bionic.
+#if defined(__BIONIC__)
+
+#include <sys/thread_properties.h>
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unistd.h>  // for gettid
+
+// Helper binary to use TLS-related functions in thread_properties
+
+// Tests __get_static_tls_bound.
+thread_local int local_var;
+void test_static_tls_bounds() {
+  local_var = 123;
+  void* start_addr = nullptr;
+  void* end_addr = nullptr;
+
+  __libc_get_static_tls_bounds(reinterpret_cast<void**>(&start_addr),
+                               reinterpret_cast<void**>(&end_addr));
+  assert(start_addr != nullptr);
+  assert(end_addr != nullptr);
+
+  assert(&local_var >= start_addr && &local_var < end_addr);
+
+  printf("done_get_static_tls_bounds\n");
+}
+
+// Tests iterate_dynamic tls chunks.
+// Export a var from the shared so.
+__thread char large_tls_var[4 * 1024 * 1024];
+void test_iter_tls() {
+  void* lib = dlopen("libtest_elftls_dynamic.so", RTLD_LOCAL | RTLD_NOW);
+
+  int i = 0;
+  auto cb = [&](void* dtls_begin, void* dtls_end, size_t dso_id, void* arg) {
+    printf("iterate_cb i = %d\n", i++);
+  };
+  __libc_iterate_dynamic_tls(gettid(), cb, nullptr);
+  printf("done_iterate_dynamic_tls\n");
+}
+
+int main() {
+  test_static_tls_bounds();
+  test_iter_tls();
+  return 0;
+}
+
+#else
+int main() {
+  return 0;
+}
+#endif  // __BIONIC__
diff --git a/tests/link_test.cpp b/tests/link_test.cpp
index 75bb4d6..127a3d9 100644
--- a/tests/link_test.cpp
+++ b/tests/link_test.cpp
@@ -258,7 +258,7 @@
   ASSERT_TRUE(entries != nullptr);
   ASSERT_GT(count, 0);
 
-  // Sanity checks
+  // Validity checks.
   uintptr_t func = reinterpret_cast<uintptr_t>(read_exidx_func);
   bool found = false;
   for (int i = 0; i < count; ++i) {
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 5944414..55bd149 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -662,6 +662,46 @@
 #endif
 }
 
+#if defined(__BIONIC__)
+static void GetAllocatorVersion(bool* allocator_scudo) {
+  TemporaryFile tf;
+  ASSERT_TRUE(tf.fd != -1);
+  FILE* fp = fdopen(tf.fd, "w+");
+  tf.release();
+  ASSERT_TRUE(fp != nullptr);
+  ASSERT_EQ(0, malloc_info(0, fp));
+  ASSERT_EQ(0, fclose(fp));
+
+  std::string contents;
+  ASSERT_TRUE(android::base::ReadFileToString(tf.path, &contents));
+
+  tinyxml2::XMLDocument doc;
+  ASSERT_EQ(tinyxml2::XML_SUCCESS, doc.Parse(contents.c_str()));
+
+  auto root = doc.FirstChildElement();
+  ASSERT_NE(nullptr, root);
+  ASSERT_STREQ("malloc", root->Name());
+  std::string version(root->Attribute("version"));
+  *allocator_scudo = (version == "scudo-1");
+}
+#endif
+
+TEST(malloc, mallopt_scudo_only_options) {
+#if defined(__BIONIC__)
+  SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
+  bool allocator_scudo;
+  GetAllocatorVersion(&allocator_scudo);
+  if (!allocator_scudo) {
+    GTEST_SKIP() << "scudo allocator only test";
+  }
+  ASSERT_EQ(1, mallopt(M_CACHE_COUNT_MAX, 100));
+  ASSERT_EQ(1, mallopt(M_CACHE_SIZE_MAX, 1024 * 1024 * 2));
+  ASSERT_EQ(1, mallopt(M_TSDS_COUNT_MAX, 8));
+#else
+  GTEST_SKIP() << "bionic-only test";
+#endif
+}
+
 TEST(malloc, reallocarray_overflow) {
 #if HAVE_REALLOCARRAY
   // Values that cause overflow to a result small enough (8 on LP64) that malloc would "succeed".
@@ -1201,70 +1241,3 @@
   GTEST_SKIP() << "bionic extension";
 #endif
 }
-
-#if defined(__BIONIC__) && defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
-template <int SiCode> void CheckSiCode(int, siginfo_t* info, void*) {
-  if (info->si_code != SiCode) {
-    _exit(2);
-  }
-  _exit(1);
-}
-
-static bool SetTagCheckingLevel(int level) {
-  int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
-  if (tagged_addr_ctrl < 0) {
-    return false;
-  }
-
-  tagged_addr_ctrl = (tagged_addr_ctrl & ~PR_MTE_TCF_MASK) | level;
-  return prctl(PR_SET_TAGGED_ADDR_CTRL, tagged_addr_ctrl, 0, 0, 0) == 0;
-}
-#endif
-
-TEST(android_mallopt, tag_level) {
-#if defined(__BIONIC__) && defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
-  if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) {
-    GTEST_SKIP() << "requires MTE support";
-    return;
-  }
-
-  std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
-
-  // First, check that memory tagging is enabled and the default tag checking level is async.
-  // We assume that scudo is used on all MTE enabled hardware; scudo inserts a header with a
-  // mismatching tag before each allocation.
-  EXPECT_EXIT(
-      {
-        ScopedSignalHandler ssh(SIGSEGV, CheckSiCode<SEGV_MTEAERR>, SA_SIGINFO);
-        p[-1] = 42;
-      },
-      testing::ExitedWithCode(1), "");
-
-  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_SYNC));
-  EXPECT_EXIT(
-      {
-        ScopedSignalHandler ssh(SIGSEGV, CheckSiCode<SEGV_MTESERR>, SA_SIGINFO);
-        p[-1] = 42;
-      },
-      testing::ExitedWithCode(1), "");
-
-  EXPECT_TRUE(SetTagCheckingLevel(PR_MTE_TCF_NONE));
-  volatile int oob ATTRIBUTE_UNUSED = p[-1];
-
-  HeapTaggingLevel tag_level = M_HEAP_TAGGING_LEVEL_TBI;
-  EXPECT_FALSE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-
-  tag_level = M_HEAP_TAGGING_LEVEL_NONE;
-  EXPECT_TRUE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-  std::unique_ptr<int[]> p2 = std::make_unique<int[]>(4);
-  EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(p2.get()) >> 56);
-
-  tag_level = M_HEAP_TAGGING_LEVEL_ASYNC;
-  EXPECT_FALSE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-
-  tag_level = M_HEAP_TAGGING_LEVEL_NONE;
-  EXPECT_TRUE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-#else
-  GTEST_SKIP() << "arm64 only";
-#endif
-}
diff --git a/tests/mte_test.cpp b/tests/mte_test.cpp
index 8928805..f329d8d 100644
--- a/tests/mte_test.cpp
+++ b/tests/mte_test.cpp
@@ -14,10 +14,15 @@
  * limitations under the License.
  */
 
+#include <sys/cdefs.h>
+
+#if defined(__BIONIC__)
+
 #include <gtest/gtest.h>
 
 #include <android-base/macros.h>
 #include <bionic/mte.h>
+#include "utils.h"
 
 __attribute__((no_sanitize("hwaddress")))
 static void test_tag_mismatch() {
@@ -44,5 +49,12 @@
 }
 
 TEST(mte_test, ScopedDisableMTE) {
+  // With native_bridge, native and emulated parts exchange data, including pointers.
+  // This implies tagging on native and emulated architectures should match, which is
+  // not the case at the moment.
+  SKIP_WITH_NATIVE_BRIDGE;
+
   test_tag_mismatch();
 }
+
+#endif  // __BIONIC__
diff --git a/tests/netinet_ether_test.cpp b/tests/netinet_ether_test.cpp
index faa3db4..af020ec 100644
--- a/tests/netinet_ether_test.cpp
+++ b/tests/netinet_ether_test.cpp
@@ -34,7 +34,7 @@
 TEST(netinet_ether, ether_aton_r__ether_ntoa_r) {
   ether_addr addr;
   memset(&addr, 0, sizeof(addr));
-  ether_addr* a = ether_aton_r("12:34:56:78:9a:bc", &addr);
+  ether_addr* a = ether_aton_r("12:34:56:78:9a:Bc", &addr);
   ASSERT_EQ(&addr, a);
   ASSERT_EQ(0x12, addr.ether_addr_octet[0]);
   ASSERT_EQ(0x34, addr.ether_addr_octet[1]);
@@ -49,3 +49,11 @@
   ASSERT_EQ(buf, p);
   ASSERT_STREQ("12:34:56:78:9a:bc", buf);
 }
+
+TEST(netinet_ether, ether_aton_r_failures) {
+  ether_addr addr;
+  ASSERT_TRUE(ether_aton_r("12:34:56:78:9a;bc", &addr) == nullptr);
+  ASSERT_TRUE(ether_aton_r("12:34:56:78:9a:bc ", &addr) == nullptr);
+  ASSERT_TRUE(ether_aton_r("g2:34:56:78:9a:bc ", &addr) == nullptr);
+  ASSERT_TRUE(ether_aton_r("1G:34:56:78:9a:bc ", &addr) == nullptr);
+}
diff --git a/tests/netinet_in_test.cpp b/tests/netinet_in_test.cpp
index 2606082..437e180 100644
--- a/tests/netinet_in_test.cpp
+++ b/tests/netinet_in_test.cpp
@@ -31,8 +31,15 @@
 static constexpr uint64_t be64 = 0xf0debc9a78563412;
 
 TEST(netinet_in, bindresvport) {
-  // This isn't something we can usually test, so just check the symbol's there.
+  // 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));
+
+  // Only AF_INET is supported.
+  sockaddr_in sin = {.sin_family = AF_INET6};
+  errno = 0;
+  ASSERT_EQ(-1, bindresvport(-1, &sin));
+  ASSERT_EQ(EPFNOSUPPORT, errno);
 }
 
 TEST(netinet_in, in6addr_any) {
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index d825738..851b86f 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -2821,6 +2821,9 @@
 }
 
 TEST(pthread, pthread_create__mmap_failures) {
+  // After thread is successfully created, native_bridge might need more memory to run it.
+  SKIP_WITH_NATIVE_BRIDGE;
+
   pthread_attr_t attr;
   ASSERT_EQ(0, pthread_attr_init(&attr));
   ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
index 29f86f1..d5d8994 100644
--- a/tests/pty_test.cpp
+++ b/tests/pty_test.cpp
@@ -28,34 +28,34 @@
 #include "utils.h"
 
 TEST(pty, openpty) {
-  int master, slave;
+  int pty, tty;
   char name[32];
   struct winsize w = { 123, 456, 9999, 999 };
-  ASSERT_EQ(0, openpty(&master, &slave, name, nullptr, &w));
-  ASSERT_NE(-1, master);
-  ASSERT_NE(-1, slave);
-  ASSERT_NE(master, slave);
+  ASSERT_EQ(0, openpty(&pty, &tty, name, nullptr, &w));
+  ASSERT_NE(-1, pty);
+  ASSERT_NE(-1, tty);
+  ASSERT_NE(pty, tty);
 
   char tty_name[32];
-  ASSERT_EQ(0, ttyname_r(slave, tty_name, sizeof(tty_name)));
+  ASSERT_EQ(0, ttyname_r(tty, tty_name, sizeof(tty_name)));
   ASSERT_STREQ(tty_name, name);
 
   struct winsize w_actual;
-  ASSERT_EQ(0, ioctl(slave, TIOCGWINSZ, &w_actual));
+  ASSERT_EQ(0, ioctl(tty, TIOCGWINSZ, &w_actual));
   ASSERT_EQ(w_actual.ws_row, w.ws_row);
   ASSERT_EQ(w_actual.ws_col, w.ws_col);
   ASSERT_EQ(w_actual.ws_xpixel, w.ws_xpixel);
   ASSERT_EQ(w_actual.ws_ypixel, w.ws_ypixel);
 
-  close(master);
-  close(slave);
+  close(pty);
+  close(tty);
 }
 
 TEST(pty, forkpty) {
   pid_t sid = getsid(0);
 
-  int master;
-  pid_t pid = forkpty(&master, nullptr, nullptr, nullptr);
+  int pty;
+  pid_t pid = forkpty(&pty, nullptr, nullptr, nullptr);
   ASSERT_NE(-1, pid);
 
   if (pid == 0) {
@@ -68,12 +68,12 @@
 
   AssertChildExited(pid, 0);
 
-  close(master);
+  close(pty);
 }
 
 struct PtyReader_28979140_Arg {
   int main_cpu_id;
-  int slave_fd;
+  int fd;
   uint32_t data_count;
   bool finished;
   std::atomic<bool> matched;
@@ -90,7 +90,7 @@
   while (counter <= arg->data_count) {
     char buf[4096];  // Use big buffer to read to hit the bug more easily.
     size_t to_read = std::min(sizeof(buf), (arg->data_count + 1 - counter) * sizeof(uint32_t));
-    ASSERT_TRUE(android::base::ReadFully(arg->slave_fd, buf, to_read));
+    ASSERT_TRUE(android::base::ReadFully(arg->fd, buf, to_read));
     size_t num_of_value = to_read / sizeof(uint32_t);
     uint32_t* p = reinterpret_cast<uint32_t*>(buf);
     while (num_of_value-- > 0) {
@@ -99,7 +99,7 @@
       }
     }
   }
-  close(arg->slave_fd);
+  close(arg->fd);
   arg->finished = true;
 }
 
@@ -114,16 +114,16 @@
   constexpr uint32_t TEST_DATA_COUNT = 2000000;
 
   // 1. Open raw pty.
-  int master;
-  int slave;
-  ASSERT_EQ(0, openpty(&master, &slave, nullptr, nullptr, nullptr));
+  int pty;
+  int tty;
+  ASSERT_EQ(0, openpty(&pty, &tty, nullptr, nullptr, nullptr));
   termios tattr;
-  ASSERT_EQ(0, tcgetattr(slave, &tattr));
+  ASSERT_EQ(0, tcgetattr(tty, &tattr));
   cfmakeraw(&tattr);
-  ASSERT_EQ(0, tcsetattr(slave, TCSADRAIN, &tattr));
+  ASSERT_EQ(0, tcsetattr(tty, TCSADRAIN, &tattr));
 
-  // 2. Make master thread and slave thread running on different cpus:
-  // master thread uses first available cpu, and slave thread uses other cpus.
+  // 2. Make two threads running on different cpus:
+  // pty thread uses first available cpu, and tty thread uses other cpus.
   PtyReader_28979140_Arg arg;
   arg.main_cpu_id = -1;
   for (int i = 0; i < CPU_SETSIZE; i++) {
@@ -134,9 +134,9 @@
   }
   ASSERT_GE(arg.main_cpu_id, 0);
 
-  // 3. Create thread for slave reader.
+  // 3. Create thread for tty reader.
   pthread_t thread;
-  arg.slave_fd = slave;
+  arg.fd = tty;
   arg.data_count = TEST_DATA_COUNT;
   arg.matched = true;
   ASSERT_EQ(0, pthread_create(&thread, nullptr,
@@ -147,7 +147,7 @@
   CPU_SET(arg.main_cpu_id, &cpus);
   ASSERT_EQ(0, sched_setaffinity(0, sizeof(cpu_set_t), &cpus));
 
-  // 4. Send data to slave.
+  // 4. Send data to tty reader.
   // Send a bunch of data at a time, so it is easier to catch the bug that some data isn't seen
   // by the reader thread on another cpu.
   uint32_t counter_buf[100];
@@ -156,11 +156,11 @@
     for (size_t i = 0; i < sizeof(counter_buf) / sizeof(counter_buf[0]); ++i) {
       counter_buf[i] = counter++;
     }
-    ASSERT_TRUE(android::base::WriteFully(master, &counter_buf, sizeof(counter_buf)));
+    ASSERT_TRUE(android::base::WriteFully(pty, &counter_buf, sizeof(counter_buf)));
     ASSERT_TRUE(arg.matched) << "failed at count = " << counter;
   }
   ASSERT_EQ(0, pthread_join(thread, nullptr));
   ASSERT_TRUE(arg.finished);
   ASSERT_TRUE(arg.matched);
-  close(master);
+  close(pty);
 }
diff --git a/tests/sched_test.cpp b/tests/sched_test.cpp
index 9309a7f..03e8062 100644
--- a/tests/sched_test.cpp
+++ b/tests/sched_test.cpp
@@ -301,3 +301,7 @@
   // don't behave as POSIX specifies. http://b/26203902.
   ASSERT_EQ(0, sched_setscheduler(getpid(), original_policy, &p));
 }
+
+TEST(sched, sched_getaffinity_failure) {
+  ASSERT_EQ(-1, sched_getaffinity(getpid(), 0, nullptr));
+}
diff --git a/tests/search_test.cpp b/tests/search_test.cpp
index 1509199..8b8359d 100644
--- a/tests/search_test.cpp
+++ b/tests/search_test.cpp
@@ -114,6 +114,11 @@
   ASSERT_EQ(3U, g_free_calls);
 }
 
+TEST(search, tdestroy_null) {
+  // It's okay to pass a null node, and your callback will not be called.
+  tdestroy(nullptr, nullptr);
+}
+
 struct pod_node {
   explicit pod_node(int i) : i(i) {}
   int i;
@@ -285,3 +290,26 @@
   AssertEntry(e, "a", "B");
   hdestroy_r(&h2);
 }
+
+TEST(search, hsearch_resizing) {
+  ASSERT_NE(0, hcreate(1));
+
+  std::vector<char*> entries;
+  // Add enough entries to ensure that we've had to resize.
+  for (char ch = ' '; ch <= '~'; ++ch) {
+    char* p;
+    asprintf(&p, "%c", ch);
+    ENTRY e;
+    e.data = e.key = p;
+    ASSERT_TRUE(hsearch(e, ENTER) != nullptr);
+    entries.push_back(p);
+  }
+
+  // Check they're all there.
+  for (auto& p : entries) {
+    ENTRY* e = hsearch(ENTRY{.key = p, .data = nullptr}, FIND);
+    AssertEntry(e, p, p);
+  }
+
+  for (auto& p : entries) free(p);
+}
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 3c66034..f465458 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -154,44 +154,6 @@
   raise(SIGALRM);
 }
 
-TEST(signal, sigwait_SIGALRM) {
-  ScopedSignalHandler ssh(SIGALRM, [](int sig) { ASSERT_EQ(SIGALRM, sig); });
-
-  sigset_t wait_set;
-  sigemptyset(&wait_set);
-  sigaddset(&wait_set, SIGALRM);
-
-  alarm(1);
-
-  int received_signal;
-  errno = 0;
-  ASSERT_EQ(0, sigwait(&wait_set, &received_signal));
-  ASSERT_EQ(0, errno);
-  ASSERT_EQ(SIGALRM, received_signal);
-}
-
-TEST(signal, sigwait64_SIGRTMIN) {
-  ScopedSignalHandler ssh(SIGRTMIN, [](int sig) { ASSERT_EQ(SIGRTMIN, sig); });
-
-  sigset64_t wait_set;
-  sigemptyset64(&wait_set);
-  sigaddset64(&wait_set, SIGRTMIN);
-
-  pid_t tid = gettid();
-  std::thread thread([&tid]() {
-    sleep(1);
-    tgkill(getpid(), tid, SIGRTMIN);
-  });
-
-  int received_signal;
-  errno = 0;
-  ASSERT_EQ(0, sigwait64(&wait_set, &received_signal));
-  ASSERT_EQ(0, errno);
-  ASSERT_EQ(SIGRTMIN, received_signal);
-
-  thread.join();
-}
-
 static int g_sigsuspend_signal_handler_call_count = 0;
 
 TEST(signal, sigsuspend_sigpending) {
@@ -620,8 +582,7 @@
 
 TEST(signal, sigqueue) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
@@ -630,8 +591,7 @@
 
 TEST(signal, pthread_sigqueue_self) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   errno = 0;
   ASSERT_EQ(0, pthread_sigqueue(pthread_self(), SIGALRM, sigval));
   ASSERT_EQ(0, errno);
@@ -640,8 +600,7 @@
 
 TEST(signal, pthread_sigqueue_other) {
   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
 
   sigset_t mask;
   sigfillset(&mask);
@@ -664,6 +623,44 @@
   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
 }
 
+TEST(signal, sigwait_SIGALRM) {
+  SignalMaskRestorer smr;
+
+  // Block SIGALRM.
+  sigset_t just_SIGALRM;
+  sigemptyset(&just_SIGALRM);
+  sigaddset(&just_SIGALRM, SIGALRM);
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
+
+  // Raise SIGALRM.
+  sigval_t sigval = {.sival_int = 1};
+  ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
+
+  // Get pending SIGALRM.
+  int sig;
+  ASSERT_EQ(0, sigwait(&just_SIGALRM, &sig));
+  ASSERT_EQ(SIGALRM, sig);
+}
+
+TEST(signal, sigwait64_SIGRTMIN) {
+  SignalMaskRestorer smr;
+
+  // Block SIGRTMIN.
+  sigset64_t just_SIGRTMIN;
+  sigemptyset64(&just_SIGRTMIN);
+  sigaddset64(&just_SIGRTMIN, SIGRTMIN);
+  ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
+
+  // Raise SIGRTMIN.
+  sigval_t sigval = {.sival_int = 1};
+  ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
+
+  // Get pending SIGRTMIN.
+  int sig;
+  ASSERT_EQ(0, sigwait64(&just_SIGRTMIN, &sig));
+  ASSERT_EQ(SIGRTMIN, sig);
+}
+
 TEST(signal, sigwaitinfo) {
   SignalMaskRestorer smr;
 
@@ -674,8 +671,7 @@
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
 
   // Get pending SIGALRM.
@@ -697,8 +693,7 @@
   ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
 
   // Raise SIGRTMIN.
-  sigval_t sigval;
-  sigval.sival_int = 1;
+  sigval_t sigval = {.sival_int = 1};
   ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
 
   // Get pending SIGRTMIN.
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index e620ecd..0ff6f30 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -112,10 +112,6 @@
 }
 
 TEST(stack_unwinding, unwind_through_signal_frame) {
-#if defined(__i386__)
-  GTEST_SKIP() << "Temporarily skip test since it fails on x86 see b/132763120.";
-#endif
-
   ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
 
   UnwindTest();
@@ -123,10 +119,6 @@
 
 // On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore.
 TEST(stack_unwinding, unwind_through_signal_frame_SA_SIGINFO) {
-#if defined(__i386__)
-  GTEST_SKIP() << "Temporarily skip test since it fails on x86 see b/132763120.";
-#endif
-
   ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO);
 
   UnwindTest();
diff --git a/tests/stdatomic_test.cpp b/tests/stdatomic_test.cpp
index 8a6b267..7b98df2 100644
--- a/tests/stdatomic_test.cpp
+++ b/tests/stdatomic_test.cpp
@@ -181,7 +181,7 @@
 
 // And a rudimentary test of acquire-release memory ordering:
 
-constexpr static uint_least32_t BIG = 10000000ul; // Assumed even below.
+constexpr static uint_least32_t BIG = 30'000'000ul; // Assumed even below.
 
 struct three_atomics {
   atomic_uint_least32_t x;
@@ -192,7 +192,7 @@
   atomic_uint_least32_t z;
 };
 
-// Very simple acquire/release memory ordering sanity check.
+// Very simple acquire/release memory ordering smoke test.
 static void* writer(void* arg) {
   three_atomics* a = reinterpret_cast<three_atomics*>(arg);
   for (uint_least32_t i = 0; i <= BIG; i+=2) {
@@ -239,7 +239,7 @@
 }
 
 TEST(stdatomic, ordering) {
-  // Run a memory ordering sanity test.
+  // Run a memory ordering smoke test.
   void* result;
   three_atomics a;
   atomic_init(&a.x, 0ul);
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 75abbd2..c21c3b8 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -294,6 +294,34 @@
   EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
 }
 
+// http://b/152588929
+TEST(STDIO_TEST, snprintf_La) {
+#if defined(__LP64__)
+  char buf[BUFSIZ];
+  union {
+    uint64_t a[2];
+    long double v;
+  } u;
+
+  u.a[0] = UINT64_C(0x9b9b9b9b9b9b9b9b);
+  u.a[1] = UINT64_C(0xdfdfdfdfdfdfdfdf);
+  EXPECT_EQ(41, snprintf(buf, sizeof(buf), "<%La>", u.v));
+  EXPECT_STREQ("<-0x1.dfdfdfdfdfdf9b9b9b9b9b9b9b9bp+8160>", buf);
+
+  u.a[0] = UINT64_C(0xffffffffffffffff);
+  u.a[1] = UINT64_C(0x7ffeffffffffffff);
+  EXPECT_EQ(41, snprintf(buf, sizeof(buf), "<%La>", u.v));
+  EXPECT_STREQ("<0x1.ffffffffffffffffffffffffffffp+16383>", buf);
+
+  u.a[0] = UINT64_C(0x0000000000000000);
+  u.a[1] = UINT64_C(0x0000000000000000);
+  EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%La>", u.v));
+  EXPECT_STREQ("<0x0p+0>", buf);
+#else
+  GTEST_SKIP() << "no ld128";
+#endif
+}
+
 TEST(STDIO_TEST, snprintf_lc) {
   char buf[BUFSIZ];
   wint_t wc = L'a';
@@ -343,6 +371,11 @@
 #endif
 }
 
+TEST(STDIO_TEST, snprintf_measure) {
+  char buf[16];
+  ASSERT_EQ(11, snprintf(buf, 0, "Hello %s", "world"));
+}
+
 TEST(STDIO_TEST, snprintf_smoke) {
   char buf[BUFSIZ];
 
@@ -1127,7 +1160,6 @@
   free(p1);
 }
 
-
 TEST(STDIO_TEST, sscanf_mlc) {
   // This is so useless that clang doesn't even believe it exists...
 #pragma clang diagnostic push
@@ -1161,7 +1193,6 @@
 #pragma clang diagnostic pop
 }
 
-
 TEST(STDIO_TEST, sscanf_ms) {
   CheckScanfM(sscanf, "hello", "%ms", 1, "hello");
   CheckScanfM(sscanf, "hello", "%4ms", 1, "hell");
@@ -2505,6 +2536,16 @@
   eth.Run([&]() { exit(puts("a b c")); }, 0, "a b c\n");
 }
 
+TEST(STDIO_TEST, putchar) {
+  ExecTestHelper eth;
+  eth.Run([&]() { exit(putchar('A')); }, 65, "A");
+}
+
+TEST(STDIO_TEST, putchar_unlocked) {
+  ExecTestHelper eth;
+  eth.Run([&]() { exit(putchar('B')); }, 66, "B");
+}
+
 TEST(STDIO_TEST, unlocked) {
   TemporaryFile tf;
 
@@ -2705,3 +2746,73 @@
  ASSERT_NE(0, RENAME_WHITEOUT);
 #endif
 }
+
+TEST(STDIO_TEST, fdopen_failures) {
+  FILE* fp;
+  int fd = open("/proc/version", O_RDONLY);
+  ASSERT_TRUE(fd != -1);
+
+  // Nonsense mode.
+  errno = 0;
+  fp = fdopen(fd, "nonsense");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EINVAL, errno);
+
+  // Mode that isn't a subset of the fd's actual mode.
+  errno = 0;
+  fp = fdopen(fd, "w");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EINVAL, errno);
+
+  // Can't set append on the underlying fd.
+  errno = 0;
+  fp = fdopen(fd, "a");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EINVAL, errno);
+
+  // Bad fd.
+  errno = 0;
+  fp = fdopen(-1, "re");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EBADF, errno);
+
+  close(fd);
+}
+
+TEST(STDIO_TEST, fmemopen_invalid_mode) {
+  errno = 0;
+  FILE* fp = fmemopen(nullptr, 16, "nonsense");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, fopen_invalid_mode) {
+  errno = 0;
+  FILE* fp = fopen("/proc/version", "nonsense");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, freopen_invalid_mode) {
+  FILE* fp = fopen("/proc/version", "re");
+  ASSERT_TRUE(fp != nullptr);
+
+  errno = 0;
+  fp = freopen("/proc/version", "nonsense", fp);
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(EINVAL, errno);
+}
+
+TEST(STDIO_TEST, asprintf_smoke) {
+  char* p = nullptr;
+  ASSERT_EQ(11, asprintf(&p, "hello %s", "world"));
+  ASSERT_STREQ("hello world", p);
+  free(p);
+}
+
+TEST(STDIO_TEST, fopen_ENOENT) {
+  errno = 0;
+  FILE* fp = fopen("/proc/does-not-exist", "re");
+  ASSERT_TRUE(fp == nullptr);
+  ASSERT_EQ(ENOENT, errno);
+}
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 3f1ec86..c7b2ad8 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -800,10 +800,25 @@
   ASSERT_EQ(T(0), fn("123", &end_p, 37));
   ASSERT_EQ(EINVAL, errno);
 
+  // Both leading + or - are always allowed (even for the strtou* family).
+  ASSERT_EQ(T(-123), fn("-123", &end_p, 10));
+  ASSERT_EQ(T(123), fn("+123", &end_p, 10));
+
   // If we see "0x" *not* followed by a hex digit, we shouldn't swallow the 'x'.
   ASSERT_EQ(T(0), fn("0xy", &end_p, 16));
   ASSERT_EQ('x', *end_p);
 
+  // Hexadecimal (both the 0x and the digits) is case-insensitive.
+  ASSERT_EQ(T(0xab), fn("0xab", &end_p, 0));
+  ASSERT_EQ(T(0xab), fn("0Xab", &end_p, 0));
+  ASSERT_EQ(T(0xab), fn("0xAB", &end_p, 0));
+  ASSERT_EQ(T(0xab), fn("0XAB", &end_p, 0));
+  ASSERT_EQ(T(0xab), fn("0xAb", &end_p, 0));
+  ASSERT_EQ(T(0xab), fn("0XAb", &end_p, 0));
+
+  // Octal lives! (Sadly.)
+  ASSERT_EQ(T(0666), fn("0666", &end_p, 0));
+
   if (std::numeric_limits<T>::is_signed) {
     // Minimum (such as -128).
     std::string min{std::to_string(std::numeric_limits<T>::min())};
@@ -878,6 +893,18 @@
   CheckStrToInt(strtoumax);
 }
 
+TEST(stdlib, atoi) {
+  // Implemented using strtol in bionic, so extensive testing unnecessary.
+  ASSERT_EQ(123, atoi("123four"));
+  ASSERT_EQ(0, atoi("hello"));
+}
+
+TEST(stdlib, atol) {
+  // Implemented using strtol in bionic, so extensive testing unnecessary.
+  ASSERT_EQ(123L, atol("123four"));
+  ASSERT_EQ(0L, atol("hello"));
+}
+
 TEST(stdlib, abs) {
   ASSERT_EQ(INT_MAX, abs(-INT_MAX));
   ASSERT_EQ(INT_MAX, abs(INT_MAX));
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 0ed0598..22be852 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -64,6 +64,11 @@
   ASSERT_STREQ("Unknown error 134", strerror(EHWPOISON + 1));
 }
 
+TEST(STRING_TEST, strerror_l) {
+  // bionic just forwards to strerror(3).
+  ASSERT_STREQ("Success", strerror_l(0, LC_GLOBAL_LOCALE));
+}
+
 #if defined(__BIONIC__)
 static void* ConcurrentStrErrorFn(void*) {
   bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
@@ -1538,13 +1543,31 @@
 }
 
 TEST(STRING_TEST, memmem_smoke) {
-  const char haystack[] = "big\0daddy\0giant\0haystacks";
-  ASSERT_EQ(haystack, memmem(haystack, sizeof(haystack), "", 0));
-  ASSERT_EQ(haystack + 3, memmem(haystack, sizeof(haystack), "", 1));
+  const char haystack[] = "big\0daddy/giant\0haystacks!";
+
+  // The current memmem() implementation has special cases for needles of
+  // lengths 0, 1, 2, 3, and 4, plus a long needle case. We test matches at the
+  // beginning, middle, and end of the haystack.
+
+  ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "", 0));
+
   ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "b", 1));
-  ASSERT_EQ(haystack + 1, memmem(haystack, sizeof(haystack), "i", 1));
-  ASSERT_EQ(haystack + 4, memmem(haystack, sizeof(haystack), "da", 2));
-  ASSERT_EQ(haystack + 8, memmem(haystack, sizeof(haystack), "y\0g", 3));
+  ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "bi", 2));
+  ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big", 3));
+  ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big\0", 4));
+  ASSERT_EQ(haystack + 0, memmem(haystack, sizeof(haystack), "big\0d", 5));
+
+  ASSERT_EQ(haystack + 2, memmem(haystack, sizeof(haystack), "g", 1));
+  ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gi", 2));
+  ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gia", 3));
+  ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "gian", 4));
+  ASSERT_EQ(haystack + 10, memmem(haystack, sizeof(haystack), "giant", 5));
+
+  ASSERT_EQ(haystack + 25, memmem(haystack, sizeof(haystack), "!", 1));
+  ASSERT_EQ(haystack + 24, memmem(haystack, sizeof(haystack), "s!", 2));
+  ASSERT_EQ(haystack + 23, memmem(haystack, sizeof(haystack), "ks!", 3));
+  ASSERT_EQ(haystack + 22, memmem(haystack, sizeof(haystack), "cks!", 4));
+  ASSERT_EQ(haystack + 21, memmem(haystack, sizeof(haystack), "acks!", 5));
 }
 
 TEST(STRING_TEST, strstr_smoke) {
@@ -1589,16 +1612,44 @@
   ASSERT_TRUE(strcoll("aac", "aab") > 0);
 }
 
+TEST(STRING_TEST, strcoll_l_smoke) {
+  // bionic just forwards to strcoll(3).
+  ASSERT_TRUE(strcoll_l("aab", "aac", LC_GLOBAL_LOCALE) < 0);
+  ASSERT_TRUE(strcoll_l("aab", "aab", LC_GLOBAL_LOCALE) == 0);
+  ASSERT_TRUE(strcoll_l("aac", "aab", LC_GLOBAL_LOCALE) > 0);
+}
+
 TEST(STRING_TEST, strxfrm_smoke) {
   const char* src1 = "aab";
   char dst1[16] = {};
-  ASSERT_GT(strxfrm(dst1, src1, sizeof(dst1)), 0U);
+  // Dry run.
+  ASSERT_EQ(strxfrm(dst1, src1, 0), 3U);
+  ASSERT_STREQ(dst1, "");
+  // Really do it.
+  ASSERT_EQ(strxfrm(dst1, src1, sizeof(dst1)), 3U);
+
   const char* src2 = "aac";
   char dst2[16] = {};
-  ASSERT_GT(strxfrm(dst2, src2, sizeof(dst2)), 0U);
+  // Dry run.
+  ASSERT_EQ(strxfrm(dst2, src2, 0), 3U);
+  ASSERT_STREQ(dst2, "");
+  // Really do it.
+  ASSERT_EQ(strxfrm(dst2, src2, sizeof(dst2)), 3U);
+
+  // The "transform" of two different strings should cause different outputs.
   ASSERT_TRUE(strcmp(dst1, dst2) < 0);
 }
 
+TEST(STRING_TEST, strxfrm_l_smoke) {
+  // bionic just forwards to strxfrm(3), so this is a subset of the
+  // strxfrm test.
+  const char* src1 = "aab";
+  char dst1[16] = {};
+  ASSERT_EQ(strxfrm_l(dst1, src1, 0, LC_GLOBAL_LOCALE), 3U);
+  ASSERT_STREQ(dst1, "");
+  ASSERT_EQ(strxfrm_l(dst1, src1, sizeof(dst1), LC_GLOBAL_LOCALE), 3U);
+}
+
 TEST(STRING_TEST, memccpy_smoke) {
   char dst[32];
 
diff --git a/tests/strings_test.cpp b/tests/strings_test.cpp
index ac327d4..0226d1a 100644
--- a/tests/strings_test.cpp
+++ b/tests/strings_test.cpp
@@ -38,6 +38,48 @@
   ASSERT_EQ(32, ffs(0x80000000));
 }
 
+TEST(STRINGS_TEST, ffsl) {
+  ASSERT_EQ( 0, ffsl(0x00000000L));
+  ASSERT_EQ( 1, ffsl(0x00000001L));
+  ASSERT_EQ( 6, ffsl(0x00000020L));
+  ASSERT_EQ(11, ffsl(0x00000400L));
+  ASSERT_EQ(16, ffsl(0x00008000L));
+  ASSERT_EQ(17, ffsl(0x00010000L));
+  ASSERT_EQ(22, ffsl(0x00200000L));
+  ASSERT_EQ(27, ffsl(0x04000000L));
+  ASSERT_EQ(32, ffsl(0x80000000L));
+#if defined(__LP64__)
+  ASSERT_EQ(33, ffsl(0x0000000100000000L));
+  ASSERT_EQ(38, ffsl(0x0000002000000000L));
+  ASSERT_EQ(43, ffsl(0x0000040000000000L));
+  ASSERT_EQ(48, ffsl(0x0000800000000000L));
+  ASSERT_EQ(49, ffsl(0x0001000000000000L));
+  ASSERT_EQ(54, ffsl(0x0020000000000000L));
+  ASSERT_EQ(59, ffsl(0x0400000000000000L));
+  ASSERT_EQ(64, ffsl(0x8000000000000000L));
+#endif
+}
+
+TEST(STRINGS_TEST, ffsll) {
+  ASSERT_EQ( 0, ffsll(0x0000000000000000LL));
+  ASSERT_EQ( 1, ffsll(0x0000000000000001LL));
+  ASSERT_EQ( 6, ffsll(0x0000000000000020LL));
+  ASSERT_EQ(11, ffsll(0x0000000000000400LL));
+  ASSERT_EQ(16, ffsll(0x0000000000008000LL));
+  ASSERT_EQ(17, ffsll(0x0000000000010000LL));
+  ASSERT_EQ(22, ffsll(0x0000000000200000LL));
+  ASSERT_EQ(27, ffsll(0x0000000004000000LL));
+  ASSERT_EQ(32, ffsll(0x0000000080000000LL));
+  ASSERT_EQ(33, ffsll(0x0000000100000000LL));
+  ASSERT_EQ(38, ffsll(0x0000002000000000LL));
+  ASSERT_EQ(43, ffsll(0x0000040000000000LL));
+  ASSERT_EQ(48, ffsll(0x0000800000000000LL));
+  ASSERT_EQ(49, ffsll(0x0001000000000000LL));
+  ASSERT_EQ(54, ffsll(0x0020000000000000LL));
+  ASSERT_EQ(59, ffsll(0x0400000000000000LL));
+  ASSERT_EQ(64, ffsll(0x8000000000000000LL));
+}
+
 TEST(STRINGS_TEST, strcasecmp) {
   ASSERT_EQ(0, strcasecmp("hello", "HELLO"));
   ASSERT_LT(strcasecmp("hello1", "hello2"), 0);
diff --git a/libc/include/android/legacy_strings_inlines.h b/tests/sys_auxv_test.cpp
similarity index 63%
copy from libc/include/android/legacy_strings_inlines.h
copy to tests/sys_auxv_test.cpp
index 2cc2da2..afd62ea 100644
--- a/libc/include/android/legacy_strings_inlines.h
+++ b/tests/sys_auxv_test.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,19 +26,32 @@
  * SUCH DAMAGE.
  */
 
-#pragma once
+#include <gtest/gtest.h>
 
-#include <sys/cdefs.h>
+#include <sys/auxv.h>
 
-#if defined(__i386__) && __ANDROID_API__ < 18
+TEST(sys_auxv, getauxval_HWCAP) {
+  __attribute__((__unused__)) unsigned long hwcap = getauxval(AT_HWCAP);
 
-#include <strings.h>
-
-__BEGIN_DECLS
-
-/* Everyone except x86 had ffs since the beginning. */
-static __inline int ffs(int __n) { return __builtin_ffs(__n); }
-
-__END_DECLS
-
+  // Check that the constants for *using* AT_HWCAP are also available.
+#if defined(__arm__)
+  ASSERT_NE(0, HWCAP_THUMB);
+#elif defined(__aarch64__)
+  ASSERT_NE(0, HWCAP_FP);
 #endif
+}
+
+TEST(sys_auxv, getauxval_HWCAP2) {
+#if defined(AT_HWCAP2)
+  __attribute__((__unused__)) unsigned long hwcap = getauxval(AT_HWCAP2);
+
+  // Check that the constants for *using* AT_HWCAP2 are also available.
+#if defined(__arm__)
+  ASSERT_NE(0, HWCAP2_AES);
+#elif defined(__aarch64__)
+  ASSERT_NE(0, HWCAP2_SVE2);
+#endif
+#else
+  GTEST_SKIP() << "No AT_HWCAP2 for this architecture.";
+#endif
+}
diff --git a/tests/sys_procfs_test.cpp b/tests/sys_procfs_test.cpp
index 8054869..5e0a0b0 100644
--- a/tests/sys_procfs_test.cpp
+++ b/tests/sys_procfs_test.cpp
@@ -18,7 +18,7 @@
 
 #include <sys/procfs.h>
 
-TEST(sys_procfs, smoke) {
+TEST(sys_procfs, types) {
   elf_greg_t reg;
   memset(&reg, 0, sizeof(reg));
 
@@ -37,3 +37,16 @@
   static_assert(sizeof(prgregset_t) == sizeof(elf_gregset_t), "");
   static_assert(sizeof(prfpregset_t) == sizeof(elf_fpregset_t), "");
 }
+
+TEST(sys_procfs, constants) {
+  // NGREG != ELF_NGREG (https://github.com/android/ndk/issues/1347)
+  static_assert(sizeof(gregset_t) / sizeof(greg_t) == NGREG);
+
+#if defined(__arm__)
+  static_assert(sizeof(user_regs) / sizeof(elf_greg_t) == ELF_NGREG);
+#elif defined(__aarch64__)
+  static_assert(sizeof(user_pt_regs) / sizeof(elf_greg_t) == ELF_NGREG);
+#else
+  static_assert(sizeof(user_regs_struct) / sizeof(elf_greg_t) == ELF_NGREG);
+#endif
+}
diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp
index 71591c0..8f1437b 100644
--- a/tests/sys_stat_test.cpp
+++ b/tests/sys_stat_test.cpp
@@ -109,7 +109,6 @@
   int rc = statx(AT_FDCWD, "/proc/version", AT_STATX_SYNC_AS_STAT, STATX_ALL, &sx);
   if (rc == -1 && errno == ENOSYS) {
     GTEST_SKIP() << "statx returned ENOSYS";
-    return;
   }
   ASSERT_EQ(0, rc);
   struct stat64 sb;
diff --git a/tests/sys_thread_properties_test.cpp b/tests/sys_thread_properties_test.cpp
new file mode 100644
index 0000000..cf1a6ba
--- /dev/null
+++ b/tests/sys_thread_properties_test.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include "gtest_globals.h"
+#include "utils.h"
+
+TEST(thread_properties_test, iterate_dts) {
+#if defined(__BIONIC__)
+  const char expected_out[] =
+      "got test_static_tls_bounds\niterate_cb i = 0\ndone_iterate_dynamic_tls\n";
+  std::string helper = GetTestLibRoot() + "tls_properties_helper/tls_properties_helper";
+  chmod(helper.c_str(), 0755);  // TODO: "x" lost in CTS, b/34945607
+
+  ExecTestHelper eth;
+  eth.SetArgs({helper.c_str(), nullptr});
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, expected_out);
+#endif
+}
+
+TEST(thread_properties_test, thread_exit_cb) {
+#if defined(__BIONIC__)
+  // tests/libs/thread_exit_cb_helper.cpp
+  const char expected_out[] = "exit_cb_1 called exit_cb_2 called exit_cb_3 called";
+  std::string helper = GetTestLibRoot() + "thread_exit_cb_helper/thread_exit_cb_helper";
+  chmod(helper.c_str(), 0755);  // TODO: "x" lost in CTS, b/34945607
+
+  ExecTestHelper eth;
+  eth.SetArgs({helper.c_str(), nullptr});
+  eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0, expected_out);
+
+#endif
+}
diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp
index a521967..f82f505 100644
--- a/tests/sys_vfs_test.cpp
+++ b/tests/sys_vfs_test.cpp
@@ -44,12 +44,26 @@
   Check(sb);
 }
 
+TEST(sys_vfs, statfs_failure) {
+  struct statfs sb;
+  errno = 0;
+  ASSERT_EQ(-1, statfs("/does-not-exist", &sb));
+  ASSERT_EQ(ENOENT, errno);
+}
+
 TEST(sys_vfs, statfs64) {
   struct statfs64 sb;
   ASSERT_EQ(0, statfs64("/proc", &sb));
   Check(sb);
 }
 
+TEST(sys_vfs, statfs64_failure) {
+  struct statfs64 sb;
+  errno = 0;
+  ASSERT_EQ(-1, statfs64("/does-not-exist", &sb));
+  ASSERT_EQ(ENOENT, errno);
+}
+
 TEST(sys_vfs, fstatfs) {
   struct statfs sb;
   int fd = open("/proc", O_RDONLY);
@@ -58,6 +72,13 @@
   Check(sb);
 }
 
+TEST(sys_vfs, fstatfs_failure) {
+  struct statfs sb;
+  errno = 0;
+  ASSERT_EQ(-1, fstatfs(-1, &sb));
+  ASSERT_EQ(EBADF, errno);
+}
+
 TEST(sys_vfs, fstatfs64) {
   struct statfs64 sb;
   int fd = open("/proc", O_RDONLY);
@@ -65,3 +86,10 @@
   close(fd);
   Check(sb);
 }
+
+TEST(sys_vfs, fstatfs64_failure) {
+  struct statfs sb;
+  errno = 0;
+  ASSERT_EQ(-1, fstatfs(-1, &sb));
+  ASSERT_EQ(EBADF, errno);
+}
diff --git a/libc/arch-arm64/mte/bionic/strlen.c b/tests/sys_wait_test.cpp
similarity index 77%
copy from libc/arch-arm64/mte/bionic/strlen.c
copy to tests/sys_wait_test.cpp
index de88320..c006972 100644
--- a/libc/arch-arm64/mte/bionic/strlen.c
+++ b/tests/sys_wait_test.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,19 @@
  * SUCH DAMAGE.
  */
 
-#include <upstream-openbsd/android/include/openbsd-compat.h>
+#include <gtest/gtest.h>
 
-#define strlen strlen_mte
-#include <upstream-openbsd/lib/libc/string/strlen.c>
+#include <sys/wait.h>
+
+TEST(sys_wait, waitid) {
+  pid_t pid = fork();
+  ASSERT_NE(pid, -1);
+
+  if (pid == 0) _exit(66);
+
+  siginfo_t si = {};
+  ASSERT_EQ(0, waitid(P_PID, pid, &si, WEXITED));
+  ASSERT_EQ(pid, si.si_pid);
+  ASSERT_EQ(66, si.si_status);
+  ASSERT_EQ(CLD_EXITED, si.si_code);
+}
diff --git a/tests/tagged_pointers_test.cpp b/tests/tagged_pointers_test.cpp
deleted file mode 100644
index 56d1037..0000000
--- a/tests/tagged_pointers_test.cpp
+++ /dev/null
@@ -1,84 +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.
- */
-
-#include <gtest/gtest.h>
-#include <sys/prctl.h>
-
-#include "platform/bionic/malloc.h"
-#include "platform/bionic/mte.h"
-#include "utils.h"
-
-#include <bionic/malloc_tagged_pointers.h>
-
-static bool KernelSupportsTaggedPointers() {
-#ifdef __aarch64__
-#define PR_SET_TAGGED_ADDR_CTRL 55
-#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
-  int res = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
-  return res >= 0 && res & PR_TAGGED_ADDR_ENABLE;
-#else
-  return false;
-#endif
-}
-
-TEST(tagged_pointers, check_tagged_pointer_dies) {
-  if (!KernelSupportsTaggedPointers()) {
-    GTEST_SKIP() << "Kernel doesn't support tagged pointers.";
-  }
-
-#ifdef __aarch64__
-  if (mte_supported()) {
-    GTEST_SKIP() << "Tagged pointers are not used on MTE hardware.";
-  }
-
-  void *x = malloc(1);
-
-  // Ensure that `x` has a pointer tag.
-  EXPECT_NE(reinterpret_cast<uintptr_t>(x) >> 56, 0u);
-
-  x = untag_address(x);
-  EXPECT_DEATH(free(x), "Pointer tag for 0x[a-zA-Z0-9]* was truncated");
-
-  HeapTaggingLevel tag_level = M_HEAP_TAGGING_LEVEL_TBI;
-  EXPECT_TRUE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-  EXPECT_DEATH(free(untag_address(malloc(1))), "Pointer tag for 0x[a-zA-Z0-9]* was truncated");
-
-  tag_level = M_HEAP_TAGGING_LEVEL_ASYNC;
-  EXPECT_FALSE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-
-  x = malloc(1);
-  void *y = malloc(1);
-  // Disable heap tagging.
-  tag_level = M_HEAP_TAGGING_LEVEL_NONE;
-  EXPECT_TRUE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-  // Ensure an older tagged pointer can still be freed.
-  free(x);
-  // Tag mismatch is not detected on old pointers.
-  free(untag_address(y));
-  // New pointers are not tagged.
-  x = malloc(1);
-  EXPECT_EQ(untag_address(x), x);
-  free(x);
-
-  // Switching back to checked mode is not possible.
-  tag_level = M_HEAP_TAGGING_LEVEL_TBI;
-  EXPECT_FALSE(android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &tag_level, sizeof(tag_level)));
-  // We remain in the unchecked mode.
-  x = malloc(1);
-  EXPECT_EQ(untag_address(x), x);
-  free(x);
-#endif // defined(__aarch64__)
-}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 378b4ac..b1de0a4 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -142,7 +142,7 @@
   t.tm_mday = 10;
 
 #if !defined(__LP64__)
-  // 32-bit bionic stupidly had a signed 32-bit time_t.
+  // 32-bit bionic has a signed 32-bit time_t.
   ASSERT_EQ(-1, mktime(&t));
   ASSERT_EQ(EOVERFLOW, errno);
 #else
@@ -363,6 +363,105 @@
   EXPECT_TRUE(memcmp(&tm, &zero, sizeof(tm)) == 0);
 }
 
+TEST(time, strptime_Z) {
+#if defined(__BIONIC__)
+  // glibc doesn't handle %Z at all.
+  // The BSDs only handle hard-coded "GMT" and "UTC", plus whatever two strings
+  // are in the global `tzname` (which correspond to the current $TZ).
+  struct tm tm;
+  setenv("TZ", "Europe/Berlin", 1);
+
+  // "GMT" always works.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("GMT", "%Z", &tm));
+  EXPECT_STREQ("GMT", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(0, tm.tm_gmtoff);
+
+  // As does "UTC".
+  tm = {};
+  ASSERT_EQ('\0', *strptime("UTC", "%Z", &tm));
+  EXPECT_STREQ("UTC", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(0, tm.tm_gmtoff);
+
+  // Europe/Berlin is known as "CET" when there's no DST.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("CET", "%Z", &tm));
+  EXPECT_STREQ("CET", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(3600, tm.tm_gmtoff);
+
+  // Europe/Berlin is known as "CEST" when there's no DST.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("CEST", "%Z", &tm));
+  EXPECT_STREQ("CEST", tm.tm_zone);
+  EXPECT_EQ(1, tm.tm_isdst);
+  EXPECT_EQ(3600, tm.tm_gmtoff);
+
+  // And as long as we're in Europe/Berlin, those are the only time zone
+  // abbreviations that are recognized.
+  tm = {};
+  ASSERT_TRUE(strptime("PDT", "%Z", &tm) == nullptr);
+#endif
+}
+
+TEST(time, strptime_z) {
+  struct tm tm;
+  setenv("TZ", "Europe/Berlin", 1);
+
+  // "UT" is what RFC822 called UTC.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("UT", "%z", &tm));
+  EXPECT_STREQ("UTC", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(0, tm.tm_gmtoff);
+  // "GMT" is RFC822's other name for UTC.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("GMT", "%z", &tm));
+  EXPECT_STREQ("UTC", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(0, tm.tm_gmtoff);
+
+  // "Z" ("Zulu") is a synonym for UTC.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("Z", "%z", &tm));
+  EXPECT_STREQ("UTC", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(0, tm.tm_gmtoff);
+
+  // "PST"/"PDT" and the other common US zone abbreviations are all supported.
+  tm = {};
+  ASSERT_EQ('\0', *strptime("PST", "%z", &tm));
+  EXPECT_STREQ("PST", tm.tm_zone);
+  EXPECT_EQ(0, tm.tm_isdst);
+  EXPECT_EQ(-28800, tm.tm_gmtoff);
+  tm = {};
+  ASSERT_EQ('\0', *strptime("PDT", "%z", &tm));
+  EXPECT_STREQ("PDT", tm.tm_zone);
+  EXPECT_EQ(1, tm.tm_isdst);
+  EXPECT_EQ(-25200, tm.tm_gmtoff);
+
+  // +-hh
+  tm = {};
+  ASSERT_EQ('\0', *strptime("+01", "%z", &tm));
+  EXPECT_EQ(3600, tm.tm_gmtoff);
+  EXPECT_TRUE(tm.tm_zone == nullptr);
+  EXPECT_EQ(0, tm.tm_isdst);
+  // +-hhmm
+  tm = {};
+  ASSERT_EQ('\0', *strptime("+0130", "%z", &tm));
+  EXPECT_EQ(5400, tm.tm_gmtoff);
+  EXPECT_TRUE(tm.tm_zone == nullptr);
+  EXPECT_EQ(0, tm.tm_isdst);
+  // +-hh:mm
+  tm = {};
+  ASSERT_EQ('\0', *strptime("+01:30", "%z", &tm));
+  EXPECT_EQ(5400, tm.tm_gmtoff);
+  EXPECT_TRUE(tm.tm_zone == nullptr);
+  EXPECT_EQ(0, tm.tm_isdst);
+}
+
 void SetTime(timer_t t, time_t value_s, time_t value_ns, time_t interval_s, time_t interval_ns) {
   itimerspec ts;
   ts.it_value.tv_sec = value_s;
@@ -1005,3 +1104,8 @@
   GTEST_SKIP() << "glibc doesn't have timespec_get until 2.21";
 #endif
 }
+
+TEST(time, difftime) {
+  ASSERT_EQ(1.0, difftime(1, 0));
+  ASSERT_EQ(-1.0, difftime(0, 1));
+}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 6b28561..43d50f8 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1350,6 +1350,11 @@
   ASSERT_EQ(EACCES, errno);
 }
 
+static void append_llvm_cov_env_var(std::string& env_str) {
+  if (getenv("LLVM_PROFILE_FILE") != nullptr)
+    env_str.append("__LLVM_PROFILE_RT_INIT_ONCE=__LLVM_PROFILE_RT_INIT_ONCE\n");
+}
+
 TEST(UNISTD_TEST, execve_args) {
   // int execve(const char* path, char* argv[], char* envp[]);
 
@@ -1361,7 +1366,12 @@
   // Test environment variable setting too.
   eth.SetArgs({"printenv", nullptr});
   eth.SetEnv({"A=B", nullptr});
-  eth.Run([&]() { execve(BIN_DIR "printenv", eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+
+  std::string expected_output("A=B\n");
+  append_llvm_cov_env_var(expected_output);
+
+  eth.Run([&]() { execve(BIN_DIR "printenv", eth.GetArgs(), eth.GetEnv()); }, 0,
+          expected_output.c_str());
 }
 
 TEST(UNISTD_TEST, execl_failure) {
@@ -1386,8 +1396,13 @@
 TEST(UNISTD_TEST, execle) {
   ExecTestHelper eth;
   eth.SetEnv({"A=B", nullptr});
+
+  std::string expected_output("A=B\n");
+  append_llvm_cov_env_var(expected_output);
+
   // int execle(const char* path, const char* arg, ..., char* envp[]);
-  eth.Run([&]() { execle(BIN_DIR "printenv", "printenv", nullptr, eth.GetEnv()); }, 0, "A=B\n");
+  eth.Run([&]() { execle(BIN_DIR "printenv", "printenv", nullptr, eth.GetEnv()); }, 0,
+          expected_output.c_str());
 }
 
 TEST(UNISTD_TEST, execv_failure) {
@@ -1450,7 +1465,11 @@
   // Test environment variable setting too.
   eth.SetArgs({"printenv", nullptr});
   eth.SetEnv({"A=B", nullptr});
-  eth.Run([&]() { execvpe("printenv", eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+
+  std::string expected_output("A=B\n");
+  append_llvm_cov_env_var(expected_output);
+
+  eth.Run([&]() { execvpe("printenv", eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
 }
 
 TEST(UNISTD_TEST, execvpe_ENOEXEC) {
@@ -1538,7 +1557,11 @@
   ASSERT_NE(-1, printenv_fd);
   eth.SetArgs({"printenv", nullptr});
   eth.SetEnv({"A=B", nullptr});
-  eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, "A=B\n");
+
+  std::string expected_output("A=B\n");
+  append_llvm_cov_env_var(expected_output);
+
+  eth.Run([&]() { fexecve(printenv_fd, eth.GetArgs(), eth.GetEnv()); }, 0, expected_output.c_str());
   close(printenv_fd);
 }
 
diff --git a/tests/utils.h b/tests/utils.h
index 5014ef7..c1b7f65 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -25,6 +25,16 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#if defined(__BIONIC__)
+#include <sys/system_properties.h>
+#endif
+
+#if defined(__BIONIC__)
+#include <bionic/macros.h>
+#else
+#define untag_address(p) p
+#endif
+
 #include <atomic>
 #include <string>
 #include <regex>
@@ -66,14 +76,21 @@
 
 #define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
 
-static inline void* untag_address(void* addr) {
-#if defined(__LP64__)
-  constexpr uintptr_t mask = (static_cast<uintptr_t>(1) << 56) - 1;
-  addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(addr) & mask);
+static inline bool running_with_native_bridge() {
+#if defined(__BIONIC__)
+#if defined(__arm__)
+  static const prop_info* pi = __system_property_find("ro.dalvik.vm.isa.arm");
+  return pi != nullptr;
+#elif defined(__aarch64__)
+  static const prop_info* pi = __system_property_find("ro.dalvik.vm.isa.arm64");
+  return pi != nullptr;
 #endif
-  return addr;
+#endif
+  return false;
 }
 
+#define SKIP_WITH_NATIVE_BRIDGE if (running_with_native_bridge()) GTEST_SKIP()
+
 #if defined(__linux__)
 
 #include <sys/sysmacros.h>
diff --git a/tests/utmp_test.cpp b/tests/utmp_test.cpp
index 0fa55c7..6d0d6f1 100644
--- a/tests/utmp_test.cpp
+++ b/tests/utmp_test.cpp
@@ -24,8 +24,10 @@
   ASSERT_EQ(-1, login_tty(-1));
 }
 
-TEST(utmp, setutent_getutent_endutent) {
+TEST(utmp, smoke) {
+  ASSERT_EQ(-1, utmpname("hello"));
   setutent();
-  getutent();
+  ASSERT_EQ(NULL, getutent());
   endutent();
+  ASSERT_EQ(NULL, pututline(NULL));
 }
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index 3c6f643..ec2e38d 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -72,7 +72,7 @@
 
     // <math.h> maps fool onto foo on 32-bit, since long double is the same as double.
     if (auto asm_attr = decl->getAttr<AsmLabelAttr>()) {
-      return asm_attr->getLabel();
+      return asm_attr->getLabel().str();
     }
 
     // The decl might not have a name (e.g. bitfields).
@@ -84,7 +84,7 @@
         return mangled;
       }
 
-      return identifier->getName();
+      return identifier->getName().str();
     }
 
     return "<unnamed>";
@@ -173,7 +173,7 @@
               &arch_availability[Arch::x86_64].introduced } },
         };
 
-        if (auto it = prefix_map.find(fragments[0]); it != prefix_map.end()) {
+        if (auto it = prefix_map.find(fragments[0].str()); it != prefix_map.end()) {
           int value;
           if (fragments[1].getAsInteger(10, value)) {
             errx(1, "invalid __ANDROID_AVAILABILITY_DUMP__ annotation: '%s'",
@@ -190,8 +190,8 @@
     auto symbol_it = database.symbols.find(declaration_name);
     if (symbol_it == database.symbols.end()) {
       Symbol symbol = {.name = declaration_name };
-      bool dummy;
-      std::tie(symbol_it, dummy) = database.symbols.insert({ declaration_name, symbol });
+      bool unused;
+      std::tie(symbol_it, unused) = database.symbols.insert({declaration_name, symbol});
     }
 
     auto expansion_range = src_manager.getExpansionRange(range);
@@ -201,7 +201,7 @@
     }
 
     Location location = {
-      .filename = filename,
+      .filename = filename.str(),
       .start = {
         .line = src_manager.getExpansionLineNumber(expansion_range.getBegin()),
         .column = src_manager.getExpansionColumnNumber(expansion_range.getBegin()),
diff --git a/tools/versioner/src/Preprocessor.cpp b/tools/versioner/src/Preprocessor.cpp
index 4ee3446..eb88c46 100644
--- a/tools/versioner/src/Preprocessor.cpp
+++ b/tools/versioner/src/Preprocessor.cpp
@@ -237,7 +237,7 @@
   return "("s + Join(expressions, ") || (") + ")";
 }
 
-// Assumes that nothing crazy is happening (e.g. having the semicolon be in a macro)
+// Assumes that nothing weird is happening (e.g. having the semicolon be in a macro).
 static FileLocation findNextSemicolon(const std::deque<std::string>& lines, FileLocation start) {
   unsigned current_line = start.line;
   unsigned current_column = start.column;
@@ -373,8 +373,8 @@
 
     guard_map.erase(current);
     guard_map.erase(next);
-    bool dummy;
-    std::tie(current, dummy) = guard_map.insert(std::make_pair(merged, avail));
+    bool unused;
+    std::tie(current, unused) = guard_map.insert(std::make_pair(merged, avail));
     next = current;
     ++next;
   }
@@ -446,7 +446,7 @@
       continue;
     }
 
-    std::string rel_path = path.substr(src_dir.length() + 1);
+    std::string rel_path = path.substr(src_dir.length() + 1).str();
     std::string dst_path = dst_dir + "/" + rel_path;
     llvm::StringRef parent_path = llvm::sys::path::parent_path(dst_path);
     if (llvm::sys::fs::create_directories(parent_path)) {
@@ -471,13 +471,13 @@
     GuardMap guard_map;
     for (const auto& it : orig_guard_map) {
       Location loc = it.first;
-      loc.end = findNextSemicolon(file_lines[file_path], loc.end);
+      loc.end = findNextSemicolon(file_lines[file_path.str()], loc.end);
       guard_map[loc] = it.second;
     }
 
     // TODO: Make sure that the Locations don't overlap.
     // TODO: Merge adjacent non-identical guards.
-    mergeGuards(file_lines[file_path], guard_map);
+    mergeGuards(file_lines[file_path.str()], guard_map);
 
     if (!file_path.startswith(src_dir)) {
       errx(1, "input file %s is not in %s\n", file_path.str().c_str(), src_dir.c_str());
@@ -487,7 +487,7 @@
     llvm::StringRef rel_path = file_path.substr(src_dir.size(), file_path.size() - src_dir.size());
     std::string output_path = (llvm::Twine(dst_dir) + rel_path).str();
 
-    rewriteFile(output_path, file_lines[file_path], guard_map);
+    rewriteFile(output_path, file_lines[file_path.str()], guard_map);
   }
 
   return true;
diff --git a/tools/versioner/src/Utils.cpp b/tools/versioner/src/Utils.cpp
index ca186a4..dc6b5dd 100644
--- a/tools/versioner/src/Utils.cpp
+++ b/tools/versioner/src/Utils.cpp
@@ -64,7 +64,7 @@
 
     if (ent->fts_info & FTS_D) {
       if (ignored_directories.count(ent->fts_path) != 0) {
-        // fts_read guarantees that `ent` is valid and sane to hold on to until
+        // fts_read guarantees that `ent` is valid and okay to hold on to until
         // after it's returned with FTS_DP set.
         skipping = ent;
       }
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 473f1f9..c818197 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -141,7 +141,7 @@
   }
 
   auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
-    for (const auto& it : header_blacklist) {
+    for (const auto& it : ignored_headers) {
       if (it.second.find(arch) == it.second.end()) {
         continue;
       }
@@ -276,7 +276,7 @@
   return intersection;
 }
 
-// Perform a sanity check on a symbol's declarations, enforcing the following invariants:
+// Perform a validity check on a symbol's declarations, enforcing the following invariants:
 //   1. At most one inline definition of the function exists (overloaded inline functions for
 //      _FORTIFY_SOURCE do not count because they are usually introduced to intercept the original
 //      functions or usually have enable_if attributes).
@@ -334,7 +334,7 @@
   return true;
 }
 
-static bool sanityCheck(const HeaderDatabase* database) {
+static bool validityCheck(const HeaderDatabase* database) {
   bool error = false;
   std::string cwd = getWorkingDir() + "/";
 
@@ -676,8 +676,8 @@
   if (dump) {
     declaration_database->dump(location.header_path + "/");
   } else {
-    if (!sanityCheck(declaration_database.get())) {
-      printf("versioner: sanity check failed\n");
+    if (!validityCheck(declaration_database.get())) {
+      printf("versioner: validity check failed\n");
       failed = true;
     }
 
diff --git a/tools/versioner/src/versioner.h b/tools/versioner/src/versioner.h
index 5e53498..e9c4989 100644
--- a/tools/versioner/src/versioner.h
+++ b/tools/versioner/src/versioner.h
@@ -33,15 +33,11 @@
     }                      \
   } while (0)
 
-static const std::unordered_map<std::string, std::set<Arch>> header_blacklist = {
+static const std::unordered_map<std::string, std::set<Arch>> ignored_headers = {
   // Internal header.
+  // TODO: we should probably just admit we're never getting rid of this.
   { "sys/_system_properties.h", supported_archs },
 
   // time64.h #errors when included on LP64 archs.
   { "time64.h", { Arch::arm64, Arch::x86_64 } },
 };
-
-static const std::unordered_set<std::string> missing_symbol_whitelist = {
-  // atexit comes from crtbegin.
-  "atexit",
-};
diff --git a/tools/versioner/tests/multiple_decl_mismatch/expected_fail b/tools/versioner/tests/multiple_decl_mismatch/expected_fail
index 1d1f266..30e7233 100644
--- a/tools/versioner/tests/multiple_decl_mismatch/expected_fail
+++ b/tools/versioner/tests/multiple_decl_mismatch/expected_fail
@@ -5,4 +5,4 @@
       obsoleted = 12
     extern declaration @ headers/foo.h:5:1
       obsoleted = 9
-versioner: sanity check failed
+versioner: validity check failed
diff --git a/tools/versioner/tests/multiple_definition/expected_fail b/tools/versioner/tests/multiple_definition/expected_fail
index cb4acc6..5abb833 100644
--- a/tools/versioner/tests/multiple_definition/expected_fail
+++ b/tools/versioner/tests/multiple_definition/expected_fail
@@ -4,4 +4,4 @@
       no availability
     static definition @ headers/bar.h:5:1
       no availability
-versioner: sanity check failed
+versioner: validity check failed
diff --git a/tools/versioner/tests/version_mismatch/expected_fail b/tools/versioner/tests/version_mismatch/expected_fail
index f2143a3..95d284b 100644
--- a/tools/versioner/tests/version_mismatch/expected_fail
+++ b/tools/versioner/tests/version_mismatch/expected_fail
@@ -5,4 +5,4 @@
       introduced = 9
     extern declaration @ headers/foo.h:8:1
       introduced = 10
-versioner: sanity check failed
+versioner: validity check failed