Merge "Duplicate tests for duplicated symbols."
diff --git a/Android.bp b/Android.bp
index dbe5c97..b44c296 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,2 +1 @@
 subdirs = ["*"]
-
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 48800ca..e4eb48a 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -389,7 +389,7 @@
 Android allows `dlclose` to unload a library even if there are still
 thread-local variables with non-trivial destructors. This leads to
 crashes when a thread exits and attempts to call the destructor, the
-code for which has been unloaded (as in [issue 360]).
+code for which has been unloaded (as in [issue 360], fixed in P).
 
 [issue 360]: https://github.com/android-ndk/ndk/issues/360
 
@@ -397,8 +397,8 @@
 set (so that calls to `dlclose` don't actually unload the library)
 are possible workarounds.
 
-|                   | Pre-M                      | M+      |
-| ----------------- | -------------------------- | ------- |
-| No workaround     | Works for static STL       | Broken  |
-| `-Wl,-z,nodelete` | Works for static STL       | Works   |
-| No `dlclose`      | Works                      | Works   |
+|                   | Pre-M                      | M+      | P+    |
+| ----------------- | -------------------------- | ------- | ----- |
+| No workaround     | Works for static STL       | Broken  | Works |
+| `-Wl,-z,nodelete` | Works for static STL       | Works   | Works |
+| No `dlclose`      | Works                      | Works   | Works |
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 115236b..f6d0e4d 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -67,7 +67,7 @@
         "libsystemproperties",
         "libasync_safe",
     ],
-    include_dirs: ["bionic/libc",],
+    include_dirs: ["bionic/libc"],
 }
 
 // We don't build a static benchmark executable because it's not usually
@@ -107,5 +107,8 @@
         "libbase",
         "libBionicBenchmarksUtils",
     ],
-    data: ["suites/*", "test_suites/*"],
+    data: [
+        "suites/*",
+        "test_suites/*",
+    ],
 }
diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp
index d82c739..d8635cd 100644
--- a/benchmarks/bionic_benchmarks.cpp
+++ b/benchmarks/bionic_benchmarks.cpp
@@ -305,7 +305,7 @@
 }
 
 void RegisterGoogleBenchmarks(bench_opts_t primary_opts, bench_opts_t secondary_opts,
-                         std::string fn_name, args_vector_t* run_args) {
+                              const std::string& fn_name, args_vector_t* run_args) {
   if (g_str_to_func.find(fn_name) == g_str_to_func.end()) {
     errx(1, "ERROR: No benchmark for function %s", fn_name.c_str());
   }
@@ -320,7 +320,7 @@
   }
 
   benchmark_func_t benchmark_function = g_str_to_func.at(fn_name).first;
-  for (std::vector<int> args : (*run_args)) {
+  for (const std::vector<int>& args : (*run_args)) {
     auto registration = benchmark::RegisterBenchmark(fn_name.c_str(), LockAndRun,
                                                      benchmark_function,
                                                      cpu_to_use)->Args(args);
@@ -335,13 +335,13 @@
   // Register any of the extra benchmarks that were specified in the options.
   args_vector_t arg_vector;
   args_vector_t* run_args = &arg_vector;
-  for (std::string extra_fn : cmdline_opts.extra_benchmarks) {
+  for (const std::string& extra_fn : cmdline_opts.extra_benchmarks) {
     android::base::Trim(extra_fn);
-    size_t first_space_pos = extra_fn.find(" ");
+    size_t first_space_pos = extra_fn.find(' ');
     std::string fn_name = extra_fn.substr(0, first_space_pos);
     std::string cmd_args;
     if (first_space_pos != std::string::npos) {
-      cmd_args = extra_fn.substr(extra_fn.find(" ") + 1);
+      cmd_args = extra_fn.substr(extra_fn.find(' ') + 1);
     } else {
       cmd_args = "";
     }
@@ -514,28 +514,12 @@
 
 void RegisterAllBenchmarks(const bench_opts_t& opts,
                            std::map<std::string, args_vector_t>& args_shorthand) {
-  // Add the property tests at the end since they might cause segfaults in
-  // tests running afterwards (b/62197783).
-  std::vector<std::string> prop_tests;
-
   for (auto& entry : g_str_to_func) {
-    if (android::base::StartsWith(entry.first, "BM_property_")) {
-      prop_tests.push_back(entry.first);
-    } else {
-      auto& function_info = entry.second;
-      args_vector_t arg_vector;
-      args_vector_t* run_args = ResolveArgs(&arg_vector, function_info.second,
-                                            args_shorthand);
-      RegisterGoogleBenchmarks(bench_opts_t(), opts, entry.first, run_args);
-    }
-  }
-
-  for (auto& prop_name : prop_tests) {
-    auto& function_info = g_str_to_func.at(prop_name);
+    auto& function_info = entry.second;
     args_vector_t arg_vector;
     args_vector_t* run_args = ResolveArgs(&arg_vector, function_info.second,
                                           args_shorthand);
-    RegisterGoogleBenchmarks(bench_opts_t(), opts, prop_name, run_args);
+    RegisterGoogleBenchmarks(bench_opts_t(), opts, entry.first, run_args);
   }
 }
 
diff --git a/benchmarks/pthread_benchmark.cpp b/benchmarks/pthread_benchmark.cpp
index 1ad6345..c72736e 100644
--- a/benchmarks/pthread_benchmark.cpp
+++ b/benchmarks/pthread_benchmark.cpp
@@ -96,6 +96,55 @@
 }
 BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE);
 
+namespace {
+struct PIMutex {
+  pthread_mutex_t mutex;
+
+  PIMutex(int type) {
+    pthread_mutexattr_t attr;
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, type);
+    pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+    pthread_mutex_init(&mutex, &attr);
+    pthread_mutexattr_destroy(&attr);
+  }
+
+  ~PIMutex() {
+    pthread_mutex_destroy(&mutex);
+  }
+};
+}
+
+static void BM_pthread_mutex_lock_PI(benchmark::State& state) {
+  PIMutex m(PTHREAD_MUTEX_NORMAL);
+
+  while (state.KeepRunning()) {
+    pthread_mutex_lock(&m.mutex);
+    pthread_mutex_unlock(&m.mutex);
+  }
+}
+BIONIC_BENCHMARK(BM_pthread_mutex_lock_PI);
+
+static void BM_pthread_mutex_lock_ERRORCHECK_PI(benchmark::State& state) {
+  PIMutex m(PTHREAD_MUTEX_ERRORCHECK);
+
+  while (state.KeepRunning()) {
+    pthread_mutex_lock(&m.mutex);
+    pthread_mutex_unlock(&m.mutex);
+  }
+}
+BIONIC_BENCHMARK(BM_pthread_mutex_lock_ERRORCHECK_PI);
+
+static void BM_pthread_mutex_lock_RECURSIVE_PI(benchmark::State& state) {
+  PIMutex m(PTHREAD_MUTEX_RECURSIVE);
+
+  while (state.KeepRunning()) {
+    pthread_mutex_lock(&m.mutex);
+    pthread_mutex_unlock(&m.mutex);
+  }
+}
+BIONIC_BENCHMARK(BM_pthread_mutex_lock_RECURSIVE_PI);
+
 static void BM_pthread_rwlock_read(benchmark::State& state) {
   pthread_rwlock_t lock;
   pthread_rwlock_init(&lock, NULL);
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 965a3ae..9c81e0f 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -29,7 +29,7 @@
   memset(line, 'x', sizeof(line));
   line[sizeof(line) - 1] = '\0';
 
-  FILE* fp = fopen(tf.path, "w");
+  FILE* fp = fopen(tf.path, "we");
   for (size_t i = 0; i < 4096; ++i) fputs(line, fp);
   fclose(fp);
 }
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
index 64629e6..d34017d 100644
--- a/benchmarks/tests/interface_test.cpp
+++ b/benchmarks/tests/interface_test.cpp
@@ -176,6 +176,8 @@
     "BM_atomic_seq_cst_fence/iterations:1\n"
     "BM_atomic_store_release/iterations:1\n"
     "BM_atomic_store_seq_cst/iterations:1\n"
+    "BM_inttypes_strtoimax/iterations:1\n"
+    "BM_inttypes_strtoumax/iterations:1\n"
     "BM_math_fabs/0/iterations:1\n"
     "BM_math_fabs/1/iterations:1\n"
     "BM_math_fabs/2/iterations:1\n"
@@ -234,6 +236,34 @@
     "BM_math_sin_fesetenv/iterations:1\n"
     "BM_math_sin_feupdateenv/iterations:1\n"
     "BM_math_sqrt/iterations:1\n"
+    "BM_property_find/1/iterations:1\n"
+    "BM_property_find/4/iterations:1\n"
+    "BM_property_find/16/iterations:1\n"
+    "BM_property_find/64/iterations:1\n"
+    "BM_property_find/128/iterations:1\n"
+    "BM_property_find/256/iterations:1\n"
+    "BM_property_find/512/iterations:1\n"
+    "BM_property_get/1/iterations:1\n"
+    "BM_property_get/4/iterations:1\n"
+    "BM_property_get/16/iterations:1\n"
+    "BM_property_get/64/iterations:1\n"
+    "BM_property_get/128/iterations:1\n"
+    "BM_property_get/256/iterations:1\n"
+    "BM_property_get/512/iterations:1\n"
+    "BM_property_read/1/iterations:1\n"
+    "BM_property_read/4/iterations:1\n"
+    "BM_property_read/16/iterations:1\n"
+    "BM_property_read/64/iterations:1\n"
+    "BM_property_read/128/iterations:1\n"
+    "BM_property_read/256/iterations:1\n"
+    "BM_property_read/512/iterations:1\n"
+    "BM_property_serial/1/iterations:1\n"
+    "BM_property_serial/4/iterations:1\n"
+    "BM_property_serial/16/iterations:1\n"
+    "BM_property_serial/64/iterations:1\n"
+    "BM_property_serial/128/iterations:1\n"
+    "BM_property_serial/256/iterations:1\n"
+    "BM_property_serial/512/iterations:1\n"
     "BM_pthread_create/iterations:1\n"
     "BM_pthread_create_and_run/iterations:1\n"
     "BM_pthread_exit_and_join/iterations:1\n"
@@ -300,7 +330,10 @@
     "BM_stdio_printf_s/iterations:1\n"
     "BM_stdio_scanf_d/iterations:1\n"
     "BM_stdio_scanf_maps/iterations:1\n"
+    "BM_stdio_scanf_maps_baseline/iterations:1\n"
     "BM_stdio_scanf_s/iterations:1\n"
+    "BM_stdlib_atoi/iterations:1\n"
+    "BM_stdlib_atol/iterations:1\n"
     "BM_stdlib_malloc_free/8/iterations:1\n"
     "BM_stdlib_malloc_free/64/iterations:1\n"
     "BM_stdlib_malloc_free/512/iterations:1\n"
@@ -312,6 +345,10 @@
     "BM_stdlib_malloc_free/131072/iterations:1\n"
     "BM_stdlib_mbrtowc/0/iterations:1\n"
     "BM_stdlib_mbstowcs/0/0/iterations:1\n"
+    "BM_stdlib_strtol/iterations:1\n"
+    "BM_stdlib_strtoll/iterations:1\n"
+    "BM_stdlib_strtoul/iterations:1\n"
+    "BM_stdlib_strtoull/iterations:1\n"
     "BM_string_memcmp/8/0/0/iterations:1\n"
     "BM_string_memcmp/64/0/0/iterations:1\n"
     "BM_string_memcmp/512/0/0/iterations:1\n"
@@ -460,35 +497,7 @@
     "BM_unistd_getpid/iterations:1\n"
     "BM_unistd_getpid_syscall/iterations:1\n"
     "BM_unistd_gettid/iterations:1\n"
-    "BM_unistd_gettid_syscall/iterations:1\n"
-    "BM_property_find/1/iterations:1\n"
-    "BM_property_find/4/iterations:1\n"
-    "BM_property_find/16/iterations:1\n"
-    "BM_property_find/64/iterations:1\n"
-    "BM_property_find/128/iterations:1\n"
-    "BM_property_find/256/iterations:1\n"
-    "BM_property_find/512/iterations:1\n"
-    "BM_property_get/1/iterations:1\n"
-    "BM_property_get/4/iterations:1\n"
-    "BM_property_get/16/iterations:1\n"
-    "BM_property_get/64/iterations:1\n"
-    "BM_property_get/128/iterations:1\n"
-    "BM_property_get/256/iterations:1\n"
-    "BM_property_get/512/iterations:1\n"
-    "BM_property_read/1/iterations:1\n"
-    "BM_property_read/4/iterations:1\n"
-    "BM_property_read/16/iterations:1\n"
-    "BM_property_read/64/iterations:1\n"
-    "BM_property_read/128/iterations:1\n"
-    "BM_property_read/256/iterations:1\n"
-    "BM_property_read/512/iterations:1\n"
-    "BM_property_serial/1/iterations:1\n"
-    "BM_property_serial/4/iterations:1\n"
-    "BM_property_serial/16/iterations:1\n"
-    "BM_property_serial/64/iterations:1\n"
-    "BM_property_serial/128/iterations:1\n"
-    "BM_property_serial/256/iterations:1\n"
-    "BM_property_serial/512/iterations:1\n";
+    "BM_unistd_gettid_syscall/iterations:1\n";
   Verify(expected, 0, std::vector<const char*>{"--bionic_iterations=1"});
 }
 
diff --git a/benchmarks/util.h b/benchmarks/util.h
index a546764..3225bc2 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -29,7 +29,7 @@
 
 extern std::map<std::string, std::pair<benchmark_func_t, std::string>> g_str_to_func;
 
-static int  __attribute__((unused)) EmplaceBenchmark (std::string fn_name, benchmark_func_t fn_ptr, std::string arg = "") {
+static int  __attribute__((unused)) EmplaceBenchmark(const std::string& fn_name, benchmark_func_t fn_ptr, const std::string& arg = "") {
   g_map_lock.lock();
   g_str_to_func.emplace(std::string(fn_name), std::make_pair(fn_ptr, arg));
   g_map_lock.unlock();
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 9ae1973..0ea94d4 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -59,15 +59,27 @@
 
 In the 64-bit ABI, `off_t` is always 64-bit.
 
+For source compatibility, the names containing `64` are also available
+in the 64-bit ABI even though they're identical to the non-`64` names.
+
 
 ## `sigset_t` is too small for real-time signals
 
 On 32-bit Android, `sigset_t` is too small for ARM and x86 (but correct for
 MIPS). This means that there is no support for real-time signals in 32-bit
-code.
+code. Android P (API level 28) adds `sigset64_t` and a corresponding function
+for every function that takes a `sigset_t` (so `sigprocmask64` takes a
+`sigset64_t` where `sigprocmask` takes a `sigset_t`).
+
+On 32-bit Android, `struct sigaction` is also too small because it contains
+a `sigset_t`. We also offer a `struct sigaction64` and `sigaction64` function
+to work around this.
 
 In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
 
+For source compatibility, the names containing `64` are also available
+in the 64-bit ABI even though they're identical to the non-`64` names.
+
 
 ## `time_t` is 32-bit
 
@@ -77,10 +89,11 @@
 
 In the 64-bit ABI, `time_t` is 64-bit.
 
+
 ## `pthread_mutex_t` is too small for large pids
 
 This doesn't generally affect Android devices, because on devices
-`/proc/sys/kernel/pid_max` is usually too small to hit the 16-bit limit,
+`/proc/sys/kernel/pid_max` is usually too small to hit our 16-bit limit,
 but 32-bit bionic's `pthread_mutex` is a total of 32 bits, leaving just
 16 bits for the owner thread id. This means bionic isn't able to support
 mutexes for tids that don't fit in 16 bits. This typically manifests as
diff --git a/docs/status.md b/docs/status.md
index d4ca913..2666e58 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -48,10 +48,13 @@
   * `hcreate`/`hcreate_r`/`hdestroy`/`hdestroy_r`/`hsearch`/`hsearch_r` (completing <search.h>)
   * `iconv`/`iconv_close`/`iconv_open` (adding <iconv.h>)
   * `pthread_attr_getinheritsched`/`pthread_attr_setinheritsched`/`pthread_setschedprio`
+  * `pthread_mutexattr_getprotocol`/`pthread_mutexattr_setprotocol` (mutex priority inheritance)
+  * <signal.h> support for `sigaction64_t` and `sigset64_t` allowing LP32 access to real-time signals
   * <spawn.h>
   * `swab`
   * `syncfs`
-  * %C and %S support in the printf family (previously only the wprintf family supported these).
+  * `%C` and `%S` support in the printf family (previously only the wprintf family supported these)
+  * `%mc`/`%ms`/`%m[` support in the scanf family
 
 New libc functions in O:
   * `sendto` FORTIFY support
diff --git a/libc/Android.bp b/libc/Android.bp
index 20648d0..07f5acb 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -10,15 +10,12 @@
     "bionic/pututline.c",
     "bionic/sched_cpualloc.c",
     "bionic/sched_cpucount.c",
-    "bionic/sigblock.c",
-    "bionic/siginterrupt.c",
-    "bionic/sigsetmask.c",
     "stdio/fmemopen.cpp",
     "stdio/parsefloat.c",
     "stdio/refill.c",
     "stdio/stdio.cpp",
     "stdio/stdio_ext.cpp",
-    "stdio/vfscanf.c",
+    "stdio/vfscanf.cpp",
     "stdio/vfwscanf.c",
     "stdlib/exit.c",
 ]
@@ -39,6 +36,7 @@
     "-Wall",
     "-Wextra",
     "-Wunused",
+    "-Wno-char-subscripts",
     "-Wno-deprecated-declarations",
     "-Wno-gcc-compat",
     "-Wframe-larger-than=2048",
@@ -402,7 +400,6 @@
         "upstream-openbsd/lib/libc/gen/getprogname.c",
         "upstream-openbsd/lib/libc/gen/isctype.c",
         "upstream-openbsd/lib/libc/gen/setprogname.c",
-        "upstream-openbsd/lib/libc/gen/time.c",
         "upstream-openbsd/lib/libc/gen/tolower_.c",
         "upstream-openbsd/lib/libc/gen/toupper_.c",
         "upstream-openbsd/lib/libc/gen/verr.c",
@@ -541,7 +538,7 @@
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: [
-        // These two depend on getentropy_linux.c, which isn't in libc_ndk.a.
+        // These two depend on getentropy, which isn't in libc_ndk.a.
         "upstream-openbsd/lib/libc/crypt/arc4random.c",
         "upstream-openbsd/lib/libc/crypt/arc4random_uniform.c",
 
@@ -712,7 +709,10 @@
 
     // Disable FORTIFY for the compilation of these, so we don't end up having
     // FORTIFY silently call itself.
-    cflags: ["-U_FORTIFY_SOURCE", "-D__BIONIC_DECLARE_FORTIFY_HELPERS"],
+    cflags: [
+        "-U_FORTIFY_SOURCE",
+        "-D__BIONIC_DECLARE_FORTIFY_HELPERS",
+    ],
 
     arch: {
         arm: {
@@ -721,7 +721,10 @@
                 "arch-arm/generic/bionic/__memcpy_chk.S",
             ],
             neon: {
-                cflags: ["-DNO___STRCAT_CHK", "-DNO___STRCPY_CHK"],
+                cflags: [
+                    "-DNO___STRCAT_CHK",
+                    "-DNO___STRCPY_CHK",
+                ],
                 srcs: [
                     "arch-arm/cortex-a15/bionic/__strcat_chk.S",
                     "arch-arm/cortex-a15/bionic/__strcpy_chk.S",
@@ -820,9 +823,7 @@
         // initialized, resulting in nullptr dereferences.
         "bionic/getauxval.cpp",
 
-        // These four require getauxval, which isn't available on older
-        // platforms.
-        "bionic/getentropy_linux.c",
+        // These require getauxval, which isn't available on older platforms.
         "bionic/sysconf.cpp",
         "bionic/vdso.cpp",
         "bionic/setjmp_cookie.cpp",
@@ -1251,9 +1252,6 @@
         "bionic/dirent.cpp",
         "bionic/dup2.cpp",
         "bionic/environ.cpp",
-        "bionic/epoll_create.cpp",
-        "bionic/epoll_pwait.cpp",
-        "bionic/epoll_wait.cpp",
         "bionic/error.cpp",
         "bionic/eventfd_read.cpp",
         "bionic/eventfd_write.cpp",
@@ -1272,6 +1270,7 @@
         "bionic/futimens.cpp",
         "bionic/getcwd.cpp",
         "bionic/getdomainname.cpp",
+        "bionic/getentropy.cpp",
         "bionic/gethostname.cpp",
         "bionic/getpagesize.cpp",
         "bionic/getpgrp.cpp",
@@ -1336,25 +1335,7 @@
         "bionic/seteuid.cpp",
         "bionic/setpgrp.cpp",
         "bionic/sigaction.cpp",
-        "bionic/sigaddset.cpp",
-        "bionic/sigdelset.cpp",
-        "bionic/sigemptyset.cpp",
-        "bionic/sigfillset.cpp",
-        "bionic/sighold.cpp",
-        "bionic/sigignore.cpp",
-        "bionic/sigismember.cpp",
         "bionic/signal.cpp",
-        "bionic/signalfd.cpp",
-        "bionic/sigpause.cpp",
-        "bionic/sigpending.cpp",
-        "bionic/sigprocmask.cpp",
-        "bionic/sigqueue.cpp",
-        "bionic/sigrelse.cpp",
-        "bionic/sigset.cpp",
-        "bionic/sigsuspend.cpp",
-        "bionic/sigtimedwait.cpp",
-        "bionic/sigwait.cpp",
-        "bionic/sigwaitinfo.cpp",
         "bionic/socket.cpp",
         "bionic/spawn.cpp",
         "bionic/stat.cpp",
@@ -1371,10 +1352,12 @@
         "bionic/swab.cpp",
         "bionic/symlink.cpp",
         "bionic/sync_file_range.cpp",
+        "bionic/sys_epoll.cpp",
         "bionic/sys_msg.cpp",
         "bionic/sys_sem.cpp",
         "bionic/sys_shm.cpp",
         "bionic/sys_siglist.c",
+        "bionic/sys_signalfd.cpp",
         "bionic/sys_signame.c",
         "bionic/sys_time.cpp",
         "bionic/sysinfo.cpp",
@@ -1451,7 +1434,6 @@
         "bionic/pthread_self.cpp",
         "bionic/pthread_setname_np.cpp",
         "bionic/pthread_setschedparam.cpp",
-        "bionic/pthread_sigmask.cpp",
         "bionic/pthread_spinlock.cpp",
 
         // The following implementations depend on pthread data or implementation,
@@ -1670,6 +1652,7 @@
 cc_library {
     defaults: ["libc_defaults"],
     name: "libc",
+    static_ndk_lib: true,
     product_variables: {
         platform_sdk_version: {
             asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1706,16 +1689,22 @@
     // Do not pack libc.so relocations; see http://b/20645321 for details.
     pack_relocations: false,
 
-    // WARNING: The only library libc.so should depend on is libdl.so!  If you add other libraries,
-    // make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries.  This
-    // ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
-    // external; if that were the case, then libc would not pull those symbols from libgcc.a as it
-    // should, instead relying on the external symbols from the dependent libraries.  That would
-    // create a "cloaked" dependency on libgcc.a in libc though the libraries, which is not what
-    // you wanted!
+    // WARNING: The only libraries libc.so should depend on are libdl.so and ld-android.so!
+    // If you add other libraries, make sure to add -Wl,--exclude-libs=libgcc.a to the
+    // LOCAL_LDFLAGS for those libraries.  This ensures that symbols that are pulled into
+    // those new libraries from libgcc.a are not declared external; if that were the case,
+    // then libc would not pull those symbols from libgcc.a as it should, instead relying
+    // on the external symbols from the dependent libraries.  That would create a "cloaked"
+    // dependency on libgcc.a in libc though the libraries, which is not what you wanted!
 
-    shared_libs: ["libdl"],
-    whole_static_libs: ["libc_common", "libjemalloc"],
+    shared_libs: [
+        "ld-android",
+        "libdl",
+    ],
+    whole_static_libs: [
+        "libc_common",
+        "libjemalloc",
+    ],
 
     nocrt: true,
 
@@ -1779,6 +1768,7 @@
         "bionic/new.cpp",
     ],
     name: "libstdc++",
+    static_ndk_lib: true,
     system_shared_libs: ["libc"],
     static_libs: ["libasync_safe"],
 
@@ -1812,7 +1802,11 @@
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
 
-    cflags: ["-Wno-gcc-compat", "-Wall", "-Werror"],
+    cflags: [
+        "-Wno-gcc-compat",
+        "-Wall",
+        "-Werror",
+    ],
 }
 
 cc_defaults {
@@ -2122,4 +2116,11 @@
     first_version: "9",
 }
 
-subdirs = ["*"]
+// Export these headers for toolbox to process
+filegroup {
+    name: "kernel_input_headers",
+    srcs: [
+        "kernel/uapi/linux/input.h",
+        "kernel/uapi/linux/input-event-codes.h",
+    ],
+}
diff --git a/libc/NOTICE b/libc/NOTICE
index db4b5a5..f9a2aff 100644
--- a/libc/NOTICE
+++ b/libc/NOTICE
@@ -1041,6 +1041,34 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2018 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
 Copyright (c) 1980, 1983, 1988, 1993
    The Regents of the University of California.  All rights reserved.
 
@@ -5483,26 +5511,6 @@
 
 -------------------------------------------------------------------
 
-Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
-Copyright (c) 2014 Bob Beck <beck@obtuse.com>
-
-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.
-
-Emulation of getentropy(2) as documented at:
-http://man.openbsd.org/getentropy.2
-
--------------------------------------------------------------------
-
 Copyright (c) 2014, Intel Corporation
 All rights reserved.
 
diff --git a/libc/SECCOMP_BLACKLIST_APP.TXT b/libc/SECCOMP_BLACKLIST_APP.TXT
new file mode 100644
index 0000000..25542d6
--- /dev/null
+++ b/libc/SECCOMP_BLACKLIST_APP.TXT
@@ -0,0 +1,68 @@
+# 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
+#
+# Each non-blank, non-comment line has the following format:
+#
+# return_type func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
+#
+# where:
+#       arch_list ::= "all" | arch+
+#       arch      ::= "arm" | "arm64" | "mips" | "mips64" | "x86" | "x86_64"
+#
+# Note:
+#      - syscall_name corresponds to the name of the syscall, which may differ from
+#        the exported function name (example: the exit syscall is implemented by the _exit()
+#        function, which is not the same as the standard C exit() function which calls it)
+
+#      - alias_list is optional comma separated list of function aliases
+#
+#      - The call_id parameter, given that func_name and syscall_name have
+#        been provided, allows the user to specify dispatch style syscalls.
+#        For example, socket() syscall on i386 actually becomes:
+#          socketcall(__NR_socket, 1, *(rest of args on stack)).
+#
+#      - Each parameter type is assumed to be stored in 32 bits.
+#
+# This file is processed by a python script named genseccomp.py.
+
+# syscalls to modify IDs
+int     setgid:setgid32(gid_t)     arm,x86
+int     setgid:setgid(gid_t)       arm64,mips,mips64,x86_64
+int     setuid:setuid32(uid_t)    arm,x86
+int     setuid:setuid(uid_t)      arm64,mips,mips64,x86_64
+int     setreuid:setreuid32(uid_t, uid_t)   arm,x86
+int     setreuid:setreuid(uid_t, uid_t)     arm64,mips,mips64,x86_64
+int     setresuid:setresuid32(uid_t, uid_t, uid_t)   arm,x86
+int     setresuid:setresuid(uid_t, uid_t, uid_t)     arm64,mips,mips64,x86_64
+int     setresgid:setresgid32(gid_t, gid_t, gid_t)   arm,x86
+int     setresgid:setresgid(gid_t, gid_t, gid_t)     arm64,mips,mips64,x86_64
+int     setfsgid(gid_t)  all
+int     setfsuid(uid_t)  all
+int     setgroups:setgroups32(int, const gid_t*)   arm,x86
+int     setgroups:setgroups(int, const gid_t*)     arm64,mips,mips64,x86_64
+
+# syscalls to modify times
+int     adjtimex(struct timex*)   all
+int     clock_adjtime(clockid_t, struct timex*)   all
+int     clock_settime(clockid_t, const struct timespec*)  all
+int     settimeofday(const struct timeval*, const struct timezone*)   all
+
+int     acct(const char*  filepath)  all
+int     klogctl:syslog(int, char*, int)   all
+
+int     capset(cap_user_header_t header, const cap_user_data_t data) all
+int     chroot(const char*)  all
+
+# syscalls to change machine various configurations
+int     init_module(void*, unsigned long, const char*)  all
+int     delete_module(const char*, unsigned int)   all
+int     mount(const char*, const char*, const char*, unsigned long, const void*)  all
+int     umount2(const char*, int)  all
+int     swapon(const char*, int) all
+int     swapoff(const char*) all
+int     setdomainname(const char*, size_t)  all
+int     sethostname(const char*, size_t)  all
+int     __reboot:reboot(int, int, int, void*)  all
diff --git a/libc/SECCOMP_BLACKLIST.TXT b/libc/SECCOMP_BLACKLIST_COMMON.TXT
similarity index 95%
rename from libc/SECCOMP_BLACKLIST.TXT
rename to libc/SECCOMP_BLACKLIST_COMMON.TXT
index 2834515..f279002 100644
--- a/libc/SECCOMP_BLACKLIST.TXT
+++ b/libc/SECCOMP_BLACKLIST_COMMON.TXT
@@ -26,7 +26,7 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
+# 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.TXT b/libc/SECCOMP_WHITELIST_APP.TXT
similarity index 78%
copy from libc/SECCOMP_BLACKLIST.TXT
copy to libc/SECCOMP_WHITELIST_APP.TXT
index 2834515..2f3618c 100644
--- a/libc/SECCOMP_BLACKLIST.TXT
+++ b/libc/SECCOMP_WHITELIST_APP.TXT
@@ -1,9 +1,6 @@
 # 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
-#
 # Each non-blank, non-comment line has the following format:
 #
 # return_type func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
@@ -26,7 +23,4 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
-
-int     swapon(const char*, int) all
-int     swapoff(const char*) all
+# This file is processed by a python script named genseccomp.py.
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST_COMMON.TXT
similarity index 98%
rename from libc/SECCOMP_WHITELIST.TXT
rename to libc/SECCOMP_WHITELIST_COMMON.TXT
index 36a579b..a620b44 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST_COMMON.TXT
@@ -23,7 +23,7 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
+# This file is processed by a python script named genseccomp.py.
 
 # syscalls needed to boot android
 int	pivot_root:pivot_root(const char *new_root, const char *put_old)	arm64,x86_64,mips64
diff --git a/libc/SECCOMP_BLACKLIST.TXT b/libc/SECCOMP_WHITELIST_SYSTEM.TXT
similarity index 78%
copy from libc/SECCOMP_BLACKLIST.TXT
copy to libc/SECCOMP_WHITELIST_SYSTEM.TXT
index 2834515..155867f 100644
--- a/libc/SECCOMP_BLACKLIST.TXT
+++ b/libc/SECCOMP_WHITELIST_SYSTEM.TXT
@@ -1,9 +1,6 @@
 # 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
-#
 # Each non-blank, non-comment line has the following format:
 #
 # return_type func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
@@ -26,7 +23,6 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
+# This file is processed by a python script named genseccomp.py.
 
-int     swapon(const char*, int) all
-int     swapoff(const char*) all
+int bpf(int cmd, union bpf_attr *attr, unsigned int size) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 5c9a284..5c63c0f 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -229,12 +229,12 @@
 # signals
 int     __sigaction:sigaction(int, const struct sigaction*, struct sigaction*)  arm,mips,x86
 int     __rt_sigaction:rt_sigaction(int, const struct sigaction*, struct sigaction*, size_t)  all
-int     __rt_sigpending:rt_sigpending(sigset_t*, size_t)  all
-int     __rt_sigprocmask:rt_sigprocmask(int, const sigset_t*, sigset_t*, size_t)  all
-int     __rt_sigsuspend:rt_sigsuspend(const sigset_t*, size_t)  all
-int     __rt_sigtimedwait:rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t)  all
+int     __rt_sigpending:rt_sigpending(sigset64_t*, size_t)  all
+int     __rt_sigprocmask:rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t)  all
+int     __rt_sigsuspend:rt_sigsuspend(const sigset64_t*, size_t)  all
+int     __rt_sigtimedwait:rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t)  all
 int     ___rt_sigqueueinfo:rt_sigqueueinfo(pid_t, int, siginfo_t*)  all
-int     __signalfd4:signalfd4(int, const sigset_t*, size_t, int)  all
+int     __signalfd4:signalfd4(int, const sigset64_t*, size_t, int)  all
 
 # sockets
 int           __socket:socket(int, int, int)              arm,arm64,mips,mips64,x86_64
@@ -305,7 +305,7 @@
 
 int epoll_create1(int)  all
 int epoll_ctl(int, int op, int, struct epoll_event*)  all
-int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*, size_t)  all
+int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset64_t*, size_t)  all
 
 int eventfd:eventfd2(unsigned int, int)  all
 
@@ -317,7 +317,7 @@
 int inotify_rm_watch(int, unsigned int)  all
 
 int __pselect6:pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*)  all
-int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset_t*, size_t)  all
+int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t)  all
 
 ssize_t process_vm_readv(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long)  all
 ssize_t process_vm_writev(pid_t, const struct iovec*, unsigned long, const struct iovec*, unsigned long, unsigned long)  all
diff --git a/libc/arch-arm/bionic/exidx_static.c b/libc/arch-arm/bionic/exidx_static.c
index 72c0a5b..1686d6a 100644
--- a/libc/arch-arm/bionic/exidx_static.c
+++ b/libc/arch-arm/bionic/exidx_static.c
@@ -30,7 +30,7 @@
 
 /* Find the .ARM.exidx section (which in the case of a static executable
  * can be identified through its start and end symbols), and return its
- * beginning and numbe of entries to the caller.  Note that for static
+ * beginning and number of entries to the caller.  Note that for static
  * executables we do not need to use the value of the PC to find the
  * EXIDX section.
  */
@@ -38,9 +38,7 @@
 extern unsigned __exidx_end;
 extern unsigned __exidx_start;
 
-_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc __attribute__((unused)), 
-                                    int *pcount)
-{
-	*pcount = (__exidx_end-__exidx_start)/8;
-	return (_Unwind_Ptr)__exidx_start;
+_Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr pc __attribute__((unused)), int* pcount) {
+  *pcount = (&__exidx_end - &__exidx_start) / 8;
+  return (_Unwind_Ptr)&__exidx_start;
 }
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index b814124..30e7e23 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -56,12 +56,14 @@
 //
 // word   name            description
 // 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
-// 1      sigmask         signal mask (not used with _setjmp / _longjmp)
-// 2      float_base      base of float registers (d8 to d15)
-// 18     float_state     floating-point status and control register
-// 19     core_base       base of core registers (r4-r11, r13-r14)
-// 29     checksum        checksum of all of the core registers, to give better error messages.
-// 30     reserved        reserved entries (room to grow)
+// 1      sigmask         64-bit signal mask (not used with _setjmp / _longjmp)
+// 2      "               "
+// 3      reserved        (unused to allow float_base to be maximally aligned)
+// 4      float_base      base of float registers (d8 to d15)
+// 20     float_state     floating-point status and control register
+// 21     core_base       base of core registers (r4-r11, r13-r14)
+// 31     checksum        checksum of all of the core registers, to give better error messages.
+// 32     reserved        reserved entries (room to grow)
 // 64
 //
 // NOTE: float_base must be at an even word index, since the
@@ -69,8 +71,8 @@
 //       that expect 8-byte alignment.
 
 #define _JB_SIGFLAG     0
-#define _JB_SIGMASK     (_JB_SIGFLAG+1)
-#define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
+#define _JB_SIGMASK     (_JB_SIGFLAG + 1)
+#define _JB_FLOAT_BASE  (_JB_SIGMASK + 3)
 #define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
 #define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
 #define _JB_CHECKSUM    (_JB_CORE_BASE+10)
@@ -151,7 +153,7 @@
   add r2, r0, #(_JB_SIGMASK * 4)
   mov r0, #2 // SIG_SETMASK
   mov r1, #0
-  bl sigprocmask
+  bl sigprocmask64
 
   // Unalign the stack.
   add sp, #4
@@ -218,8 +220,10 @@
   beq 1f
 
   // Restore the signal mask.
-  ldr r0, [r0, #(_JB_SIGMASK * 4)]
-  bl sigsetmask
+  mov r2, #0
+  add r1, r0, #(_JB_SIGMASK * 4)
+  mov r0, #2 // SIG_SETMASK
+  bl sigprocmask64
 
 1:
   ldmfd sp!, {r0, r1, lr}
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index 45c9ea7..31ad621 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -36,7 +36,7 @@
 SECTION(".fini_array") void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
 #undef SECTION
 
-static void _start_main(void* raw_args) __used {
+__used static void _start_main(void* raw_args) {
   structors_array_t array;
   array.preinit_array = &__PREINIT_ARRAY__;
   array.init_array = &__INIT_ARRAY__;
@@ -66,3 +66,6 @@
 #include "__dso_handle.h"
 #include "atexit.h"
 #include "pthread_atfork.h"
+#ifdef __i386__
+# include "../../arch-x86/bionic/__stack_chk_fail_local.h"
+#endif
diff --git a/libc/arch-common/bionic/crtbegin_so.c b/libc/arch-common/bionic/crtbegin_so.c
index 258a6cd..3754363 100644
--- a/libc/arch-common/bionic/crtbegin_so.c
+++ b/libc/arch-common/bionic/crtbegin_so.c
@@ -57,3 +57,6 @@
 # include "atexit.h"
 #endif
 #include "pthread_atfork.h"
+#ifdef __i386__
+# include "../../arch-x86/bionic/__stack_chk_fail_local.h"
+#endif
diff --git a/libc/arch-common/bionic/pthread_atfork.h b/libc/arch-common/bionic/pthread_atfork.h
index 0c48a12..c6a33ff 100644
--- a/libc/arch-common/bionic/pthread_atfork.h
+++ b/libc/arch-common/bionic/pthread_atfork.h
@@ -14,6 +14,12 @@
  * limitations under the License.
  */
 
+#include <android/api-level.h>
+
+// __register_atfork wasn't available until android-23. We need to build a
+// pre-23 and 23+ version of crtbegin.
+#if __ANDROID_API__ >= __ANDROID_API_M__
+
 extern void* __dso_handle;
 
 extern int __register_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void), void* dso);
@@ -27,3 +33,4 @@
   return __register_atfork(prepare, parent, child, &__dso_handle);
 }
 
+#endif  /* __ANDROID_API__ >= __ANDROID_API_M__ */
diff --git a/libc/arch-x86/bionic/__stack_chk_fail_local.h b/libc/arch-x86/bionic/__stack_chk_fail_local.h
new file mode 100644
index 0000000..0b0fd7f
--- /dev/null
+++ b/libc/arch-x86/bionic/__stack_chk_fail_local.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+/*
+   __stack_chk_fail routine is runtime part of stack protector compiler
+   feature. It's implemented in libc and represents die routine when stack
+   corruption is detected.
+
+   Calls are generated by compiler and injected into user functions when
+   -fstack-protector* options are used.
+
+   __stack_chk_fail_local is wrapper for __stack_chk_fail. Compiler generates
+   wrapper calls instead for PIC code only and only on IA32 for optimization
+   purpose (see gcc/config/i386/i386.c). Wrapper body is always included into
+   executable or library. This is the idea of optimization.
+
+   Glibc is doing this via libc_nonshared.a which is linked automatically
+   everytime with libc.so. In bionic we have to bring it within crtfiles
+   because libc.so is real library and not a link script like libc.so at glibc.
+
+   For x86_64 or non-PIC code compiler always generates __stack_chk_fail calls.
+*/
+
+#ifdef __i386__
+extern void __stack_chk_fail();
+
+__LIBC_HIDDEN__ void __stack_chk_fail_local() {
+  __stack_chk_fail();
+}
+#endif
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index 6e6c365..1e1ce58 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -42,10 +42,10 @@
 // 3      ebp
 // 4      esi
 // 5      edi
-// 6      sigmask         signal mask (not used with _setjmp / _longjmp)
-// 7      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
-// 8      checksum        checksum of the core registers, to give better error messages.
-// 9      reserved
+// 6      sigmask         64-bit signal mask (not used with _setjmp / _longjmp)
+// 7      "               "
+// 8      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 9      checksum        checksum of the core registers, to give better error messages.
 
 #define _JB_EDX 0
 #define _JB_EBX 1
@@ -54,8 +54,8 @@
 #define _JB_ESI 4
 #define _JB_EDI 5
 #define _JB_SIGMASK 6
-#define _JB_SIGFLAG 7
-#define _JB_CHECKSUM 8
+#define _JB_SIGFLAG 8
+#define _JB_CHECKSUM 9
 
 .macro m_mangle_registers reg
   xorl \reg,%edx
@@ -110,16 +110,17 @@
   testl $1,%eax
   jz 1f
 
-  // Get the current signal mask.
+  // Save the current signal mask.
+  pushl %ecx
   PIC_PROLOGUE
-  pushl $0
-  call PIC_PLT(sigblock)
-  addl $4,%esp
+  leal (_JB_SIGMASK * 4)(%ecx),%eax
+  pushl %eax
+  pushl $0 // NULL
+  pushl $2 // SIG_SETMASK
+  call PIC_PLT(sigprocmask64)
+  addl $12,%esp
   PIC_EPILOGUE
-
-  // Save the signal mask.
-  movl 4(%esp),%ecx
-  movl %eax,(_JB_SIGMASK * 4)(%ecx)
+  popl %ecx
 
 1:
   // Fetch the setjmp cookie and clear the signal flag bit.
@@ -159,10 +160,13 @@
   jz 1f
 
   // Restore the signal mask.
+  leal (_JB_SIGMASK * 4)(%edx),%eax
   PIC_PROLOGUE
-  pushl (_JB_SIGMASK * 4)(%edx)
-  call PIC_PLT(sigsetmask)
-  addl $4,%esp
+  pushl $0 // NULL
+  pushl %eax
+  pushl $2 // SIG_SETMASK
+  call PIC_PLT(sigprocmask64)
+  addl $12,%esp
   PIC_EPILOGUE
 
 1:
diff --git a/libc/bionic/__cxa_thread_atexit_impl.cpp b/libc/bionic/__cxa_thread_atexit_impl.cpp
index f687fd1..99077c1 100644
--- a/libc/bionic/__cxa_thread_atexit_impl.cpp
+++ b/libc/bionic/__cxa_thread_atexit_impl.cpp
@@ -28,6 +28,8 @@
 };
 
 extern "C" int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle);
+extern "C" void __loader_add_thread_local_dtor(void* dso_handle) __attribute__((weak));
+extern "C" void __loader_remove_thread_local_dtor(void* dso_handle) __attribute__((weak));
 
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) {
@@ -40,6 +42,9 @@
   pthread_internal_t* thread = __get_thread();
   dtor->next = thread->thread_local_dtors;
   thread->thread_local_dtors = dtor;
+  if (__loader_add_thread_local_dtor != nullptr) {
+    __loader_add_thread_local_dtor(dso_handle);
+  }
   return 0;
 }
 
@@ -50,6 +55,9 @@
     thread->thread_local_dtors = current->next;
 
     current->func(current->arg);
+    if (__loader_remove_thread_local_dtor != nullptr) {
+      __loader_remove_thread_local_dtor(current->dso_handle);
+    }
     delete current;
   }
 }
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index f401cab..d2c99a5 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -60,22 +60,19 @@
 
   // Don't block SIGABRT to give any signal handler a chance; we ignore
   // any errors -- X311J doesn't allow abort to return anyway.
-  sigset_t mask;
-  sigfillset(&mask);
-  sigdelset(&mask, SIGABRT);
-  sigprocmask(SIG_SETMASK, &mask, NULL);
+  sigset64_t mask;
+  sigfillset64(&mask);
+  sigdelset64(&mask, SIGABRT);
 
+  sigprocmask64(SIG_SETMASK, &mask, nullptr);
   inline_tgkill(pid, tid, SIGABRT);
 
-  // If SIGABRT ignored, or caught and the handler returns,
+  // If SIGABRT is ignored or it's caught and the handler returns,
   // remove the SIGABRT signal handler and raise SIGABRT again.
-  struct sigaction sa;
-  sa.sa_handler = SIG_DFL;
-  sa.sa_flags   = SA_RESTART;
-  sigemptyset(&sa.sa_mask);
-  sigaction(SIGABRT, &sa, &sa);
-  sigprocmask(SIG_SETMASK, &mask, NULL);
+  struct sigaction64 sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART };
+  sigaction64(SIGABRT, &sa, nullptr);
 
+  sigprocmask64(SIG_SETMASK, &mask, nullptr);
   inline_tgkill(pid, tid, SIGABRT);
 
   // If we get this far, just exit.
diff --git a/libc/bionic/bionic_futex.cpp b/libc/bionic/bionic_futex.cpp
index dd66e40..0ac1f6e 100644
--- a/libc/bionic/bionic_futex.cpp
+++ b/libc/bionic/bionic_futex.cpp
@@ -32,8 +32,9 @@
 
 #include "private/bionic_time_conversions.h"
 
-int __futex_wait_ex(volatile void* ftx, bool shared, int value, bool use_realtime_clock,
-                    const timespec* abs_timeout) {
+static inline __always_inline int FutexWithTimeout(volatile void* ftx, int op, int value,
+                                                   bool use_realtime_clock,
+                                                   const timespec* abs_timeout, int bitset) {
   const timespec* futex_abs_timeout = abs_timeout;
   // pthread's and semaphore's default behavior is to use CLOCK_REALTIME, however this behavior is
   // essentially never intended, as that clock is prone to change discontinuously.
@@ -54,6 +55,17 @@
     futex_abs_timeout = &converted_monotonic_abs_timeout;
   }
 
-  return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE), value,
-                 futex_abs_timeout, FUTEX_BITSET_MATCH_ANY);
+  return __futex(ftx, op, value, futex_abs_timeout, bitset);
+}
+
+int __futex_wait_ex(volatile void* ftx, bool shared, int value, bool use_realtime_clock,
+                    const timespec* abs_timeout) {
+  return FutexWithTimeout(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE), value,
+                          use_realtime_clock, abs_timeout, FUTEX_BITSET_MATCH_ANY);
+}
+
+int __futex_pi_lock_ex(volatile void* ftx, bool shared, bool use_realtime_clock,
+                       const timespec* abs_timeout) {
+  return FutexWithTimeout(ftx, (shared ? FUTEX_LOCK_PI : FUTEX_LOCK_PI_PRIVATE), 0,
+                          use_realtime_clock, abs_timeout, 0);
 }
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index 970a92b..bac3d88 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -29,12 +29,11 @@
 #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() {
-  static CachedProperty g_debug_atrace_tags_enableflags("debug.atrace.tags.enableflags");
-  static uint64_t g_tags;
-
   g_lock.lock();
   if (g_debug_atrace_tags_enableflags.DidChange()) {
     g_tags = strtoull(g_debug_atrace_tags_enableflags.Get(), nullptr, 0);
diff --git a/libc/bionic/epoll_create.cpp b/libc/bionic/epoll_create.cpp
deleted file mode 100644
index 74f664f..0000000
--- a/libc/bionic/epoll_create.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 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 <sys/epoll.h>
-
-int epoll_create(int size) {
-  if (size <= 0) {
-    errno = EINVAL;
-    return -1;
-  }
-  return epoll_create1(0);
-}
diff --git a/libc/bionic/epoll_wait.cpp b/libc/bionic/epoll_wait.cpp
deleted file mode 100644
index deb19da..0000000
--- a/libc/bionic/epoll_wait.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2013 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/epoll.h>
-
-int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) {
-  return epoll_pwait(fd, events, max_events, timeout, NULL);
-}
diff --git a/libc/bionic/getentropy.cpp b/libc/bionic/getentropy.cpp
new file mode 100644
index 0000000..2c6e417
--- /dev/null
+++ b/libc/bionic/getentropy.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 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 <fcntl.h>
+#include <sys/random.h>
+#include <unistd.h>
+
+static int getentropy_urandom(void* buffer, size_t buffer_size, int saved_errno) {
+  int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_NOFOLLOW | O_CLOEXEC, 0));
+  if (fd == -1) return -1;
+
+  size_t collected = 0;
+  while (collected < buffer_size) {
+    ssize_t count = TEMP_FAILURE_RETRY(read(fd, static_cast<char*>(buffer) + collected,
+                                            buffer_size - collected));
+    if (count == -1) {
+      close(fd);
+      return -1;
+    }
+    collected += count;
+  }
+
+  close(fd);
+  errno = saved_errno;
+  return 0;
+}
+
+int getentropy(void* buffer, size_t buffer_size) {
+  if (buffer_size > 256) {
+    errno = EIO;
+    return -1;
+  }
+
+  int saved_errno = errno;
+
+  size_t collected = 0;
+  while (collected < buffer_size) {
+    long count = TEMP_FAILURE_RETRY(getrandom(static_cast<char*>(buffer) + collected,
+                                              buffer_size - collected, GRND_NONBLOCK));
+    if (count == -1) {
+      // EAGAIN: there isn't enough entropy right now.
+      // ENOSYS/EINVAL: getrandom(2) or GRND_NONBLOCK isn't supported.
+      // EFAULT: `buffer` is invalid.
+      // Try /dev/urandom regardless because it can't hurt,
+      // and we don't need to optimize the EFAULT case.
+      // See http://b/33059407 and http://b/67015565.
+      return getentropy_urandom(buffer, buffer_size, saved_errno);
+    }
+    collected += count;
+  }
+
+  errno = saved_errno;
+  return 0;
+}
diff --git a/libc/bionic/getentropy_linux.c b/libc/bionic/getentropy_linux.c
deleted file mode 100644
index cf0aa45..0000000
--- a/libc/bionic/getentropy_linux.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*	$OpenBSD: getentropy_linux.c,v 1.42 2016/04/19 20:20:24 tj Exp $	*/
-
-/*
- * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
- * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
- *
- * 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.
- *
- * Emulation of getentropy(2) as documented at:
- * http://man.openbsd.org/getentropy.2
- */
-
-#define	_POSIX_C_SOURCE	199309L
-#define	_GNU_SOURCE	1
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/resource.h>
-#include <sys/syscall.h>
-#ifdef SYS__sysctl
-#include <linux/sysctl.h>
-#endif
-#include <sys/statvfs.h>
-#include <sys/socket.h>
-#include <sys/mount.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <link.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#ifdef HAVE_OPENSSL
-#include <openssl/sha.h>
-#endif
-
-#include <linux/types.h>
-#include <linux/random.h>
-#ifdef HAVE_GETAUXVAL
-#include <sys/auxv.h>
-#endif
-#include <sys/vfs.h>
-
-#define REPEAT 5
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-
-#define HX(a, b) \
-	do { \
-		if ((a)) \
-			HD(errno); \
-		else \
-			HD(b); \
-	} while (0)
-
-#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
-#define HD(x)	 (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
-#define HF(x)    (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
-
-int	getentropy(void *buf, size_t len);
-
-static int gotdata(char *buf, size_t len);
-static int getentropy_getrandom(void *buf, size_t len);
-static int getentropy_urandom(void *buf, size_t len);
-#ifdef SYS__sysctl
-static int getentropy_sysctl(void *buf, size_t len);
-#endif
-#ifdef HAVE_OPENSSL
-static int getentropy_fallback(void *buf, size_t len);
-static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
-#endif
-
-int
-getentropy(void *buf, size_t len)
-{
-	int ret = -1;
-
-	if (len > 256) {
-		errno = EIO;
-		return (-1);
-	}
-
-	/*
-	 * Try descriptor-less getrandom()
-	 */
-	ret = getentropy_getrandom(buf, len);
-	if (ret != -1)
-		return (ret);
-	if (errno != ENOSYS && errno != EAGAIN)
-		return (-1);
-
-	/*
-	 * Try to get entropy with /dev/urandom
-	 *
-	 * This can fail if the process is inside a chroot or if file
-	 * descriptors are exhausted.
-	 */
-	ret = getentropy_urandom(buf, len);
-	if (ret != -1)
-		return (ret);
-
-#ifdef SYS__sysctl
-	/*
-	 * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
-	 * sysctl is a failsafe API, so it guarantees a result.  This
-	 * should work inside a chroot, or when file descriptors are
-	 * exhausted.
-	 *
-	 * However this can fail if the Linux kernel removes support
-	 * for sysctl.  Starting in 2007, there have been efforts to
-	 * deprecate the sysctl API/ABI, and push callers towards use
-	 * of the chroot-unavailable fd-using /proc mechanism --
-	 * essentially the same problems as /dev/urandom.
-	 *
-	 * Numerous setbacks have been encountered in their deprecation
-	 * schedule, so as of June 2014 the kernel ABI still exists on
-	 * most Linux architectures. The sysctl() stub in libc is missing
-	 * on some systems.  There are also reports that some kernels
-	 * spew messages to the console.
-	 */
-	ret = getentropy_sysctl(buf, len);
-	if (ret != -1)
-		return (ret);
-#endif /* SYS__sysctl */
-
-	/*
-	 * Entropy collection via /dev/urandom and sysctl have failed.
-	 *
-	 * No other API exists for collecting entropy.  See the large
-	 * comment block above.
-	 *
-	 * We have very few options:
-	 *     - Even syslog_r is unsafe to call at this low level, so
-	 *	 there is no way to alert the user or program.
-	 *     - Cannot call abort() because some systems have unsafe
-	 *	 corefiles.
-	 *     - Could raise(SIGKILL) resulting in silent program termination.
-	 *     - Return EIO, to hint that arc4random's stir function
-	 *       should raise(SIGKILL)
-	 *     - Do the best under the circumstances....
-	 *
-	 * This code path exists to bring light to the issue that Linux
-	 * does not provide a failsafe API for entropy collection.
-	 *
-	 * We hope this demonstrates that Linux should either retain their
-	 * sysctl ABI, or consider providing a new failsafe API which
-	 * works in a chroot or when file descriptors are exhausted.
-	 */
-#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
-#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
-	raise(SIGKILL);
-#endif
-#ifdef HAVE_OPENSSL
-	ret = getentropy_fallback(buf, len);
-	if (ret != -1)
-		return (ret);
-#endif
-
-	errno = EIO;
-	return (ret);
-}
-
-/*
- * Basic sanity checking; wish we could do better.
- */
-static int
-gotdata(char *buf, size_t len)
-{
-	char	any_set = 0;
-	size_t	i;
-
-	for (i = 0; i < len; ++i)
-		any_set |= buf[i];
-	if (any_set == 0)
-		return (-1);
-	return (0);
-}
-
-static int
-getentropy_getrandom(void *buf, size_t len)
-{
-	int pre_errno = errno;
-	int ret;
-	if (len > 256)
-		return (-1);
-	do {
-		/*
-		 * Use GRND_NONBLOCK to avoid blocking before the
-		 * entropy pool has been initialized
-		 */
-		ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
-	} while (ret == -1 && errno == EINTR);
-
-	if ((size_t)ret != len)
-		return (-1);
-	errno = pre_errno;
-	return (0);
-}
-
-static int
-getentropy_urandom(void *buf, size_t len)
-{
-	struct stat st;
-	size_t i;
-	int fd, cnt, flags;
-	int save_errno = errno;
-
-start:
-
-	flags = O_RDONLY;
-#ifdef O_NOFOLLOW
-	flags |= O_NOFOLLOW;
-#endif
-#ifdef O_CLOEXEC
-	flags |= O_CLOEXEC;
-#endif
-	fd = open("/dev/urandom", flags, 0);
-	if (fd == -1) {
-		if (errno == EINTR)
-			goto start;
-		goto nodevrandom;
-	}
-#ifndef O_CLOEXEC
-	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-#endif
-
-	/* Lightly verify that the device node looks sane */
-	if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
-		close(fd);
-		goto nodevrandom;
-	}
-	if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
-		close(fd);
-		goto nodevrandom;
-	}
-	for (i = 0; i < len; ) {
-		size_t wanted = len - i;
-		ssize_t ret = read(fd, (char *)buf + i, wanted);
-
-		if (ret == -1) {
-			if (errno == EAGAIN || errno == EINTR)
-				continue;
-			close(fd);
-			goto nodevrandom;
-		}
-		i += ret;
-	}
-	close(fd);
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return (0);		/* satisfied */
-	}
-nodevrandom:
-	errno = EIO;
-	return (-1);
-}
-
-#ifdef SYS__sysctl
-static int
-getentropy_sysctl(void *buf, size_t len)
-{
-	static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
-	size_t i;
-	int save_errno = errno;
-
-	for (i = 0; i < len; ) {
-		size_t chunk = min(len - i, 16);
-
-		/* SYS__sysctl because some systems already removed sysctl() */
-		struct __sysctl_args args = {
-			.name = mib,
-			.nlen = 3,
-			.oldval = (char *)buf + i,
-			.oldlenp = &chunk,
-		};
-		if (syscall(SYS__sysctl, &args) != 0)
-			goto sysctlfailed;
-		i += chunk;
-	}
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return (0);			/* satisfied */
-	}
-sysctlfailed:
-	errno = EIO;
-	return (-1);
-}
-#endif /* SYS__sysctl */
-
-#ifdef HAVE_OPENSSL
-static const int cl[] = {
-	CLOCK_REALTIME,
-#ifdef CLOCK_MONOTONIC
-	CLOCK_MONOTONIC,
-#endif
-#ifdef CLOCK_MONOTONIC_RAW
-	CLOCK_MONOTONIC_RAW,
-#endif
-#ifdef CLOCK_TAI
-	CLOCK_TAI,
-#endif
-#ifdef CLOCK_VIRTUAL
-	CLOCK_VIRTUAL,
-#endif
-#ifdef CLOCK_UPTIME
-	CLOCK_UPTIME,
-#endif
-#ifdef CLOCK_PROCESS_CPUTIME_ID
-	CLOCK_PROCESS_CPUTIME_ID,
-#endif
-#ifdef CLOCK_THREAD_CPUTIME_ID
-	CLOCK_THREAD_CPUTIME_ID,
-#endif
-};
-
-static int
-getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
-{
-	SHA512_CTX *ctx = data;
-
-	SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
-	return (0);
-}
-
-static int
-getentropy_fallback(void *buf, size_t len)
-{
-	uint8_t results[SHA512_DIGEST_LENGTH];
-	int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
-	static int cnt;
-	struct timespec ts;
-	struct timeval tv;
-	struct rusage ru;
-	sigset_t sigset;
-	struct stat st;
-	SHA512_CTX ctx;
-	static pid_t lastpid;
-	pid_t pid;
-	size_t i, ii, m;
-	char *p;
-
-	pid = getpid();
-	if (lastpid == pid) {
-		faster = 1;
-		repeat = 2;
-	} else {
-		faster = 0;
-		lastpid = pid;
-		repeat = REPEAT;
-	}
-	for (i = 0; i < len; ) {
-		int j;
-		SHA512_Init(&ctx);
-		for (j = 0; j < repeat; j++) {
-			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
-			if (e != -1) {
-				cnt += (int)tv.tv_sec;
-				cnt += (int)tv.tv_usec;
-			}
-
-			dl_iterate_phdr(getentropy_phdr, &ctx);
-
-			for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
-				HX(clock_gettime(cl[ii], &ts) == -1, ts);
-
-			HX((pid = getpid()) == -1, pid);
-			HX((pid = getsid(pid)) == -1, pid);
-			HX((pid = getppid()) == -1, pid);
-			HX((pid = getpgid(0)) == -1, pid);
-			HX((e = getpriority(0, 0)) == -1, e);
-
-			if (!faster) {
-				ts.tv_sec = 0;
-				ts.tv_nsec = 1;
-				(void) nanosleep(&ts, NULL);
-			}
-
-			HX(sigpending(&sigset) == -1, sigset);
-			HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
-			    sigset);
-
-			HF(getentropy);	/* an addr in this library */
-			HF(printf);		/* an addr in libc */
-			p = (char *)&p;
-			HD(p);		/* an addr on stack */
-			p = (char *)&errno;
-			HD(p);		/* the addr of errno */
-
-			if (i == 0) {
-				struct sockaddr_storage ss;
-				struct statvfs stvfs;
-				struct termios tios;
-				struct statfs stfs;
-				socklen_t ssl;
-				off_t off;
-
-				/*
-				 * Prime-sized mappings encourage fragmentation;
-				 * thus exposing some address entropy.
-				 */
-				struct mm {
-					size_t	npg;
-					void	*p;
-				} mm[] =	 {
-					{ 17, MAP_FAILED }, { 3, MAP_FAILED },
-					{ 11, MAP_FAILED }, { 2, MAP_FAILED },
-					{ 5, MAP_FAILED }, { 3, MAP_FAILED },
-					{ 7, MAP_FAILED }, { 1, MAP_FAILED },
-					{ 57, MAP_FAILED }, { 3, MAP_FAILED },
-					{ 131, MAP_FAILED }, { 1, MAP_FAILED },
-				};
-
-				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
-					HX(mm[m].p = mmap(NULL,
-					    mm[m].npg * pgs,
-					    PROT_READ|PROT_WRITE,
-					    MAP_PRIVATE|MAP_ANON, -1,
-					    (off_t)0), mm[m].p);
-					if (mm[m].p != MAP_FAILED) {
-						size_t mo;
-
-						/* Touch some memory... */
-						p = mm[m].p;
-						mo = cnt %
-						    (mm[m].npg * pgs - 1);
-						p[mo] = 1;
-						cnt += (int)((long)(mm[m].p)
-						    / pgs);
-					}
-
-					/* Check cnts and times... */
-					for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
-					    ii++) {
-						HX((e = clock_gettime(cl[ii],
-						    &ts)) == -1, ts);
-						if (e != -1)
-							cnt += (int)ts.tv_nsec;
-					}
-
-					HX((e = getrusage(RUSAGE_SELF,
-					    &ru)) == -1, ru);
-					if (e != -1) {
-						cnt += (int)ru.ru_utime.tv_sec;
-						cnt += (int)ru.ru_utime.tv_usec;
-					}
-				}
-
-				for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
-					if (mm[m].p != MAP_FAILED)
-						munmap(mm[m].p, mm[m].npg * pgs);
-					mm[m].p = MAP_FAILED;
-				}
-
-				HX(stat(".", &st) == -1, st);
-				HX(statvfs(".", &stvfs) == -1, stvfs);
-				HX(statfs(".", &stfs) == -1, stfs);
-
-				HX(stat("/", &st) == -1, st);
-				HX(statvfs("/", &stvfs) == -1, stvfs);
-				HX(statfs("/", &stfs) == -1, stfs);
-
-				HX((e = fstat(0, &st)) == -1, st);
-				if (e == -1) {
-					if (S_ISREG(st.st_mode) ||
-					    S_ISFIFO(st.st_mode) ||
-					    S_ISSOCK(st.st_mode)) {
-						HX(fstatvfs(0, &stvfs) == -1,
-						    stvfs);
-						HX(fstatfs(0, &stfs) == -1,
-						    stfs);
-						HX((off = lseek(0, (off_t)0,
-						    SEEK_CUR)) < 0, off);
-					}
-					if (S_ISCHR(st.st_mode)) {
-						HX(tcgetattr(0, &tios) == -1,
-						    tios);
-					} else if (S_ISSOCK(st.st_mode)) {
-						memset(&ss, 0, sizeof ss);
-						ssl = sizeof(ss);
-						HX(getpeername(0,
-						    (void *)&ss, &ssl) == -1,
-						    ss);
-					}
-				}
-
-				HX((e = getrusage(RUSAGE_CHILDREN,
-				    &ru)) == -1, ru);
-				if (e != -1) {
-					cnt += (int)ru.ru_utime.tv_sec;
-					cnt += (int)ru.ru_utime.tv_usec;
-				}
-			} else {
-				/* Subsequent hashes absorb previous result */
-				HD(results);
-			}
-
-			HX((e = gettimeofday(&tv, NULL)) == -1, tv);
-			if (e != -1) {
-				cnt += (int)tv.tv_sec;
-				cnt += (int)tv.tv_usec;
-			}
-
-			HD(cnt);
-		}
-#ifdef HAVE_GETAUXVAL
-#ifdef AT_RANDOM
-		/* Not as random as you think but we take what we are given */
-		p = (char *) getauxval(AT_RANDOM);
-		if (p)
-			HR(p, 16);
-#endif
-#ifdef AT_SYSINFO_EHDR
-		p = (char *) getauxval(AT_SYSINFO_EHDR);
-		if (p)
-			HR(p, pgs);
-#endif
-#ifdef AT_BASE
-		p = (char *) getauxval(AT_BASE);
-		if (p)
-			HD(p);
-#endif
-#endif
-
-		SHA512_Final(results, &ctx);
-		memcpy((char *)buf + i, results, min(sizeof(results), len - i));
-		i += min(sizeof(results), len - i);
-	}
-	memset(results, 0, sizeof results);
-	if (gotdata(buf, len) == 0) {
-		errno = save_errno;
-		return (0);		/* satisfied */
-	}
-	errno = EIO;
-	return (-1);
-}
-#endif /* HAVE_OPENSSL */
diff --git a/libc/bionic/icu.cpp b/libc/bionic/icu.cpp
index 78e551b..c09c9ea 100644
--- a/libc/bionic/icu.cpp
+++ b/libc/bionic/icu.cpp
@@ -68,7 +68,7 @@
   }
   free(namelist);
 
-  if (max_version == -1 || max_version < ICUDATA_VERSION_MIN) {
+  if (max_version < ICUDATA_VERSION_MIN) {
     async_safe_write_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find an ICU .dat file");
     return false;
   }
diff --git a/libc/bionic/pause.cpp b/libc/bionic/pause.cpp
index 94a16fb..534a804 100644
--- a/libc/bionic/pause.cpp
+++ b/libc/bionic/pause.cpp
@@ -26,17 +26,10 @@
  * SUCH DAMAGE.
  */
 
+#include <signal.h>
 #include <unistd.h>
 
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t);
-extern "C" int __rt_sigsuspend(const kernel_sigset_t*, size_t);
-
 int pause() {
-  kernel_sigset_t mask;
-  if (__rt_sigprocmask(SIG_SETMASK, NULL, &mask, sizeof(mask)) == -1) {
-    return -1;
-  }
-  return __rt_sigsuspend(&mask, sizeof(mask));
+  sigset64_t mask = {};
+  return sigsuspend64(&mask);
 }
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index dbc9584..1d72fe5 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -31,51 +31,56 @@
 #include <sys/select.h>
 
 #include "private/bionic_time_conversions.h"
-#include "private/kernel_sigset_t.h"
+#include "private/SigSetConverter.h"
 
-extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const kernel_sigset_t*, size_t);
+extern "C" int __ppoll(pollfd*, unsigned int, timespec*, const sigset64_t*, size_t);
 extern "C" int __pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*);
 
 int poll(pollfd* fds, nfds_t fd_count, int ms) __overloadable {
   timespec ts;
-  timespec* ts_ptr = NULL;
+  timespec* ts_ptr = nullptr;
   if (ms >= 0) {
     timespec_from_ms(ts, ms);
     ts_ptr = &ts;
   }
-  return __ppoll(fds, fd_count, ts_ptr, NULL, 0);
+  return __ppoll(fds, fd_count, ts_ptr, nullptr, 0);
 }
 
 int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) __overloadable {
+  // The underlying `__ppoll` system call only takes `sigset64_t`.
+  SigSetConverter set;
+  sigset64_t* ss_ptr = nullptr;
+  if (ss != nullptr) {
+    set = {};
+    set.sigset = *ss;
+    ss_ptr = &set.sigset64;
+  }
+  return ppoll64(fds, fd_count, ts, ss_ptr);
+}
+
+int ppoll64(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset64_t* ss) {
+  // The underlying __ppoll system call modifies its `struct timespec` argument.
   timespec mutable_ts;
-  timespec* mutable_ts_ptr = NULL;
-  if (ts != NULL) {
+  timespec* mutable_ts_ptr = nullptr;
+  if (ts != nullptr) {
     mutable_ts = *ts;
     mutable_ts_ptr = &mutable_ts;
   }
-
-  kernel_sigset_t kernel_ss;
-  kernel_sigset_t* kernel_ss_ptr = NULL;
-  if (ss != NULL) {
-    kernel_ss.set(ss);
-    kernel_ss_ptr = &kernel_ss;
-  }
-
-  return __ppoll(fds, fd_count, mutable_ts_ptr, kernel_ss_ptr, sizeof(kernel_ss));
+  return __ppoll(fds, fd_count, mutable_ts_ptr, ss, sizeof(*ss));
 }
 
 int select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) {
   timespec ts;
-  timespec* ts_ptr = NULL;
-  if (tv != NULL) {
+  timespec* ts_ptr = nullptr;
+  if (tv != nullptr) {
     if (!timespec_from_timeval(ts, *tv)) {
       errno = EINVAL;
       return -1;
     }
     ts_ptr = &ts;
   }
-  int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, NULL);
-  if (tv != NULL) {
+  int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, nullptr);
+  if (tv != nullptr) {
     timeval_from_timespec(*tv, ts);
   }
   return result;
@@ -83,20 +88,27 @@
 
 int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
             const timespec* ts, const sigset_t* ss) {
+  // The underlying `__pselect6` system call only takes `sigset64_t`.
+  SigSetConverter set;
+  sigset64_t* ss_ptr = nullptr;
+  if (ss != nullptr) {
+    set = {};
+    set.sigset = *ss;
+    ss_ptr = &set.sigset64;
+  }
+  return pselect64(fd_count, read_fds, write_fds, error_fds, ts, ss_ptr);
+}
+
+int pselect64(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
+              const timespec* ts, const sigset64_t* ss) {
+  // The underlying __pselect6 system call modifies its `struct timespec` argument.
   timespec mutable_ts;
-  timespec* mutable_ts_ptr = NULL;
-  if (ts != NULL) {
+  timespec* mutable_ts_ptr = nullptr;
+  if (ts != nullptr) {
     mutable_ts = *ts;
     mutable_ts_ptr = &mutable_ts;
   }
 
-  kernel_sigset_t kernel_ss;
-  kernel_sigset_t* kernel_ss_ptr = NULL;
-  if (ss != NULL) {
-    kernel_ss.set(ss);
-    kernel_ss_ptr = &kernel_ss;
-  }
-
   // The Linux kernel only handles 6 arguments and this system call really needs 7,
   // so the last argument is a void* pointing to:
   struct pselect6_extra_data_t {
@@ -104,8 +116,8 @@
     size_t ss_len;
   };
   pselect6_extra_data_t extra_data;
-  extra_data.ss_addr = reinterpret_cast<uintptr_t>(kernel_ss_ptr);
-  extra_data.ss_len = sizeof(kernel_ss);
+  extra_data.ss_addr = reinterpret_cast<uintptr_t>(ss);
+  extra_data.ss_len = sizeof(*ss);
 
   return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data);
 }
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index c46965f..2edfe97 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -26,8 +26,6 @@
  * SUCH DAMAGE.
  */
 
-#include "private/kernel_sigset_t.h"
-
 #include <errno.h>
 #include <malloc.h>
 #include <pthread.h>
@@ -37,7 +35,6 @@
 #include <time.h>
 
 // System calls.
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
 extern "C" int __timer_create(clockid_t, sigevent*, __kernel_timer_t*);
 extern "C" int __timer_delete(__kernel_timer_t);
 extern "C" int __timer_getoverrun(__kernel_timer_t);
@@ -74,17 +71,13 @@
 static void* __timer_thread_start(void* arg) {
   PosixTimer* timer = reinterpret_cast<PosixTimer*>(arg);
 
-  kernel_sigset_t sigset;
-  sigaddset(sigset.get(), TIMER_SIGNAL);
+  sigset64_t sigset = {};
+  sigaddset64(&sigset, TIMER_SIGNAL);
 
   while (true) {
     // Wait for a signal...
-    siginfo_t si;
-    memset(&si, 0, sizeof(si));
-    int rc = __rt_sigtimedwait(sigset.get(), &si, NULL, sizeof(sigset));
-    if (rc == -1) {
-      continue;
-    }
+    siginfo_t si = {};
+    if (sigtimedwait64(&sigset, &si, nullptr) == -1) continue;
 
     if (si.si_code == SI_TIMER) {
       // This signal was sent because a timer fired, so call the callback.
@@ -150,14 +143,14 @@
 
   // We start the thread with TIMER_SIGNAL blocked by blocking the signal here and letting it
   // inherit. If it tried to block the signal itself, there would be a race.
-  kernel_sigset_t sigset;
-  sigaddset(sigset.get(), TIMER_SIGNAL);
-  kernel_sigset_t old_sigset;
-  pthread_sigmask(SIG_BLOCK, sigset.get(), old_sigset.get());
+  sigset64_t sigset = {};
+  sigaddset64(&sigset, TIMER_SIGNAL);
+  sigset64_t old_sigset;
+  sigprocmask64(SIG_BLOCK, &sigset, &old_sigset);
 
   int rc = pthread_create(&timer->callback_thread, &thread_attributes, __timer_thread_start, timer);
 
-  pthread_sigmask(SIG_SETMASK, old_sigset.get(), NULL);
+  sigprocmask64(SIG_SETMASK, &old_sigset, nullptr);
 
   if (rc != 0) {
     free(timer);
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index 8b4c44e..f1b65fd 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -34,6 +34,7 @@
 #include <sys/mman.h>
 
 #include "private/bionic_defs.h"
+#include "private/ScopedSignalBlocker.h"
 #include "pthread_internal.h"
 
 extern "C" __noreturn void _exit_with_stack_teardown(void*, size_t);
@@ -63,6 +64,12 @@
   }
 }
 
+static void __pthread_unmap_tls(pthread_internal_t* thread) {
+  // Unmap the bionic TLS, including guard pages.
+  void* allocation = reinterpret_cast<char*>(thread->bionic_tls) - PTHREAD_GUARD_SIZE;
+  munmap(allocation, BIONIC_TLS_SIZE + 2 * PTHREAD_GUARD_SIZE);
+}
+
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
 void pthread_exit(void* return_value) {
   // Call dtors for thread_local objects first.
@@ -96,10 +103,6 @@
     thread->alternate_signal_stack = NULL;
   }
 
-  // Unmap the bionic TLS, including guard pages.
-  void* allocation = reinterpret_cast<char*>(thread->bionic_tls) - PTHREAD_GUARD_SIZE;
-  munmap(allocation, BIONIC_TLS_SIZE + 2 * PTHREAD_GUARD_SIZE);
-
   ThreadJoinState old_state = THREAD_NOT_JOINED;
   while (old_state == THREAD_NOT_JOINED &&
          !atomic_compare_exchange_weak(&thread->join_state, &old_state, THREAD_EXITED_NOT_JOINED)) {
@@ -120,16 +123,15 @@
       // That's not something we can do in C.
 
       // We don't want to take a signal after we've unmapped the stack.
-      // That's one last thing we can handle in C.
-      sigset_t mask;
-      sigfillset(&mask);
-      sigprocmask(SIG_SETMASK, &mask, NULL);
-
+      // That's one last thing we can do before dropping to assembler.
+      ScopedSignalBlocker ssb;
+      __pthread_unmap_tls(thread);
       _exit_with_stack_teardown(thread->attr.stack_base, thread->mmap_size);
     }
   }
 
   // No need to free mapped space. Either there was no space mapped, or it is left for
   // the pthread_join caller to clean up.
+  __pthread_unmap_tls(thread);
   __exit(0);
 }
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index 14e0ab0..f1f7294 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -31,6 +31,7 @@
 #include <errno.h>
 #include <limits.h>
 #include <stdatomic.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/cdefs.h>
 #include <sys/mman.h>
@@ -49,9 +50,13 @@
  * bits:     name       description
  * 0-3       type       type of mutex
  * 4         shared     process-shared flag
+ * 5         protocol   whether it is a priority inherit mutex.
  */
 #define  MUTEXATTR_TYPE_MASK   0x000f
 #define  MUTEXATTR_SHARED_MASK 0x0010
+#define MUTEXATTR_PROTOCOL_MASK 0x0020
+
+#define MUTEXATTR_PROTOCOL_SHIFT 5
 
 int pthread_mutexattr_init(pthread_mutexattr_t *attr)
 {
@@ -113,17 +118,211 @@
     return 0;
 }
 
-/* a mutex contains a state value and a owner_tid.
- * The value is implemented as a 16-bit integer holding the following fields:
- *
- * bits:     name     description
- * 15-14     type     mutex type
- * 13        shared   process-shared flag
- * 12-2      counter  counter of recursive mutexes
- * 1-0       state    lock state (0, 1 or 2)
- *
- * The owner_tid is used only in recursive and errorcheck mutex to hold the mutex owner thread tid.
- */
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t* attr, int protocol) {
+    if (protocol != PTHREAD_PRIO_NONE && protocol != PTHREAD_PRIO_INHERIT) {
+        return EINVAL;
+    }
+    *attr = (*attr & ~MUTEXATTR_PROTOCOL_MASK) | (protocol << MUTEXATTR_PROTOCOL_SHIFT);
+    return 0;
+}
+
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* attr, int* protocol) {
+    *protocol = (*attr & MUTEXATTR_PROTOCOL_MASK) >> MUTEXATTR_PROTOCOL_SHIFT;
+    return 0;
+}
+
+// Priority Inheritance mutex implementation
+struct PIMutex {
+  // mutex type, can be 0 (normal), 1 (recursive), 2 (errorcheck), constant during lifetime
+  uint8_t type;
+  // process-shared flag, constant during lifetime
+  bool shared;
+  // <number of times a thread holding a recursive PI mutex> - 1
+  uint16_t counter;
+  // owner_tid is read/written by both userspace code and kernel code. It includes three fields:
+  // FUTEX_WAITERS, FUTEX_OWNER_DIED and FUTEX_TID_MASK.
+  atomic_int owner_tid;
+};
+
+static inline __always_inline int PIMutexTryLock(PIMutex& mutex) {
+    pid_t tid = __get_thread()->tid;
+    // Handle common case first.
+    int old_owner = 0;
+    if (__predict_true(atomic_compare_exchange_strong_explicit(&mutex.owner_tid,
+                                                               &old_owner, tid,
+                                                               memory_order_acquire,
+                                                               memory_order_relaxed))) {
+        return 0;
+    }
+    if (tid == (old_owner & FUTEX_TID_MASK)) {
+        // We already own this mutex.
+        if (mutex.type == PTHREAD_MUTEX_NORMAL) {
+            return EBUSY;
+        }
+        if (mutex.type == PTHREAD_MUTEX_ERRORCHECK) {
+            return EDEADLK;
+        }
+        if (mutex.counter == 0xffff) {
+            return EAGAIN;
+        }
+        mutex.counter++;
+        return 0;
+    }
+    return EBUSY;
+}
+
+// Inlining this function in pthread_mutex_lock() add the cost of stack frame instructions on
+// ARM/ARM64, which increases at most 20 percent overhead. So make it noinline.
+static int  __attribute__((noinline)) PIMutexTimedLock(PIMutex& mutex,
+                                                       const timespec* abs_timeout) {
+    int ret = PIMutexTryLock(mutex);
+    if (__predict_true(ret == 0)) {
+        return 0;
+    }
+    if (ret == EBUSY) {
+        ScopedTrace trace("Contending for pthread mutex");
+        ret = -__futex_pi_lock_ex(&mutex.owner_tid, mutex.shared, true, abs_timeout);
+    }
+    return ret;
+}
+
+static int PIMutexUnlock(PIMutex& mutex) {
+    pid_t tid = __get_thread()->tid;
+    int old_owner = tid;
+    // Handle common case first.
+    if (__predict_true(mutex.type == PTHREAD_MUTEX_NORMAL)) {
+        if (__predict_true(atomic_compare_exchange_strong_explicit(&mutex.owner_tid,
+                                                                   &old_owner, 0,
+                                                                   memory_order_release,
+                                                                   memory_order_relaxed))) {
+            return 0;
+        }
+    }
+
+    if (tid != (old_owner & FUTEX_TID_MASK)) {
+        // The mutex can only be unlocked by the thread who owns it.
+        return EPERM;
+    }
+    if (mutex.type == PTHREAD_MUTEX_RECURSIVE) {
+        if (mutex.counter != 0u) {
+            --mutex.counter;
+            return 0;
+        }
+    }
+    if (old_owner == tid) {
+        // No thread is waiting.
+        if (__predict_true(atomic_compare_exchange_strong_explicit(&mutex.owner_tid,
+                                                                   &old_owner, 0,
+                                                                   memory_order_release,
+                                                                   memory_order_relaxed))) {
+            return 0;
+        }
+    }
+    return -__futex_pi_unlock(&mutex.owner_tid, mutex.shared);
+}
+
+static int PIMutexDestroy(PIMutex& mutex) {
+    // The mutex should be in unlocked state (owner_tid == 0) when destroyed.
+    // Store 0xffffffff to make the mutex unusable.
+    int old_owner = 0;
+    if (atomic_compare_exchange_strong_explicit(&mutex.owner_tid, &old_owner, 0xffffffff,
+                                                memory_order_relaxed, memory_order_relaxed)) {
+        return 0;
+    }
+    return EBUSY;
+}
+
+#if !defined(__LP64__)
+
+namespace PIMutexAllocator {
+// pthread_mutex_t has only 4 bytes in 32-bit programs, which are not enough to hold PIMutex.
+// So we use malloc to allocate PIMutexes and use 16-bit of pthread_mutex_t as indexes to find
+// the allocated PIMutexes. This allows at most 65536 PI mutexes.
+// When calling operations like pthread_mutex_lock/unlock, the 16-bit index is mapped to the
+// corresponding PIMutex. To make the map operation fast, we use a lockless mapping method:
+//   Once a PIMutex is allocated, all the data used to map index to the PIMutex isn't changed until
+//   it is destroyed.
+// Below are the data structures:
+//   // struct Node contains a PIMutex.
+//   typedef Node NodeArray[256];
+//   typedef NodeArray* NodeArrayP;
+//   NodeArrayP nodes[256];
+//
+// A 16-bit index is mapped to Node as below:
+//   (*nodes[index >> 8])[index & 0xff]
+//
+// Also use a free list to allow O(1) finding recycled PIMutexes.
+
+union Node {
+    PIMutex mutex;
+    int next_free_id;  // If not -1, refer to the next node in the free PIMutex list.
+};
+typedef Node NodeArray[256];
+typedef NodeArray* NodeArrayP;
+
+// lock_ protects below items.
+static Lock lock;
+static NodeArrayP* nodes;
+static int next_to_alloc_id;
+static int first_free_id = -1;  // If not -1, refer to the first node in the free PIMutex list.
+
+static inline __always_inline Node& IdToNode(int id) {
+    return (*nodes[id >> 8])[id & 0xff];
+}
+
+static inline __always_inline PIMutex& IdToPIMutex(int id) {
+    return IdToNode(id).mutex;
+}
+
+static int AllocIdLocked() {
+    if (first_free_id != -1) {
+        int result = first_free_id;
+        first_free_id = IdToNode(result).next_free_id;
+        return result;
+    }
+    if (next_to_alloc_id >= 0x10000) {
+        return -1;
+    }
+    int array_pos = next_to_alloc_id >> 8;
+    int node_pos = next_to_alloc_id & 0xff;
+    if (node_pos == 0) {
+        if (array_pos == 0) {
+            nodes = static_cast<NodeArray**>(calloc(256, sizeof(NodeArray*)));
+            if (nodes == nullptr) {
+                return -1;
+            }
+        }
+        nodes[array_pos] = static_cast<NodeArray*>(malloc(sizeof(NodeArray)));
+        if (nodes[array_pos] == nullptr) {
+            return -1;
+        }
+    }
+    return next_to_alloc_id++;
+}
+
+// If succeed, return an id referring to a PIMutex, otherwise return -1.
+// A valid id is in range [0, 0xffff].
+static int AllocId() {
+    lock.lock();
+    int result = AllocIdLocked();
+    lock.unlock();
+    if (result != -1) {
+        memset(&IdToPIMutex(result), 0, sizeof(PIMutex));
+    }
+    return result;
+}
+
+static void FreeId(int id) {
+    lock.lock();
+    IdToNode(id).next_free_id = first_free_id;
+    first_free_id = id;
+    lock.unlock();
+}
+
+}  // namespace PIMutexAllocator
+
+#endif  // !defined(__LP64__)
+
 
 /* Convenience macro, creates a mask of 'bits' bits that starts from
  * the 'shift'-th least significant bit in a 32-bit word.
@@ -139,7 +338,6 @@
 /* And this one does the opposite, i.e. extract a field's value from a bit pattern */
 #define  FIELD_FROM_BITS(val,shift,bits)  (((val) >> (shift)) & ((1 << (bits))-1))
 
-
 /* Convenience macros.
  *
  * These are used to form or modify the bit pattern of a given mutex value
@@ -214,18 +412,75 @@
 #define  MUTEX_TYPE_BITS_NORMAL      MUTEX_TYPE_TO_BITS(PTHREAD_MUTEX_NORMAL)
 #define  MUTEX_TYPE_BITS_RECURSIVE   MUTEX_TYPE_TO_BITS(PTHREAD_MUTEX_RECURSIVE)
 #define  MUTEX_TYPE_BITS_ERRORCHECK  MUTEX_TYPE_TO_BITS(PTHREAD_MUTEX_ERRORCHECK)
+// Use a special mutex type to mark priority inheritance mutexes.
+#define  MUTEX_TYPE_BITS_WITH_PI     MUTEX_TYPE_TO_BITS(3)
 
-struct pthread_mutex_internal_t {
-  _Atomic(uint16_t) state;
+// For a PI mutex, it includes below fields:
+//   Atomic(uint16_t) state;
+//   PIMutex pi_mutex;  // uint16_t pi_mutex_id in 32-bit programs
+//
+//   state holds the following fields:
+//
+//   bits:   name    description
+//   15-14   type    mutex type, should be 3
+//
+//   pi_mutex holds the state of a PI mutex.
+//   pi_mutex_id holds an integer to find the state of a PI mutex.
+//
+// For a Non-PI mutex, it includes below fields:
+//   Atomic(uint16_t) state;
+//   atomic_int owner_tid;  // Atomic(uint16_t) in 32-bit programs
+//
+//   state holds the following fields:
+//
+//   bits:     name     description
+//   15-14     type     mutex type, can be 0 (normal), 1 (recursive), 2 (errorcheck)
+//   13        shared   process-shared flag
+//   12-2      counter  <number of times a thread holding a recursive Non-PI mutex> - 1
+//   1-0       state    lock state (0, 1 or 2)
+//
+//   bits 15-13 are constant during the lifetime of the mutex.
+//
+//   owner_tid is used only in recursive and errorcheck Non-PI mutexes to hold the mutex owner
+//   thread id.
+//
+// PI mutexes and Non-PI mutexes are distinguished by checking type field in state.
 #if defined(__LP64__)
-  uint16_t __pad;
-  atomic_int owner_tid;
-  char __reserved[32];
-#else
-  _Atomic(uint16_t) owner_tid;
-#endif
+struct pthread_mutex_internal_t {
+    _Atomic(uint16_t) state;
+    uint16_t __pad;
+    union {
+        atomic_int owner_tid;
+        PIMutex pi_mutex;
+    };
+    char __reserved[28];
+
+    PIMutex& ToPIMutex() {
+        return pi_mutex;
+    }
+
+    void FreePIMutex() {
+    }
 } __attribute__((aligned(4)));
 
+#else
+struct pthread_mutex_internal_t {
+    _Atomic(uint16_t) state;
+    union {
+        _Atomic(uint16_t) owner_tid;
+        uint16_t pi_mutex_id;
+    };
+
+    PIMutex& ToPIMutex() {
+        return PIMutexAllocator::IdToPIMutex(pi_mutex_id);
+    }
+
+    void FreePIMutex() {
+        PIMutexAllocator::FreeId(pi_mutex_id);
+    }
+} __attribute__((aligned(4)));
+#endif
+
 static_assert(sizeof(pthread_mutex_t) == sizeof(pthread_mutex_internal_t),
               "pthread_mutex_t should actually be pthread_mutex_internal_t in implementation.");
 
@@ -267,13 +522,33 @@
         return EINVAL;
     }
 
-    atomic_init(&mutex->state, state);
-    atomic_init(&mutex->owner_tid, 0);
+    if (((*attr & MUTEXATTR_PROTOCOL_MASK) >> MUTEXATTR_PROTOCOL_SHIFT) == PTHREAD_PRIO_INHERIT) {
+#if !defined(__LP64__)
+        if (state & MUTEX_SHARED_MASK) {
+            return EINVAL;
+        }
+        int id = PIMutexAllocator::AllocId();
+        if (id == -1) {
+            return ENOMEM;
+        }
+        mutex->pi_mutex_id = id;
+#endif
+        atomic_init(&mutex->state, MUTEX_TYPE_BITS_WITH_PI);
+        PIMutex& pi_mutex = mutex->ToPIMutex();
+        pi_mutex.type = *attr & MUTEXATTR_TYPE_MASK;
+        pi_mutex.shared = (*attr & MUTEXATTR_SHARED_MASK) != 0;
+    } else {
+        atomic_init(&mutex->state, state);
+        atomic_init(&mutex->owner_tid, 0);
+    }
     return 0;
 }
 
-static inline __always_inline int __pthread_normal_mutex_trylock(pthread_mutex_internal_t* mutex,
-                                                                 uint16_t shared) {
+// namespace for Non-PI mutex routines.
+namespace NonPI {
+
+static inline __always_inline int NormalMutexTryLock(pthread_mutex_internal_t* mutex,
+                                                     uint16_t shared) {
     const uint16_t unlocked           = shared | MUTEX_STATE_BITS_UNLOCKED;
     const uint16_t locked_uncontended = shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
 
@@ -286,7 +561,7 @@
 }
 
 /*
- * Lock a mutex of type NORMAL.
+ * Lock a normal Non-PI mutex.
  *
  * As noted above, there are three states:
  *   0 (unlocked, no contention)
@@ -297,11 +572,11 @@
  * "type" value is zero, so the only bits that will be set are the ones in
  * the lock state field.
  */
-static inline __always_inline int __pthread_normal_mutex_lock(pthread_mutex_internal_t* mutex,
-                                                              uint16_t shared,
-                                                              bool use_realtime_clock,
-                                                              const timespec* abs_timeout_or_null) {
-    if (__predict_true(__pthread_normal_mutex_trylock(mutex, shared) == 0)) {
+static inline __always_inline int NormalMutexLock(pthread_mutex_internal_t* mutex,
+                                                  uint16_t shared,
+                                                  bool use_realtime_clock,
+                                                  const timespec* abs_timeout_or_null) {
+    if (__predict_true(NormalMutexTryLock(mutex, shared) == 0)) {
         return 0;
     }
     int result = check_timespec(abs_timeout_or_null, true);
@@ -333,11 +608,11 @@
 }
 
 /*
- * Release a normal mutex.  The caller is responsible for determining
+ * Release a normal Non-PI mutex.  The caller is responsible for determining
  * that we are in fact the owner of this lock.
  */
-static inline __always_inline void __pthread_normal_mutex_unlock(pthread_mutex_internal_t* mutex,
-                                                                 uint16_t shared) {
+static inline __always_inline void NormalMutexUnlock(pthread_mutex_internal_t* mutex,
+                                                     uint16_t shared) {
     const uint16_t unlocked         = shared | MUTEX_STATE_BITS_UNLOCKED;
     const uint16_t locked_contended = shared | MUTEX_STATE_BITS_LOCKED_CONTENDED;
 
@@ -370,14 +645,14 @@
     }
 }
 
-/* This common inlined function is used to increment the counter of a recursive mutex.
+/* This common inlined function is used to increment the counter of a recursive Non-PI mutex.
  *
  * If the counter overflows, it will return EAGAIN.
  * Otherwise, it atomically increments the counter and returns 0.
  *
  */
-static inline __always_inline int __recursive_increment(pthread_mutex_internal_t* mutex,
-                                                        uint16_t old_state) {
+static inline __always_inline int RecursiveIncrement(pthread_mutex_internal_t* mutex,
+                                                     uint16_t old_state) {
     // Detect recursive lock overflow and return EAGAIN.
     // This is safe because only the owner thread can modify the
     // counter bits in the mutex value.
@@ -387,17 +662,17 @@
 
     // Other threads are able to change the lower bits (e.g. promoting it to "contended"),
     // but the mutex counter will not overflow. So we use atomic_fetch_add operation here.
-    // The mutex is still locked by current thread, so we don't need a release fence.
+    // The mutex is already locked by current thread, so we don't need an acquire fence.
     atomic_fetch_add_explicit(&mutex->state, MUTEX_COUNTER_BITS_ONE, memory_order_relaxed);
     return 0;
 }
 
-static inline __always_inline int __recursive_or_errorcheck_mutex_wait(
-                                                      pthread_mutex_internal_t* mutex,
-                                                      uint16_t shared,
-                                                      uint16_t old_state,
-                                                      bool use_realtime_clock,
-                                                      const timespec* abs_timeout) {
+// Wait on a recursive or errorcheck Non-PI mutex.
+static inline __always_inline int RecursiveOrErrorcheckMutexWait(pthread_mutex_internal_t* mutex,
+                                                                 uint16_t shared,
+                                                                 uint16_t old_state,
+                                                                 bool use_realtime_clock,
+                                                                 const timespec* abs_timeout) {
 // __futex_wait always waits on a 32-bit value. But state is 16-bit. For a normal mutex, the owner_tid
 // field in mutex is not used. On 64-bit devices, the __pad field in mutex is not used.
 // But when a recursive or errorcheck mutex is used on 32-bit devices, we need to add the
@@ -418,16 +693,16 @@
 #endif
 }
 
-static int __pthread_mutex_lock_with_timeout(pthread_mutex_internal_t* mutex,
-                                             bool use_realtime_clock,
-                                             const timespec* abs_timeout_or_null) {
+// Lock a Non-PI mutex.
+static int MutexLockWithTimeout(pthread_mutex_internal_t* mutex, bool use_realtime_clock,
+                                const timespec* abs_timeout_or_null) {
     uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
     uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
     uint16_t shared = (old_state & MUTEX_SHARED_MASK);
 
     // Handle common case first.
     if ( __predict_true(mtype == MUTEX_TYPE_BITS_NORMAL) ) {
-        return __pthread_normal_mutex_lock(mutex, shared, use_realtime_clock, abs_timeout_or_null);
+        return NormalMutexLock(mutex, shared, use_realtime_clock, abs_timeout_or_null);
     }
 
     // Do we already own this recursive or error-check mutex?
@@ -436,7 +711,7 @@
         if (mtype == MUTEX_TYPE_BITS_ERRORCHECK) {
             return EDEADLK;
         }
-        return __recursive_increment(mutex, old_state);
+        return RecursiveIncrement(mutex, old_state);
     }
 
     const uint16_t unlocked           = mtype | shared | MUTEX_STATE_BITS_UNLOCKED;
@@ -492,14 +767,16 @@
             return result;
         }
         // We are in locked_contended state, sleep until someone wakes us up.
-        if (__recursive_or_errorcheck_mutex_wait(mutex, shared, old_state, use_realtime_clock,
-                                                 abs_timeout_or_null) == -ETIMEDOUT) {
+        if (RecursiveOrErrorcheckMutexWait(mutex, shared, old_state, use_realtime_clock,
+                                           abs_timeout_or_null) == -ETIMEDOUT) {
             return ETIMEDOUT;
         }
         old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
     }
 }
 
+}  // namespace NonPI
+
 int pthread_mutex_lock(pthread_mutex_t* mutex_interface) {
 #if !defined(__LP64__)
     // Some apps depend on being able to pass NULL as a mutex and get EINVAL
@@ -514,14 +791,21 @@
 
     uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
     uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
-    uint16_t shared = (old_state & MUTEX_SHARED_MASK);
     // Avoid slowing down fast path of normal mutex lock operation.
     if (__predict_true(mtype == MUTEX_TYPE_BITS_NORMAL)) {
-      if (__predict_true(__pthread_normal_mutex_trylock(mutex, shared) == 0)) {
-        return 0;
-      }
+        uint16_t shared = (old_state & MUTEX_SHARED_MASK);
+        if (__predict_true(NonPI::NormalMutexTryLock(mutex, shared) == 0)) {
+            return 0;
+        }
+    } else if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
+        PIMutex& m = mutex->ToPIMutex();
+        // Handle common case first.
+        if (__predict_true(PIMutexTryLock(m) == 0)) {
+            return 0;
+        }
+        return PIMutexTimedLock(mutex->ToPIMutex(), nullptr);
     }
-    return __pthread_mutex_lock_with_timeout(mutex, false, nullptr);
+    return NonPI::MutexLockWithTimeout(mutex, false, nullptr);
 }
 
 int pthread_mutex_unlock(pthread_mutex_t* mutex_interface) {
@@ -542,9 +826,12 @@
 
     // Handle common case first.
     if (__predict_true(mtype == MUTEX_TYPE_BITS_NORMAL)) {
-        __pthread_normal_mutex_unlock(mutex, shared);
+        NonPI::NormalMutexUnlock(mutex, shared);
         return 0;
     }
+    if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
+        return PIMutexUnlock(mutex->ToPIMutex());
+    }
 
     // Do we already own this recursive or error-check mutex?
     pid_t tid = __get_thread()->tid;
@@ -582,14 +869,14 @@
 
     uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
     uint16_t mtype  = (old_state & MUTEX_TYPE_MASK);
-    uint16_t shared = (old_state & MUTEX_SHARED_MASK);
-
-    const uint16_t unlocked           = mtype | shared | MUTEX_STATE_BITS_UNLOCKED;
-    const uint16_t locked_uncontended = mtype | shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
 
     // Handle common case first.
     if (__predict_true(mtype == MUTEX_TYPE_BITS_NORMAL)) {
-        return __pthread_normal_mutex_trylock(mutex, shared);
+        uint16_t shared = (old_state & MUTEX_SHARED_MASK);
+        return NonPI::NormalMutexTryLock(mutex, shared);
+    }
+    if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
+        return PIMutexTryLock(mutex->ToPIMutex());
     }
 
     // Do we already own this recursive or error-check mutex?
@@ -598,9 +885,13 @@
         if (mtype == MUTEX_TYPE_BITS_ERRORCHECK) {
             return EBUSY;
         }
-        return __recursive_increment(mutex, old_state);
+        return NonPI::RecursiveIncrement(mutex, old_state);
     }
 
+    uint16_t shared = (old_state & MUTEX_SHARED_MASK);
+    const uint16_t unlocked           = mtype | shared | MUTEX_STATE_BITS_UNLOCKED;
+    const uint16_t locked_uncontended = mtype | shared | MUTEX_STATE_BITS_LOCKED_UNCONTENDED;
+
     // Same as pthread_mutex_lock, except that we don't want to wait, and
     // the only operation that can succeed is a single compare_exchange to acquire the
     // lock if it is released / not owned by anyone. No need for a complex loop.
@@ -623,8 +914,8 @@
     timespec_from_ms(ts, ms);
     timespec abs_timeout;
     absolute_timespec_from_timespec(abs_timeout, ts, CLOCK_MONOTONIC);
-    int error = __pthread_mutex_lock_with_timeout(__get_internal_mutex(mutex_interface),
-                                                  false, &abs_timeout);
+    int error = NonPI::MutexLockWithTimeout(__get_internal_mutex(mutex_interface), false,
+                                            &abs_timeout);
     if (error == ETIMEDOUT) {
         error = EBUSY;
     }
@@ -633,13 +924,38 @@
 #endif
 
 int pthread_mutex_timedlock(pthread_mutex_t* mutex_interface, const timespec* abs_timeout) {
-    return __pthread_mutex_lock_with_timeout(__get_internal_mutex(mutex_interface),
-                                             true, abs_timeout);
+    pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
+    uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
+    uint16_t mtype = (old_state & MUTEX_TYPE_MASK);
+    // Handle common case first.
+    if (__predict_true(mtype == MUTEX_TYPE_BITS_NORMAL)) {
+        uint16_t shared = (old_state & MUTEX_SHARED_MASK);
+        if (__predict_true(NonPI::NormalMutexTryLock(mutex, shared) == 0)) {
+            return 0;
+        }
+    }
+    if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
+        return PIMutexTimedLock(mutex->ToPIMutex(), abs_timeout);
+    }
+    return NonPI::MutexLockWithTimeout(mutex, true, abs_timeout);
 }
 
 int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
     pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
     uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
+    if (old_state == 0xffff) {
+        // The mutex has been destroyed.
+        return EBUSY;
+    }
+    uint16_t mtype  = (old_state & MUTEX_TYPE_MASK);
+    if (mtype == MUTEX_TYPE_BITS_WITH_PI) {
+        int result = PIMutexDestroy(mutex->ToPIMutex());
+        if (result == 0) {
+            mutex->FreePIMutex();
+            atomic_store(&mutex->state, 0xffff);
+        }
+        return result;
+    }
     // Store 0xffff to make the mutex unusable. Although POSIX standard says it is undefined
     // behavior to destroy a locked mutex, we prefer not to change mutex->state in that situation.
     if (MUTEX_STATE_BITS_IS_UNLOCKED(old_state) &&
diff --git a/libc/bionic/pthread_sigmask.cpp b/libc/bionic/pthread_sigmask.cpp
deleted file mode 100644
index 79f31a1..0000000
--- a/libc/bionic/pthread_sigmask.cpp
+++ /dev/null
@@ -1,39 +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 <errno.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "private/ErrnoRestorer.h"
-
-int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) {
-  ErrnoRestorer errno_restorer;
-  int result = sigprocmask(how, new_set, old_set);
-  return (result == -1) ? errno : 0;
-}
diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp
index 0633748..e5a7d5f 100644
--- a/libc/bionic/sigaction.cpp
+++ b/libc/bionic/sigaction.cpp
@@ -27,6 +27,7 @@
  */
 
 #include <signal.h>
+#include <string.h>
 
 extern "C" void __restore_rt(void);
 extern "C" void __restore(void);
@@ -75,28 +76,49 @@
   return result;
 }
 
+__strong_alias(sigaction64, sigaction);
+
 #else
 
+extern "C" int __rt_sigaction(int, const struct sigaction64*, struct sigaction64*, size_t);
 extern "C" int __sigaction(int, const struct sigaction*, struct sigaction*);
 
-int sigaction(int signal, const struct sigaction* bionic_new_action, struct sigaction* bionic_old_action) {
+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 use sigaction(2) rather than rt_sigaction(2).
-  struct sigaction kernel_new_action;
-  if (bionic_new_action != NULL) {
-    kernel_new_action.sa_flags = bionic_new_action->sa_flags;
-    kernel_new_action.sa_handler = bionic_new_action->sa_handler;
-    kernel_new_action.sa_mask = bionic_new_action->sa_mask;
-#if defined(SA_RESTORER)
-    kernel_new_action.sa_restorer = bionic_new_action->sa_restorer;
-
-    if (!(kernel_new_action.sa_flags & SA_RESTORER)) {
-      kernel_new_action.sa_flags |= SA_RESTORER;
-      kernel_new_action.sa_restorer = (kernel_new_action.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore;
-    }
-#endif
+  // so we have to translate to struct sigaction64 first.
+  struct sigaction64 kernel_new;
+  if (bionic_new) {
+    kernel_new = {};
+    kernel_new.sa_flags = bionic_new->sa_flags;
+    kernel_new.sa_handler = bionic_new->sa_handler;
+    memcpy(&kernel_new.sa_mask, &bionic_new->sa_mask, sizeof(bionic_new->sa_mask));
   }
-  return __sigaction(signal, (bionic_new_action != NULL) ? &kernel_new_action : NULL, bionic_old_action);
+
+  struct sigaction64 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;
+    bionic_old->sa_handler = kernel_old.sa_handler;
+    memcpy(&bionic_old->sa_mask, &kernel_old.sa_mask, sizeof(bionic_old->sa_mask));
+  }
+  return result;
+}
+
+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 (!(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;
+    }
+  }
+
+  return __rt_sigaction(signal,
+                        bionic_new ? &kernel_new : nullptr,
+                        bionic_old,
+                        sizeof(kernel_new.sa_mask));
 }
 
 #endif
diff --git a/libc/bionic/sigaddset.cpp b/libc/bionic/sigaddset.cpp
deleted file mode 100644
index ca6b982..0000000
--- a/libc/bionic/sigaddset.cpp
+++ /dev/null
@@ -1,41 +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 <errno.h>
-#include <signal.h>
-
-int sigaddset(sigset_t* set, int signum) {
-  int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
-  unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
-  if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
-    errno = EINVAL;
-    return -1;
-  }
-  local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
-  return 0;
-}
diff --git a/libc/bionic/sigblock.c b/libc/bionic/sigblock.c
deleted file mode 100644
index 176bc13..0000000
--- a/libc/bionic/sigblock.c
+++ /dev/null
@@ -1,50 +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 <signal.h>
-
-/* this function is called from the ARM assembly setjmp fragments */
-int
-sigblock(int mask)
-{
-    int  n;
-    union {
-        int       the_mask;
-        sigset_t  the_sigset;
-    } in, out;
-
-    sigemptyset(&in.the_sigset);
-    in.the_mask = mask;
-
-    n = sigprocmask(SIG_BLOCK, &in.the_sigset, &out.the_sigset);
-    if (n)
-        return n;
-
-    return out.the_mask;
-}
-
-
diff --git a/libc/bionic/sigdelset.cpp b/libc/bionic/sigdelset.cpp
deleted file mode 100644
index 48363d3..0000000
--- a/libc/bionic/sigdelset.cpp
+++ /dev/null
@@ -1,41 +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 <errno.h>
-#include <signal.h>
-
-int sigdelset(sigset_t* set, int signum) {
-  int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
-  unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
-  if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
-    errno = EINVAL;
-    return -1;
-  }
-  local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
-  return 0;
-}
diff --git a/libc/bionic/sigemptyset.cpp b/libc/bionic/sigemptyset.cpp
deleted file mode 100644
index 58166a1..0000000
--- a/libc/bionic/sigemptyset.cpp
+++ /dev/null
@@ -1,40 +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 <errno.h>
-#include <signal.h>
-#include <string.h>
-
-int sigemptyset(sigset_t* set) {
-  if (set == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-  memset(set, 0, sizeof(sigset_t));
-  return 0;
-}
diff --git a/libc/bionic/sigfillset.cpp b/libc/bionic/sigfillset.cpp
deleted file mode 100644
index cb67394..0000000
--- a/libc/bionic/sigfillset.cpp
+++ /dev/null
@@ -1,40 +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 <errno.h>
-#include <signal.h>
-#include <string.h>
-
-int sigfillset(sigset_t* set) {
-  if (set == NULL) {
-    errno = EINVAL;
-    return -1;
-  }
-  memset(set, ~0, sizeof(sigset_t));
-  return 0;
-}
diff --git a/libc/bionic/sighold.cpp b/libc/bionic/sighold.cpp
deleted file mode 100644
index e9c8ca1..0000000
--- a/libc/bionic/sighold.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 <signal.h>
-
-int sighold(int sig) {
-  sigset_t set;
-  if (sigemptyset(&set) == -1) return -1;
-  if (sigaddset(&set, sig) == -1) return -1;
-  return sigprocmask(SIG_BLOCK, &set, nullptr);
-}
diff --git a/libc/bionic/sigignore.cpp b/libc/bionic/sigignore.cpp
deleted file mode 100644
index 06f458e..0000000
--- a/libc/bionic/sigignore.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 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 <signal.h>
-#include <string.h>
-
-int sigignore(int sig) {
-  struct sigaction sa;
-  memset(&sa, 0, sizeof(sa));
-  if (sigemptyset(&sa.sa_mask) == -1) return -1;
-  sa.sa_handler = SIG_IGN;
-  return sigaction(sig, &sa, nullptr);
-}
diff --git a/libc/bionic/siginterrupt.c b/libc/bionic/siginterrupt.c
deleted file mode 100644
index 4e91edb..0000000
--- a/libc/bionic/siginterrupt.c
+++ /dev/null
@@ -1,45 +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 <signal.h>
-
-/* this is only useful for legacy programs */
-int siginterrupt(int sig, int flag) 
-{
-    struct sigaction act;
-
-    (void) sigaction(sig, NULL, &act);
-
-    if (flag)
-        act.sa_flags &= ~SA_RESTART;
-    else
-        act.sa_flags |= SA_RESTART;
-
-    return sigaction(sig, &act, NULL);
-}
-
diff --git a/libc/bionic/sigismember.cpp b/libc/bionic/sigismember.cpp
deleted file mode 100644
index 9d1fc3c..0000000
--- a/libc/bionic/sigismember.cpp
+++ /dev/null
@@ -1,40 +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 <errno.h>
-#include <signal.h>
-
-int sigismember(const sigset_t* set, int signum) {
-  int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0.
-  const unsigned long* local_set = reinterpret_cast<const unsigned long*>(set);
-  if (set == NULL || bit < 0 || bit >= static_cast<int>(8*sizeof(sigset_t))) {
-    errno = EINVAL;
-    return -1;
-  }
-  return static_cast<int>((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
-}
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index 13d1882..fbfe0ce 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -26,21 +26,301 @@
  * SUCH DAMAGE.
  */
 
+#include <errno.h>
+#include <pthread.h>
 #include <signal.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/signalfd.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
 
-__LIBC_HIDDEN__ sighandler_t _signal(int signum, sighandler_t handler, int flags) {
-  struct sigaction sa;
-  sigemptyset(&sa.sa_mask);
-  sa.sa_handler = handler;
-  sa.sa_flags = flags;
+#include "private/ErrnoRestorer.h"
+#include "private/SigSetConverter.h"
 
-  if (sigaction(signum, &sa, &sa) == -1) {
+extern "C" int __rt_sigpending(const sigset64_t*, size_t);
+extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
+extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
+extern "C" int __rt_sigsuspend(const sigset64_t*, size_t);
+extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
+
+int pthread_sigmask(int how, const sigset_t* new_set, sigset_t* old_set) {
+  ErrnoRestorer errno_restorer;
+  return (sigprocmask(how, new_set, old_set) == -1) ? errno : 0;
+}
+
+int pthread_sigmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) {
+  ErrnoRestorer errno_restorer;
+  return (sigprocmask64(how, new_set, old_set) == -1) ? errno : 0;
+}
+
+template <typename SigSetT>
+int SigAddSet(SigSetT* set, int sig) {
+  int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0.
+  unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
+  if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) {
+    errno = EINVAL;
+    return -1;
+  }
+  local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT);
+  return 0;
+}
+
+int sigaddset(sigset_t* set, int sig) {
+  return SigAddSet(set, sig);
+}
+
+int sigaddset64(sigset64_t* set, int sig) {
+  return SigAddSet(set, sig);
+}
+
+// This isn't in our header files, but is exposed on all architectures.
+extern "C" int sigblock(int mask) {
+  SigSetConverter in, out;
+  sigemptyset(&in.sigset);
+  in.bsd = mask;
+  if (sigprocmask(SIG_BLOCK, &in.sigset, &out.sigset) == -1) return -1;
+  return out.bsd;
+}
+
+template <typename SigSetT>
+int SigDelSet(SigSetT* set, int sig) {
+  int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0.
+  unsigned long* local_set = reinterpret_cast<unsigned long*>(set);
+  if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) {
+    errno = EINVAL;
+    return -1;
+  }
+  local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT));
+  return 0;
+}
+
+int sigdelset(sigset_t* set, int sig) {
+  return SigDelSet(set, sig);
+}
+
+int sigdelset64(sigset64_t* set, int sig) {
+  return SigDelSet(set, sig);
+}
+
+template <typename SigSetT>
+int SigEmptySet(SigSetT* set) {
+  if (set == nullptr) {
+    errno = EINVAL;
+    return -1;
+  }
+  memset(set, 0, sizeof(*set));
+  return 0;
+}
+
+int sigemptyset(sigset_t* set) {
+  return SigEmptySet(set);
+}
+
+int sigemptyset64(sigset64_t* set) {
+  return SigEmptySet(set);
+}
+
+template <typename SigSetT>
+int SigFillSet(SigSetT* set) {
+  if (set == nullptr) {
+    errno = EINVAL;
+    return -1;
+  }
+  memset(set, 0xff, sizeof(*set));
+  return 0;
+}
+
+int sigfillset(sigset_t* set) {
+  return SigFillSet(set);
+}
+
+int sigfillset64(sigset64_t* set) {
+  return SigFillSet(set);
+}
+
+int sighold(int sig) {
+  sigset64_t set = {};
+  if (sigaddset64(&set, sig) == -1) return -1;
+  return sigprocmask64(SIG_BLOCK, &set, nullptr);
+}
+
+int sigignore(int sig) {
+  struct sigaction64 sa = { .sa_handler = SIG_IGN };
+  return sigaction64(sig, &sa, nullptr);
+}
+
+int siginterrupt(int sig, int flag) {
+  struct sigaction64 act;
+  sigaction64(sig, nullptr, &act);
+  if (flag) {
+    act.sa_flags &= ~SA_RESTART;
+  } else {
+    act.sa_flags |= SA_RESTART;
+  }
+  return sigaction64(sig, &act, nullptr);
+}
+
+template <typename SigSetT>
+int SigIsMember(const SigSetT* set, int sig) {
+  int bit = sig - 1; // Signal numbers start at 1, but bit positions start at 0.
+  const unsigned long* local_set = reinterpret_cast<const unsigned long*>(set);
+  if (set == nullptr || bit < 0 || bit >= static_cast<int>(8*sizeof(*set))) {
+    errno = EINVAL;
+    return -1;
+  }
+  return static_cast<int>((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1);
+}
+
+int sigismember(const sigset_t* set, int sig) {
+  return SigIsMember(set, sig);
+}
+
+int sigismember64(const sigset64_t* set, int sig) {
+  return SigIsMember(set, sig);
+}
+
+__LIBC_HIDDEN__ sighandler_t _signal(int sig, sighandler_t handler, int flags) {
+  struct sigaction64 sa = { .sa_handler = handler, .sa_flags = flags };
+  return (sigaction64(sig, &sa, &sa) == -1) ? SIG_ERR : sa.sa_handler;
+}
+
+sighandler_t signal(int sig, sighandler_t handler) {
+  return _signal(sig, handler, SA_RESTART);
+}
+
+int sigpause(int sig) {
+  sigset64_t set = {};
+  if (sigprocmask64(SIG_SETMASK, nullptr, &set) == -1 || sigdelset64(&set, sig) == -1) return -1;
+  return sigsuspend64(&set);
+}
+
+int sigpending(sigset_t* bionic_set) {
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  if (__rt_sigpending(&set.sigset64, sizeof(set.sigset64)) == -1) return -1;
+  *bionic_set = set.sigset;
+  return 0;
+}
+
+int sigpending64(sigset64_t* set) {
+  return __rt_sigpending(set, sizeof(*set));
+}
+
+int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
+  SigSetConverter new_set;
+  sigset64_t* new_set_ptr = nullptr;
+  if (bionic_new_set != nullptr) {
+    sigemptyset64(&new_set.sigset64);
+    new_set.sigset = *bionic_new_set;
+    new_set_ptr = &new_set.sigset64;
+  }
+
+  SigSetConverter old_set;
+  if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) {
+    return -1;
+  }
+
+  if (bionic_old_set != nullptr) {
+    *bionic_old_set = old_set.sigset;
+  }
+
+  return 0;
+}
+
+int sigprocmask64(int how, const sigset64_t* new_set, sigset64_t* old_set) {
+  return __rt_sigprocmask(how, new_set, old_set, sizeof(*new_set));
+}
+
+int sigqueue(pid_t pid, int sig, const sigval value) {
+  siginfo_t info;
+  memset(&info, 0, sizeof(siginfo_t));
+  info.si_signo = sig;
+  info.si_code = SI_QUEUE;
+  info.si_pid = getpid();
+  info.si_uid = getuid();
+  info.si_value = value;
+  return ___rt_sigqueueinfo(pid, sig, &info);
+}
+
+int sigrelse(int sig) {
+  sigset64_t set = {};
+  if (sigaddset64(&set, sig) == -1) return -1;
+  return sigprocmask64(SIG_UNBLOCK, &set, nullptr);
+}
+
+sighandler_t sigset(int sig, sighandler_t disp) {
+  struct sigaction64 new_sa;
+  if (disp != SIG_HOLD) new_sa = { .sa_handler = disp };
+
+  struct sigaction64 old_sa;
+  if (sigaction64(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) {
     return SIG_ERR;
   }
 
-  return sa.sa_handler;
+  sigset64_t new_mask = {};
+  sigaddset64(&new_mask, sig);
+  sigset64_t old_mask;
+  if (sigprocmask64(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK, &new_mask, &old_mask) == -1) {
+    return SIG_ERR;
+  }
+
+  return sigismember64(&old_mask, sig) ? SIG_HOLD : old_sa.sa_handler;
 }
 
-sighandler_t signal(int signum, sighandler_t handler) {
-  return _signal(signum, handler, SA_RESTART);
+// This isn't in our header files, but is exposed on all architectures.
+extern "C" int sigsetmask(int mask) {
+  SigSetConverter in, out;
+  sigemptyset(&in.sigset);
+  in.bsd = mask;
+  if (sigprocmask(SIG_SETMASK, &in.sigset, &out.sigset) == -1) return -1;
+  return out.bsd;
+}
+
+int sigsuspend(const sigset_t* bionic_set) {
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  return __rt_sigsuspend(&set.sigset64, sizeof(set.sigset64));
+}
+
+int sigsuspend64(const sigset64_t* set) {
+  return __rt_sigsuspend(set, sizeof(*set));
+}
+
+int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) {
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  return __rt_sigtimedwait(&set.sigset64, info, timeout, sizeof(set.sigset64));
+}
+
+int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) {
+  return __rt_sigtimedwait(set, info, timeout, sizeof(*set));
+}
+
+int sigwait(const sigset_t* bionic_set, int* sig) {
+  SigSetConverter set = {};
+  set.sigset = *bionic_set;
+  return sigwait64(&set.sigset64, sig);
+}
+
+int sigwait64(const sigset64_t* set, int* sig) {
+  while (true) {
+    // __rt_sigtimedwait can return EAGAIN or EINTR, we need to loop
+    // around them since sigwait is only allowed to return EINVAL.
+    int result = sigtimedwait64(set, nullptr, nullptr);
+    if (result >= 0) {
+      *sig = result;
+      return 0;
+    }
+    if (errno != EAGAIN && errno != EINTR) return errno;
+  }
+}
+
+int sigwaitinfo(const sigset_t* set, siginfo_t* info) {
+  return sigtimedwait(set, info, nullptr);
+}
+
+int sigwaitinfo64(const sigset64_t* set, siginfo_t* info) {
+  return sigtimedwait64(set, info, nullptr);
 }
diff --git a/libc/bionic/sigpause.cpp b/libc/bionic/sigpause.cpp
deleted file mode 100644
index 8ba42d4..0000000
--- a/libc/bionic/sigpause.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 <signal.h>
-
-int sigpause(int sig) {
-  sigset_t set;
-  if (sigprocmask(SIG_SETMASK, nullptr, &set) == -1) return -1;
-  if (sigdelset(&set, sig) == -1) return -1;
-  return sigsuspend(&set);
-}
diff --git a/libc/bionic/sigpending.cpp b/libc/bionic/sigpending.cpp
deleted file mode 100644
index b6e503c..0000000
--- a/libc/bionic/sigpending.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 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 <signal.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigpending(const kernel_sigset_t*, size_t);
-
-int sigpending(sigset_t* bionic_set) {
-  kernel_sigset_t set;
-  int result = __rt_sigpending(&set, sizeof(set));
-  if (result != -1) {
-    *bionic_set = set.bionic;
-  }
-  return result;
-}
diff --git a/libc/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
deleted file mode 100644
index 61e2c63..0000000
--- a/libc/bionic/sigprocmask.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2013 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 <pthread.h>
-#include <signal.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigprocmask(int, const kernel_sigset_t*, kernel_sigset_t*, size_t);
-
-int sigprocmask(int how, const sigset_t* bionic_new_set, sigset_t* bionic_old_set) {
-  kernel_sigset_t new_set;
-  kernel_sigset_t* new_set_ptr = NULL;
-  if (bionic_new_set != NULL) {
-    new_set.set(bionic_new_set);
-    new_set_ptr = &new_set;
-  }
-
-  kernel_sigset_t old_set;
-  if (__rt_sigprocmask(how, new_set_ptr, &old_set, sizeof(old_set)) == -1) {
-    return -1;
-  }
-
-  if (bionic_old_set != NULL) {
-    *bionic_old_set = old_set.bionic;
-  }
-
-  return 0;
-}
diff --git a/libc/bionic/sigqueue.cpp b/libc/bionic/sigqueue.cpp
deleted file mode 100644
index 8741460..0000000
--- a/libc/bionic/sigqueue.cpp
+++ /dev/null
@@ -1,46 +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.
- */
-
-#include <signal.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-extern "C" int ___rt_sigqueueinfo(pid_t, int, siginfo_t*);
-
-int sigqueue(pid_t pid, int signo, const sigval value) {
-  siginfo_t info;
-  memset(&info, 0, sizeof(siginfo_t));
-  info.si_signo = signo;
-  info.si_code = SI_QUEUE;
-  info.si_pid = getpid();
-  info.si_uid = getuid();
-  info.si_value = value;
-
-  return ___rt_sigqueueinfo(pid, signo, &info);
-}
diff --git a/libc/bionic/sigrelse.cpp b/libc/bionic/sigrelse.cpp
deleted file mode 100644
index ab5554e..0000000
--- a/libc/bionic/sigrelse.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 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 <signal.h>
-
-int sigrelse(int sig) {
-  sigset_t set;
-  if (sigemptyset(&set) == -1) return -1;
-  if (sigaddset(&set, sig) == -1) return -1;
-  return sigprocmask(SIG_UNBLOCK, &set, nullptr);
-}
diff --git a/libc/bionic/sigset.cpp b/libc/bionic/sigset.cpp
deleted file mode 100644
index e3f3e72..0000000
--- a/libc/bionic/sigset.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 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 <signal.h>
-#include <string.h>
-
-sighandler_t sigset(int sig, sighandler_t disp) {
-  struct sigaction new_sa;
-  if (disp != SIG_HOLD) {
-    memset(&new_sa, 0, sizeof(new_sa));
-    new_sa.sa_handler = disp;
-    sigemptyset(&new_sa.sa_mask);
-  }
-
-  struct sigaction old_sa;
-  if (sigaction(sig, disp == SIG_HOLD ? nullptr : &new_sa, &old_sa) == -1) {
-    return SIG_ERR;
-  }
-
-  sigset_t new_proc_mask;
-  sigemptyset(&new_proc_mask);
-  sigaddset(&new_proc_mask, sig);
-
-  sigset_t old_proc_mask;
-  if (sigprocmask(disp == SIG_HOLD ? SIG_BLOCK : SIG_UNBLOCK,
-                  &new_proc_mask, &old_proc_mask) == -1) {
-    return SIG_ERR;
-  }
-
-  return sigismember(&old_proc_mask, sig) ? SIG_HOLD : old_sa.sa_handler;
-}
diff --git a/libc/bionic/sigsetmask.c b/libc/bionic/sigsetmask.c
deleted file mode 100644
index 7842bf1..0000000
--- a/libc/bionic/sigsetmask.c
+++ /dev/null
@@ -1,50 +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 <signal.h>
-
-/* called from setjmp assembly fragment */
-int
-sigsetmask(int mask)
-{
-    int  n;
-
-    union {
-        int       the_mask;
-        sigset_t  the_sigset;
-    } in, out;
-
-    sigemptyset(&in.the_sigset);
-    in.the_mask = mask;
-
-    n = sigprocmask(SIG_SETMASK, &in.the_sigset, &out.the_sigset);
-    if (n)
-        return n;
-
-    return out.the_mask;
-}
-
diff --git a/libc/bionic/sigtimedwait.cpp b/libc/bionic/sigtimedwait.cpp
deleted file mode 100644
index c29f806..0000000
--- a/libc/bionic/sigtimedwait.cpp
+++ /dev/null
@@ -1,38 +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.
- */
-
-#include <signal.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
-
-int sigtimedwait(const sigset_t* set, siginfo_t* info, const timespec* timeout) {
-  kernel_sigset_t sigset(set);
-  return __rt_sigtimedwait(sigset.get(), info, timeout, sizeof(sigset));
-}
diff --git a/libc/bionic/sigwait.cpp b/libc/bionic/sigwait.cpp
deleted file mode 100644
index 2534b89..0000000
--- a/libc/bionic/sigwait.cpp
+++ /dev/null
@@ -1,53 +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 <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <time.h>
-
-#include "private/kernel_sigset_t.h"
-
-extern "C" int __rt_sigtimedwait(const sigset_t*, siginfo_t*, const timespec*, size_t);
-
-int sigwait(const sigset_t* set, int* sig) {
-  kernel_sigset_t sigset(set);
-  while (true) {
-    // __rt_sigtimedwait can return EAGAIN or EINTR, we need to loop
-    // around them since sigwait is only allowed to return EINVAL.
-    int result = __rt_sigtimedwait(sigset.get(), NULL, NULL, sizeof(sigset));
-    if (result >= 0) {
-      *sig = result;
-      return 0;
-    }
-
-    if (errno != EAGAIN && errno != EINTR) {
-      return errno;
-    }
-  }
-}
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index e5075f5..fde102c 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -36,6 +36,7 @@
 #include <unistd.h>
 
 #include "private/ScopedSignalBlocker.h"
+#include "private/SigSetConverter.h"
 
 enum Action {
   kOpen,
@@ -87,8 +88,8 @@
   pid_t pgroup;
   sched_param schedparam;
   int schedpolicy;
-  sigset_t sigmask;
-  sigset_t sigdefault;
+  SigSetConverter sigmask;
+  SigSetConverter sigdefault;
 };
 
 static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) {
@@ -97,17 +98,17 @@
   // POSIX: "Signals set to be caught by the calling process shall be
   // set to the default action in the child process."
   bool use_sigdefault = ((flags & POSIX_SPAWN_SETSIGDEF) != 0);
-  const struct sigaction default_sa = { .sa_handler = SIG_DFL };
+  const struct sigaction64 default_sa = { .sa_handler = SIG_DFL };
   for (int s = 1; s < _NSIG; ++s) {
     bool reset = false;
-    if (use_sigdefault && sigismember(&(*attr)->sigdefault, s)) {
+    if (use_sigdefault && sigismember64(&(*attr)->sigdefault.sigset64, s)) {
       reset = true;
     } else {
-      struct sigaction current;
-      if (sigaction(s, nullptr, &current) == -1) _exit(127);
+      struct sigaction64 current;
+      if (sigaction64(s, nullptr, &current) == -1) _exit(127);
       reset = (current.sa_handler != SIG_IGN && current.sa_handler != SIG_DFL);
     }
-    if (reset && sigaction(s, &default_sa, nullptr) == -1) _exit(127);
+    if (reset && sigaction64(s, &default_sa, nullptr) == -1) _exit(127);
   }
 
   if ((flags & POSIX_SPAWN_SETPGROUP) != 0 && setpgid(0, (*attr)->pgroup) == -1) _exit(127);
@@ -126,7 +127,7 @@
   }
 
   if ((flags & POSIX_SPAWN_SETSIGMASK) != 0) {
-    if (sigprocmask(SIG_SETMASK, &(*attr)->sigmask, nullptr)) _exit(127);
+    if (sigprocmask64(SIG_SETMASK, &(*attr)->sigmask.sigset64, nullptr)) _exit(127);
   }
 }
 
@@ -209,22 +210,42 @@
 }
 
 int posix_spawnattr_setsigmask(posix_spawnattr_t* attr, const sigset_t* mask) {
-  (*attr)->sigmask = *mask;
+  (*attr)->sigmask.sigset = *mask;
+  return 0;
+}
+
+int posix_spawnattr_setsigmask64(posix_spawnattr_t* attr, const sigset64_t* mask) {
+  (*attr)->sigmask.sigset64 = *mask;
   return 0;
 }
 
 int posix_spawnattr_getsigmask(const posix_spawnattr_t* attr, sigset_t* mask) {
-  *mask = (*attr)->sigmask;
+  *mask = (*attr)->sigmask.sigset;
+  return 0;
+}
+
+int posix_spawnattr_getsigmask64(const posix_spawnattr_t* attr, sigset64_t* mask) {
+  *mask = (*attr)->sigmask.sigset64;
   return 0;
 }
 
 int posix_spawnattr_setsigdefault(posix_spawnattr_t* attr, const sigset_t* mask) {
-  (*attr)->sigdefault = *mask;
+  (*attr)->sigdefault.sigset = *mask;
+  return 0;
+}
+
+int posix_spawnattr_setsigdefault64(posix_spawnattr_t* attr, const sigset64_t* mask) {
+  (*attr)->sigdefault.sigset64 = *mask;
   return 0;
 }
 
 int posix_spawnattr_getsigdefault(const posix_spawnattr_t* attr, sigset_t* mask) {
-  *mask = (*attr)->sigdefault;
+  *mask = (*attr)->sigdefault.sigset;
+  return 0;
+}
+
+int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* attr, sigset64_t* mask) {
+  *mask = (*attr)->sigdefault.sigset64;
   return 0;
 }
 
diff --git a/libc/bionic/strtol.cpp b/libc/bionic/strtol.cpp
index f4c8c5f..f6005fa 100644
--- a/libc/bionic/strtol.cpp
+++ b/libc/bionic/strtol.cpp
@@ -66,31 +66,11 @@
   }
   if (base == 0) base = (c == '0') ? 8 : 10;
 
-  // Compute the cutoff value between legal numbers and illegal
-  // numbers.  That is the largest legal value, divided by the
-  // base.  An input number that is greater than this value, if
-  // followed by a legal input character, is too big.  One that
-  // is equal to this value may be valid or not; the limit
-  // between valid and invalid numbers is then based on the last
-  // digit.  For instance, if the range for intmax_t is
-  // [-9223372036854775808..9223372036854775807] and the input base
-  // is 10, cutoff will be set to 922337203685477580 and cutlim to
-  // either 7 (neg==0) or 8 (neg==1), meaning that if we have
-  // accumulated a value > 922337203685477580, or equal but the
-  // next digit is > 7 (or 8), the number is too big, and we will
-  // return a range error.
-  T cutoff = neg ? Min : Max;
-  int cutlim = cutoff % base;
-  cutoff /= base;
-  if (neg) {
-    if (cutlim > 0) {
-      cutlim -= base;
-      cutoff += 1;
-    }
-    cutlim = -cutlim;
-  }
-
-  // Set `any` if any digits consumed; make it negative to indicate overflow.
+  // We always work in the negative space because the most negative value has a
+  // larger magnitude than the most positive value.
+  T cutoff = Min / base;
+  int cutlim = -(Min % base);
+  // Non-zero if any digits consumed; negative to indicate overflow/underflow.
   int any = 0;
   T acc = 0;
   for (; ; c = *s++) {
@@ -103,29 +83,25 @@
     }
     if (c >= base) break;
     if (any < 0) continue;
-    if (neg) {
-      if (acc < cutoff || (acc == cutoff && c > cutlim)) {
-        any = -1;
-        acc = Min;
-        errno = ERANGE;
-      } else {
-        any = 1;
-        acc *= base;
-        acc -= c;
-      }
+    if (acc < cutoff || (acc == cutoff && c > cutlim)) {
+      any = -1;
+      acc = Min;
+      errno = ERANGE;
     } else {
-      if (acc > cutoff || (acc == cutoff && c > cutlim)) {
-        any = -1;
-        acc = Max;
-        errno = ERANGE;
-      } else {
-        any = 1;
-        acc *= base;
-        acc += c;
-      }
+      any = 1;
+      acc *= base;
+      acc -= c;
     }
   }
   if (endptr != nullptr) *endptr = const_cast<char*>(any ? s - 1 : nptr);
+  if (!neg) {
+    if (acc == Min) {
+      errno = ERANGE;
+      acc = Max;
+    } else {
+      acc = -acc;
+    }
+  }
   return acc;
 }
 
@@ -177,7 +153,7 @@
       errno = ERANGE;
     } else {
       any = 1;
-      acc *= static_cast<T>(base);
+      acc *= base;
       acc += c;
     }
   }
diff --git a/libc/bionic/epoll_pwait.cpp b/libc/bionic/sys_epoll.cpp
similarity index 68%
rename from libc/bionic/epoll_pwait.cpp
rename to libc/bionic/sys_epoll.cpp
index f3af93e..9f82912 100644
--- a/libc/bionic/epoll_pwait.cpp
+++ b/libc/bionic/sys_epoll.cpp
@@ -26,18 +26,36 @@
  * SUCH DAMAGE.
  */
 
+#include <errno.h>
 #include <sys/epoll.h>
 
-#include "private/kernel_sigset_t.h"
+#include "private/SigSetConverter.h"
 
-extern "C" int __epoll_pwait(int, epoll_event*, int, int, const kernel_sigset_t*, size_t);
+extern "C" int __epoll_pwait(int, epoll_event*, int, int, const sigset64_t*, size_t);
+
+int epoll_create(int size) {
+  if (size <= 0) {
+    errno = EINVAL;
+    return -1;
+  }
+  return epoll_create1(0);
+}
 
 int epoll_pwait(int fd, epoll_event* events, int max_events, int timeout, const sigset_t* ss) {
-  kernel_sigset_t kernel_ss;
-  kernel_sigset_t* kernel_ss_ptr = NULL;
-  if (ss != NULL) {
-    kernel_ss.set(ss);
-    kernel_ss_ptr = &kernel_ss;
+  SigSetConverter set;
+  sigset64_t* ss_ptr = nullptr;
+  if (ss != nullptr) {
+    set = {};
+    set.sigset = *ss;
+    ss_ptr = &set.sigset64;
   }
-  return __epoll_pwait(fd, events, max_events, timeout, kernel_ss_ptr, sizeof(kernel_ss));
+  return epoll_pwait64(fd, events, max_events, timeout, ss_ptr);
+}
+
+int epoll_pwait64(int fd, epoll_event* events, int max_events, int timeout, const sigset64_t* ss) {
+  return __epoll_pwait(fd, events, max_events, timeout, ss, sizeof(*ss));
+}
+
+int epoll_wait(int fd, struct epoll_event* events, int max_events, int timeout) {
+  return epoll_pwait64(fd, events, max_events, timeout, nullptr);
 }
diff --git a/libc/bionic/signalfd.cpp b/libc/bionic/sys_signalfd.cpp
similarity index 82%
rename from libc/bionic/signalfd.cpp
rename to libc/bionic/sys_signalfd.cpp
index 63e1db4..53d1f25 100644
--- a/libc/bionic/signalfd.cpp
+++ b/libc/bionic/sys_signalfd.cpp
@@ -28,11 +28,16 @@
 
 #include <sys/signalfd.h>
 
-#include "private/kernel_sigset_t.h"
+#include "private/SigSetConverter.h"
 
-extern "C" int __signalfd4(int fd, kernel_sigset_t* mask, size_t sizemask, int flags);
+extern "C" int __signalfd4(int, const sigset64_t*, size_t, int);
 
 int signalfd(int fd, const sigset_t* mask, int flags) {
-  kernel_sigset_t in_set(mask);
-  return __signalfd4(fd, &in_set, sizeof(in_set), flags);
+  SigSetConverter set = {};
+  set.sigset = *mask;
+  return signalfd64(fd, &set.sigset64, flags);
+}
+
+int signalfd64(int fd, const sigset64_t* mask, int flags) {
+  return __signalfd4(fd, mask, sizeof(*mask), flags);
 }
diff --git a/libc/bionic/vdso.cpp b/libc/bionic/vdso.cpp
index 00d6490..c926a58 100644
--- a/libc/bionic/vdso.cpp
+++ b/libc/bionic/vdso.cpp
@@ -60,11 +60,25 @@
   return __gettimeofday(tv, tz);
 }
 
+time_t time(time_t* t) {
+  auto vdso_time = reinterpret_cast<decltype(&time)>(__libc_globals->vdso[VDSO_TIME].fn);
+  if (__predict_true(vdso_time)) {
+    return vdso_time(t);
+  }
+
+  // We can't fallback to the time(2) system call because it doesn't exist for most architectures.
+  timeval tv;
+  if (gettimeofday(&tv, nullptr) == -1) return -1;
+  if (t) *t = tv.tv_sec;
+  return tv.tv_sec;
+}
+
 void __libc_init_vdso(libc_globals* globals, KernelArgumentBlock& args) {
   auto&& vdso = globals->vdso;
   vdso[VDSO_CLOCK_GETTIME] = { VDSO_CLOCK_GETTIME_SYMBOL, nullptr };
   vdso[VDSO_CLOCK_GETRES] = { VDSO_CLOCK_GETRES_SYMBOL, nullptr };
   vdso[VDSO_GETTIMEOFDAY] = { VDSO_GETTIMEOFDAY_SYMBOL, nullptr };
+  vdso[VDSO_TIME] = { VDSO_TIME_SYMBOL, nullptr };
 
   // Do we have a vdso?
   uintptr_t vdso_ehdr_addr = args.getauxval(AT_SYSINFO_EHDR);
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 18825e7..7a909d7 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -58,5 +58,6 @@
 #define __ANDROID_API_N_MR1__ 25
 #define __ANDROID_API_O__ 26
 #define __ANDROID_API_O_MR1__ 27
+#define __ANDROID_API_P__ 28
 
-#endif /* ANDROID_API_LEVEL_H */
+#endif
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index c824544..2b4169e 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -23,88 +23,116 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>  /* for off64_t */
 
+/**
+ * \file
+ * Advanced dynamic library opening support. Most users will want to use
+ * the standard [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html)
+ * functionality in `<dlfcn.h>` instead.
+ */
+
 __BEGIN_DECLS
 
-/* bitfield definitions for android_dlextinfo.flags */
+/** Bitfield definitions for `android_dlextinfo::flags`. */
 enum {
-  /* When set, the reserved_addr and reserved_size fields must point to an
+  /**
+   * When set, the `reserved_addr` and `reserved_size` fields must point to an
    * already-reserved region of address space which will be used to load the
-   * library if it fits. If the reserved region is not large enough, the load
-   * will fail.
+   * library if it fits.
+   *
+   * If the reserved region is not large enough, loading will fail.
    */
   ANDROID_DLEXT_RESERVED_ADDRESS      = 0x1,
 
-  /* As DLEXT_RESERVED_ADDRESS, but if the reserved region is not large enough,
+  /**
+   * Like `ANDROID_DLEXT_RESERVED_ADDRESS`, but if the reserved region is not large enough,
    * the linker will choose an available address instead.
    */
   ANDROID_DLEXT_RESERVED_ADDRESS_HINT = 0x2,
 
-  /* When set, write the GNU RELRO section of the mapped library to relro_fd
+  /**
+   * When set, write the GNU RELRO section of the mapped library to `relro_fd`
    * after relocation has been performed, to allow it to be reused by another
    * process loading the same library at the same address. This implies
-   * ANDROID_DLEXT_USE_RELRO.
+   * `ANDROID_DLEXT_USE_RELRO`.
+   *
+   * This is mainly useful for the system WebView implementation.
    */
   ANDROID_DLEXT_WRITE_RELRO           = 0x4,
 
-  /* When set, compare the GNU RELRO section of the mapped library to relro_fd
+  /**
+   * When set, compare the GNU RELRO section of the mapped library to `relro_fd`
    * after relocation has been performed, and replace any relocated pages that
    * are identical with a version mapped from the file.
+   *
+   * This is mainly useful for the system WebView implementation.
    */
   ANDROID_DLEXT_USE_RELRO             = 0x8,
 
-  /* Instruct dlopen to use library_fd instead of opening file by name.
+  /**
+   * Use `library_fd` instead of opening the file by name.
    * The filename parameter is still used to identify the library.
    */
   ANDROID_DLEXT_USE_LIBRARY_FD        = 0x10,
 
-  /* If opening a library using library_fd read it starting at library_fd_offset.
-   * This flag is only valid when ANDROID_DLEXT_USE_LIBRARY_FD is set.
+  /**
+   * If opening a library using `library_fd` read it starting at `library_fd_offset`.
+   * This is mainly useful for loading a library stored within another file (such as uncompressed
+   * inside a ZIP archive).
+   * This flag is only valid when `ANDROID_DLEXT_USE_LIBRARY_FD` is set.
    */
   ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET    = 0x20,
 
-  /* When set, do not check if the library has already been loaded by file stat(2)s.
+  /**
+   * When set, do not use `stat(2)` to check if the library has already been loaded.
    *
    * This flag allows forced loading of the library in the case when for some
    * reason multiple ELF files share the same filename (because the already-loaded
    * library has been removed and overwritten, for example).
    *
-   * Note that if the library has the same dt_soname as an old one and some other
-   * library has the soname in DT_NEEDED list, the first one will be used to resolve any
+   * Note that if the library has the same `DT_SONAME` as an old one and some other
+   * library has the soname in its `DT_NEEDED` list, the first one will be used to resolve any
    * dependencies.
    */
   ANDROID_DLEXT_FORCE_LOAD = 0x40,
 
-  /* When set, if the minimum p_vaddr of the ELF file's PT_LOAD segments is non-zero,
+  /**
+   * When set, if the minimum `p_vaddr` of the ELF file's `PT_LOAD` segments is non-zero,
    * the dynamic linker will load it at that address.
    *
    * This flag is for ART internal use only.
    */
   ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80,
 
-  /* Instructs dlopen to load the library at the address specified by reserved_addr.
+  /**
+   * Instructs dlopen to load the library at the address specified by reserved_addr.
    *
-   * The difference between ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS and ANDROID_DLEXT_RESERVED_ADDRESS
-   * is that for ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS the linker reserves memory at reserved_addr
-   * whereas for ANDROID_DLEXT_RESERVED_ADDRESS the linker relies on the caller to reserve the memory.
+   * The difference between `ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS` and
+   * `ANDROID_DLEXT_RESERVED_ADDRESS` is that for `ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS` the linker
+   * reserves memory at `reserved_addr` whereas for `ANDROID_DLEXT_RESERVED_ADDRESS` the linker
+   * relies on the caller to reserve the memory.
    *
-   * This flag can be used with ANDROID_DLEXT_FORCE_FIXED_VADDR; when ANDROID_DLEXT_FORCE_FIXED_VADDR
-   * is set and load_bias is not 0 (load_bias is min(p_vaddr) of PT_LOAD segments) this flag is ignored.
-   * This is implemented this way because the linker has to pick one address over the other and this
-   * way is more convenient for art. Note that ANDROID_DLEXT_FORCE_FIXED_VADDR does not generate
-   * an error when min(p_vaddr) is 0.
+   * This flag can be used with `ANDROID_DLEXT_FORCE_FIXED_VADDR`. When
+   * `ANDROID_DLEXT_FORCE_FIXED_VADDR` is set and `load_bias` is not 0 (`load_bias` is the
+   * minimum `p_vaddr` of all `PT_LOAD` segments) this flag is ignored because the linker has to
+   * pick one address over the other and this way is more convenient for ART.
+   * Note that `ANDROID_DLEXT_FORCE_FIXED_VADDR` does not generate an error when the minimum
+   * `p_vaddr` is 0.
    *
-   * Cannot be used with ANDROID_DLEXT_RESERVED_ADDRESS or ANDROID_DLEXT_RESERVED_ADDRESS_HINT.
+   * Cannot be used with `ANDROID_DLEXT_RESERVED_ADDRESS` or `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`.
    *
    * This flag is for ART internal use only.
    */
   ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100,
 
-  /* This flag used to load library in a different namespace. The namespace is
-   * specified in library_namespace.
+  /**
+   * This flag used to load library in a different namespace. The namespace is
+   * specified in `library_namespace`.
+   *
+   * This flag is for internal use only (since there is no NDK API for namespaces).
    */
   ANDROID_DLEXT_USE_NAMESPACE = 0x200,
 
-  /* Mask of valid bits */
+  /** Mask of valid bits. */
   ANDROID_DLEXT_VALID_FLAG_BITS       = ANDROID_DLEXT_RESERVED_ADDRESS |
                                         ANDROID_DLEXT_RESERVED_ADDRESS_HINT |
                                         ANDROID_DLEXT_WRITE_RELRO |
@@ -119,19 +147,36 @@
 
 struct android_namespace_t;
 
+/** Used to pass Android-specific arguments to `android_dlopen_ext`. */
 typedef struct {
+  /** A bitmask of `ANDROID_DLEXT_` enum values. */
   uint64_t flags;
+
+  /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
   void*   reserved_addr;
+  /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
   size_t  reserved_size;
+
+  /** Used by `ANDROID_DLEXT_WRITE_RELRO` and `ANDROID_DLEXT_USE_RELRO`. */
   int     relro_fd;
+
+  /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD`. */
   int     library_fd;
+  /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET` */
   off64_t library_fd_offset;
+
+  /** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */
   struct android_namespace_t* library_namespace;
 } android_dlextinfo;
 
+/**
+ * Opens the given library. The `__filename` and `__flags` arguments are
+ * the same as for [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html),
+ * with the Android-specific flags supplied via the `flags` member of `__info`.
+ */
 void* android_dlopen_ext(const char* __filename, int __flags, const android_dlextinfo* __info)
   __INTRODUCED_IN(21);
 
 __END_DECLS
 
-#endif /* __ANDROID_DLEXT_H__ */
+#endif
diff --git a/libc/include/android/legacy_errno_inlines.h b/libc/include/android/legacy_errno_inlines.h
index 8f08074..9f116fa 100644
--- a/libc/include/android/legacy_errno_inlines.h
+++ b/libc/include/android/legacy_errno_inlines.h
@@ -29,11 +29,12 @@
 #ifndef _ANDROID_LEGACY_ERRNO_INLINES_H
 #define _ANDROID_LEGACY_ERRNO_INLINES_H
 
-#include <errno.h>
 #include <sys/cdefs.h>
 
 #if __ANDROID_API__ < __ANDROID_API_L__
 
+#include <errno.h>
+
 __BEGIN_DECLS
 
 static __inline int __attribute__((deprecated)) __set_errno(int n) {
diff --git a/libc/include/android/legacy_fenv_inlines_arm.h b/libc/include/android/legacy_fenv_inlines_arm.h
index de024cf..6f2c959 100644
--- a/libc/include/android/legacy_fenv_inlines_arm.h
+++ b/libc/include/android/legacy_fenv_inlines_arm.h
@@ -29,10 +29,12 @@
 #ifndef ANDROID_LEGACY_FENV_INLINES_ARM_H
 #define ANDROID_LEGACY_FENV_INLINES_ARM_H
 
-#include <fenv.h>
+#include <sys/cdefs.h>
 
 #if __ANDROID_API__ < __ANDROID_API_L__ && defined(__arm__)
 
+#include <fenv.h>
+
 __BEGIN_DECLS
 
 #define FPSCR_RMODE_SHIFT 22
diff --git a/libc/include/android/legacy_fenv_inlines_mips.h b/libc/include/android/legacy_fenv_inlines_mips.h
index 10b93c0..43ad360 100644
--- a/libc/include/android/legacy_fenv_inlines_mips.h
+++ b/libc/include/android/legacy_fenv_inlines_mips.h
@@ -29,10 +29,12 @@
 #ifndef ANDROID_LEGACY_FENV_INLINES_MIPS_H
 #define ANDROID_LEGACY_FENV_INLINES_MIPS_H
 
-#include <fenv.h>
+#include <sys/cdefs.h>
 
 #if __ANDROID_API__ < __ANDROID_API_L__ && (defined(__mips__) && !defined(__LP64__))
 
+#include <fenv.h>
+
 __BEGIN_DECLS
 
 #define FCSR_CAUSE_SHIFT 10
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 4d474b0..44c2f4f 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -29,16 +29,16 @@
 #ifndef _ANDROID_LEGACY_SIGNAL_INLINES_H_
 #define _ANDROID_LEGACY_SIGNAL_INLINES_H_
 
+#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
-#include <sys/cdefs.h>
-
 
 __BEGIN_DECLS
 
-#if __ANDROID_API__ < __ANDROID_API_L__
-
 sighandler_t bsd_signal(int __signal, sighandler_t __handler) __REMOVED_IN(21);
 
 /* These weren't introduced until L. */
@@ -117,8 +117,8 @@
   return bsd_signal(s, f);
 }
 
-#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
-
 __END_DECLS
 
+#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
+
 #endif /* _ANDROID_LEGACY_SIGNAL_INLINES_H_ */
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index e26e5f2..4896d2e 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -29,12 +29,29 @@
 #ifndef _ANDROID_LEGACY_STDLIB_INLINES_H_
 #define _ANDROID_LEGACY_STDLIB_INLINES_H_
 
+#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_K__
+
+__BEGIN_DECLS
+
+static __inline int abs(int __n) { return (__n < 0) ? -__n : __n; }
+
+static __inline long labs(long __n) { return (__n < 0L) ? -__n : __n; }
+
+static __inline long long llabs(long long __n) {
+  return (__n < 0LL) ? -__n : __n;
+}
+
+__END_DECLS
+
+#endif
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
 #include <errno.h>
 #include <float.h>
 #include <stdlib.h>
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_L__
 
 __BEGIN_DECLS
 
@@ -52,14 +69,6 @@
 
 static __inline double atof(const char *nptr) { return (strtod(nptr, NULL)); }
 
-static __inline int abs(int __n) { return (__n < 0) ? -__n : __n; }
-
-static __inline long labs(long __n) { return (__n < 0L) ? -__n : __n; }
-
-static __inline long long llabs(long long __n) {
-  return (__n < 0LL) ? -__n : __n;
-}
-
 static __inline int rand(void) { return (int)lrand48(); }
 
 static __inline void srand(unsigned int __s) { srand48(__s); }
diff --git a/libc/include/android/legacy_strings_inlines.h b/libc/include/android/legacy_strings_inlines.h
index 6679c30..5d63c5a 100644
--- a/libc/include/android/legacy_strings_inlines.h
+++ b/libc/include/android/legacy_strings_inlines.h
@@ -29,16 +29,19 @@
 #ifndef _ANDROID_LEGACY_STRINGS_INLINES_H_
 #define _ANDROID_LEGACY_STRINGS_INLINES_H_
 
-#include <strings.h>
 #include <sys/cdefs.h>
 
+#if defined(__i386__) && __ANDROID_API__ < __ANDROID_API_J_MR2__
+
+#include <strings.h>
+
 __BEGIN_DECLS
 
-#if defined(__i386__) && __ANDROID_API__ < __ANDROID_API_J_MR2__
 /* Everyone except x86 had ffs since the beginning. */
 static __inline int ffs(int __n) { return __builtin_ffs(__n); }
-#endif
 
 __END_DECLS
 
 #endif
+
+#endif
diff --git a/libc/include/android/legacy_sys_mman_inlines.h b/libc/include/android/legacy_sys_mman_inlines.h
index 7eb537e..160e6fe 100644
--- a/libc/include/android/legacy_sys_mman_inlines.h
+++ b/libc/include/android/legacy_sys_mman_inlines.h
@@ -29,12 +29,13 @@
 #pragma once
 
 #include <sys/cdefs.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include <unistd.h>
 
 #if __ANDROID_API__ < __ANDROID_API_L__
 
+#include <errno.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
 __BEGIN_DECLS
 
 /*
diff --git a/libc/include/android/legacy_sys_stat_inlines.h b/libc/include/android/legacy_sys_stat_inlines.h
index bbf54c0..9521694 100644
--- a/libc/include/android/legacy_sys_stat_inlines.h
+++ b/libc/include/android/legacy_sys_stat_inlines.h
@@ -30,10 +30,11 @@
 #define _ANDROID_LEGACY_SYS_STAT_INLINES_H_
 
 #include <sys/cdefs.h>
-#include <sys/stat.h>
 
 #if __ANDROID_API__ < __ANDROID_API_L__
 
+#include <sys/stat.h>
+
 __BEGIN_DECLS
 
 static __inline int mkfifo(const char* __path, mode_t __mode) {
diff --git a/libc/include/android/legacy_sys_wait_inlines.h b/libc/include/android/legacy_sys_wait_inlines.h
index 1124f8e..4298d76 100644
--- a/libc/include/android/legacy_sys_wait_inlines.h
+++ b/libc/include/android/legacy_sys_wait_inlines.h
@@ -30,12 +30,13 @@
 #define _ANDROID_LEGACY_SYS_WAIT_INLINES_H_
 
 #include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_J_MR2__
+
 #include <sys/syscall.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
-#if __ANDROID_API__ < __ANDROID_API_J_MR2__
-
 __BEGIN_DECLS
 
 static __inline pid_t wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
diff --git a/libc/include/android/legacy_termios_inlines.h b/libc/include/android/legacy_termios_inlines.h
index 4ed56f0..a63dba1 100644
--- a/libc/include/android/legacy_termios_inlines.h
+++ b/libc/include/android/legacy_termios_inlines.h
@@ -30,14 +30,16 @@
 #define _ANDROID_LEGACY_TERMIOS_INLINES_H_
 
 #include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
+#include <linux/termios.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 
-#include <linux/termios.h>
-
-#if __ANDROID_API__ < __ANDROID_API_L__
 #define __BIONIC_TERMIOS_INLINE static __inline
 #include <bits/termios_inlines.h>
+
 #endif
 
 #endif /* _ANDROID_LEGACY_TERMIOS_INLINES_H_ */
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
index 6d90341..75cd4f2 100644
--- a/libc/include/bits/fortify/fcntl.h
+++ b/libc/include/bits/fortify/fcntl.h
@@ -98,7 +98,7 @@
 __errordecl(__creat_too_many_args, __open_too_many_args_error);
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
+__BIONIC_FORTIFY_VARIADIC
 int open(const char* pathname, int flags, ...) {
     if (__builtin_constant_p(flags)) {
         if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
@@ -117,7 +117,7 @@
     return __open_real(pathname, flags, __builtin_va_arg_pack());
 }
 
-__BIONIC_FORTIFY_INLINE
+__BIONIC_FORTIFY_VARIADIC
 int openat(int dirfd, const char* pathname, int flags, ...) {
     if (__builtin_constant_p(flags)) {
         if (__open_modes_useful(flags) && __builtin_va_arg_pack_len() == 0) {
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index cfc78d7..6a6b433 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -63,8 +63,7 @@
                 "format string will always overflow destination buffer")
     __errorattr("format string will always overflow destination buffer");
 
-__BIONIC_FORTIFY_INLINE
-__printflike(3, 4)
+__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
 int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
         __overloadable {
     va_list va;
@@ -82,8 +81,7 @@
                 "format string will always overflow destination buffer")
     __errorattr("format string will always overflow destination buffer");
 
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 3)
+__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
 int sprintf(char* const __pass_object_size dest, const char* format, ...) __overloadable {
     va_list va;
     va_start(va, format);
@@ -159,12 +157,12 @@
 
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 4)
+__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
 int snprintf(char* dest, size_t size, const char* format, ...) {
     return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack());
 }
 
-__BIONIC_FORTIFY_INLINE __printflike(2, 3)
+__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
 int sprintf(char* dest, const char* format, ...) {
     return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack());
 }
diff --git a/libc/include/dirent.h b/libc/include/dirent.h
index 7ac4ab7..d6819f2 100644
--- a/libc/include/dirent.h
+++ b/libc/include/dirent.h
@@ -80,8 +80,8 @@
 DIR* fdopendir(int __dir_fd);
 struct dirent* readdir(DIR* __dir);
 struct dirent64* readdir64(DIR* __dir) __INTRODUCED_IN(21);
-int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer);
-int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21);
+int readdir_r(DIR* __dir, struct dirent* __entry, struct dirent** __buffer) __attribute__((__deprecated__("readdir_r is deprecated; use readdir instead")));
+int readdir64_r(DIR* __dir, struct dirent64* __entry, struct dirent64** __buffer) __INTRODUCED_IN(21) __attribute__((__deprecated__("readdir64_r is deprecated; use readdir64 instead")));
 int closedir(DIR* __dir);
 void rewinddir(DIR* __dir);
 void seekdir(DIR* __dir, long __location) __INTRODUCED_IN(23);
diff --git a/libc/include/elf.h b/libc/include/elf.h
index 37450b2..a8d62db 100644
--- a/libc/include/elf.h
+++ b/libc/include/elf.h
@@ -194,6 +194,10 @@
   Elf64_Word vna_next;
 } Elf64_Vernaux;
 
+/* Relocation table entry for relative (in section of type SHT_RELR). */
+typedef Elf32_Word Elf32_Relr;
+typedef Elf64_Xword Elf64_Relr;
+
 /* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html */
 #define DF_ORIGIN     0x00000001
 #define DF_SYMBOLIC   0x00000002
@@ -242,6 +246,13 @@
 #define DT_PREINIT_ARRAY 32
 #define DT_PREINIT_ARRAYSZ 33
 
+/* Experimental support for SHT_RELR sections. For details, see proposal
+   at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg */
+#define DT_RELR 0x6fffe000
+#define DT_RELRSZ 0x6fffe001
+#define DT_RELRENT 0x6fffe003
+#define DT_RELRCOUNT 0x6fffe005
+
 /* Android compressed rel/rela sections */
 #define DT_ANDROID_REL (DT_LOOS + 2)
 #define DT_ANDROID_RELSZ (DT_LOOS + 3)
@@ -494,6 +505,10 @@
 #define SHT_LOOS 0x60000000
 #define SHT_HIOS 0x6fffffff
 
+/* Experimental support for SHT_RELR sections. For details, see proposal
+   at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg */
+#define SHT_RELR 0x6fffff00
+
 /* http://www.sco.com/developers/gabi/latest/ch4.symtab.html */
 #define STN_UNDEF 0
 
diff --git a/libc/include/glob.h b/libc/include/glob.h
index 6ae8573..0ba2848 100644
--- a/libc/include/glob.h
+++ b/libc/include/glob.h
@@ -90,8 +90,8 @@
 
 __BEGIN_DECLS
 
-int glob(const char* __pattern, int __flags, int (*__error_callback)(const char* __failure_path, int __failure_errno), glob_t* __result_ptr) __INTRODUCED_IN_FUTURE;
-void globfree(glob_t* __result_ptr) __INTRODUCED_IN_FUTURE;
+int glob(const char* __pattern, int __flags, int (*__error_callback)(const char* __failure_path, int __failure_errno), glob_t* __result_ptr) __INTRODUCED_IN(28);
+void globfree(glob_t* __result_ptr) __INTRODUCED_IN(28);
 
 __END_DECLS
 
diff --git a/libc/include/iconv.h b/libc/include/iconv.h
index 4b05bae..df8fa6d 100644
--- a/libc/include/iconv.h
+++ b/libc/include/iconv.h
@@ -37,9 +37,9 @@
 struct __iconv_t;
 typedef struct __iconv_t* iconv_t;
 
-iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding) __INTRODUCED_IN_FUTURE;
-size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, char** __dst_buf, size_t* __dst_bytes_left) __INTRODUCED_IN_FUTURE;
-int iconv_close(iconv_t __converter) __INTRODUCED_IN_FUTURE;
+iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding) __INTRODUCED_IN(28);
+size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, char** __dst_buf, size_t* __dst_bytes_left) __INTRODUCED_IN(28);
+int iconv_close(iconv_t __converter) __INTRODUCED_IN(28);
 
 __END_DECLS
 
diff --git a/libc/include/netdb.h b/libc/include/netdb.h
index 4ee0ce2..7a1987e 100644
--- a/libc/include/netdb.h
+++ b/libc/include/netdb.h
@@ -214,23 +214,23 @@
 int gethostbyname_r(const char* __name, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr);
 struct hostent* gethostbyname2(const char* __name, int __af);
 int gethostbyname2_r(const char* __name, int __af, struct hostent* __ret, char* __buf, size_t __buf_size, struct hostent** __result, int* __h_errno_ptr) __INTRODUCED_IN(23);
-void endhostent(void) __INTRODUCED_IN_FUTURE;
+void endhostent(void) __INTRODUCED_IN(28);
 struct hostent* gethostent(void);
-void sethostent(int __stay_open) __INTRODUCED_IN_FUTURE;
+void sethostent(int __stay_open) __INTRODUCED_IN(28);
 
 /* These functions are obsolete. None of these functions return anything but nullptr. */
-void endnetent(void) __INTRODUCED_IN_FUTURE;
+void endnetent(void) __INTRODUCED_IN(28);
 struct netent* getnetbyaddr(uint32_t __net, int __type);
 struct netent* getnetbyname(const char* __name);
-struct netent* getnetent(void) __INTRODUCED_IN_FUTURE;
-void setnetent(int __stay_open) __INTRODUCED_IN_FUTURE;
+struct netent* getnetent(void) __INTRODUCED_IN(28);
+void setnetent(int __stay_open) __INTRODUCED_IN(28);
 
 /* None of these functions return anything but nullptr. */
-void endprotoent(void) __INTRODUCED_IN_FUTURE;
+void endprotoent(void) __INTRODUCED_IN(28);
 struct protoent* getprotobyname(const char* __name);
 struct protoent* getprotobynumber(int __proto);
-struct protoent* getprotoent(void) __INTRODUCED_IN_FUTURE;
-void setprotoent(int __stay_open) __INTRODUCED_IN_FUTURE;
+struct protoent* getprotoent(void) __INTRODUCED_IN(28);
+void setprotoent(int __stay_open) __INTRODUCED_IN(28);
 
 /* These functions return entries from a built-in database. */
 void endservent(void);
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 8517dc6..9ca1cf8 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -40,6 +40,7 @@
 
 int poll(struct pollfd* __fds, nfds_t __count, int __timeout_ms) __overloadable __RENAME_CLANG(poll);
 int ppoll(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset_t* __mask) __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
+int ppoll64(struct pollfd* __fds, nfds_t __count, const struct timespec* __timeout, const sigset64_t* __mask) __INTRODUCED_IN(28);
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #include <bits/fortify/poll.h>
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 99515da..8d95a3b 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -80,6 +80,9 @@
 #define PTHREAD_EXPLICIT_SCHED 0
 #define PTHREAD_INHERIT_SCHED 1
 
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+
 #define PTHREAD_PROCESS_PRIVATE 0
 #define PTHREAD_PROCESS_SHARED 1
 
@@ -145,9 +148,11 @@
 int pthread_mutexattr_destroy(pthread_mutexattr_t* __attr);
 int pthread_mutexattr_getpshared(const pthread_mutexattr_t* __attr, int* __shared);
 int pthread_mutexattr_gettype(const pthread_mutexattr_t* __attr, int* __type);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* __attr, int* __protocol) __INTRODUCED_IN(28);
 int pthread_mutexattr_init(pthread_mutexattr_t* __attr);
 int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared);
 int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t* __attr, int __protocol) __INTRODUCED_IN(28);
 
 int pthread_mutex_destroy(pthread_mutex_t* __mutex);
 int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr);
@@ -225,7 +230,7 @@
 int pthread_setname_np(pthread_t __pthread, const char* __name);
 
 int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* __param);
-int pthread_setschedprio(pthread_t __pthread, int __priority) __INTRODUCED_IN_FUTURE;
+int pthread_setschedprio(pthread_t __pthread, int __priority) __INTRODUCED_IN(28);
 
 int pthread_setspecific(pthread_key_t __key, const void* __value);
 
diff --git a/libc/include/search.h b/libc/include/search.h
index 5930bcd..97fdeda 100644
--- a/libc/include/search.h
+++ b/libc/include/search.h
@@ -40,14 +40,14 @@
 void insque(void* __element, void* __previous) __INTRODUCED_IN(21);
 void remque(void* __element) __INTRODUCED_IN(21);
 
-int hcreate(size_t) __INTRODUCED_IN_FUTURE;
-void hdestroy(void) __INTRODUCED_IN_FUTURE;
-ENTRY* hsearch(ENTRY, ACTION) __INTRODUCED_IN_FUTURE;
+int hcreate(size_t) __INTRODUCED_IN(28);
+void hdestroy(void) __INTRODUCED_IN(28);
+ENTRY* hsearch(ENTRY, ACTION) __INTRODUCED_IN(28);
 
 #if defined(__USE_BSD) || defined(__USE_GNU)
-int hcreate_r(size_t, struct hsearch_data*) __INTRODUCED_IN_FUTURE;
-void hdestroy_r(struct hsearch_data*) __INTRODUCED_IN_FUTURE;
-int hsearch_r(ENTRY, ACTION, ENTRY**, struct hsearch_data*) __INTRODUCED_IN_FUTURE;
+int hcreate_r(size_t, struct hsearch_data*) __INTRODUCED_IN(28);
+void hdestroy_r(struct hsearch_data*) __INTRODUCED_IN(28);
+int hsearch_r(ENTRY, ACTION, ENTRY**, struct hsearch_data*) __INTRODUCED_IN(28);
 #endif
 
 void* lfind(const void* __key, const void* __base, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*))
diff --git a/libc/include/signal.h b/libc/include/signal.h
index d9c9ee2..2027d70 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -40,7 +40,8 @@
 /* For 64-bit (and mips), the kernel's struct sigaction doesn't match the
  * POSIX one, so we need to expose our own and translate behind the scenes.
  * For 32-bit, we're stuck with the definitions we already shipped,
- * even though they contain a sigset_t that's too small. */
+ * even though they contain a sigset_t that's too small. See sigaction64.
+ */
 #define sigaction __kernel_sigaction
 #include <linux/signal.h>
 #undef sigaction
@@ -80,62 +81,101 @@
 
 #define si_timerid si_tid /* glibc compatibility. */
 
+/* sigset_t is already large enough on LP64, but LP32's sigset_t is just `unsigned long`. */
+#if defined(__LP64__)
+typedef sigset_t sigset64_t;
+#else
+typedef struct { unsigned long __bits[_KERNEL__NSIG/LONG_BIT]; } sigset64_t;
+#endif
+
 #if defined(__LP64__)
 
+#define __SIGACTION_BODY \
+  int sa_flags; \
+  union { \
+    sighandler_t sa_handler; \
+    void (*sa_sigaction)(int, struct siginfo*, void*); \
+  }; \
+  sigset_t sa_mask; \
+  void (*sa_restorer)(void); \
+
+struct sigaction { __SIGACTION_BODY };
+struct sigaction64 { __SIGACTION_BODY };
+
+#undef __SIGACTION_BODY
+
+#elif defined(__mips__)
+
+#define __SIGACTION_BODY \
+  int sa_flags; \
+  union { \
+    sighandler_t sa_handler; \
+    void (*sa_sigaction)(int, struct siginfo*, void*); \
+  }; \
+  sigset_t sa_mask; \
+
+struct sigaction { __SIGACTION_BODY };
+struct sigaction64 { __SIGACTION_BODY };
+
+#undef __SIGACTION_BODY
+
+#else
+
+#undef sa_handler
+#undef sa_sigaction
+
 struct sigaction {
-  int sa_flags;
   union {
     sighandler_t sa_handler;
     void (*sa_sigaction)(int, struct siginfo*, void*);
   };
   sigset_t sa_mask;
+  int sa_flags;
   void (*sa_restorer)(void);
 };
 
-#elif defined(__mips__)
-
-struct sigaction {
-  int sa_flags;
+/* This matches the kernel's internal structure. */
+struct sigaction64 {
   union {
     sighandler_t sa_handler;
-    void (*sa_sigaction) (int, struct siginfo*, void*);
+    void (*sa_sigaction)(int, struct siginfo*, void*);
   };
-  sigset_t sa_mask;
-};
-
-#else
-
-struct sigaction {
-  union {
-    sighandler_t _sa_handler;
-    void (*_sa_sigaction)(int, struct siginfo*, void*);
-  } _u;
-  sigset_t sa_mask;
   int sa_flags;
   void (*sa_restorer)(void);
+  sigset64_t sa_mask;
 };
 
 #endif
 
 int sigaction(int __signal, const struct sigaction* __new_action, struct sigaction* __old_action);
+int sigaction64(int __signal, const struct sigaction64* __new_action, struct sigaction64* __old_action) __INTRODUCED_IN(28);
 
 int siginterrupt(int __signal, int __flag);
 
 #if __ANDROID_API__ >= __ANDROID_API_L__
 sighandler_t signal(int __signal, sighandler_t __handler) __INTRODUCED_IN(21);
 int sigaddset(sigset_t* __set, int __signal) __INTRODUCED_IN(21);
+int sigaddset64(sigset64_t* __set, int __signal) __INTRODUCED_IN(28);
 int sigdelset(sigset_t* __set, int __signal) __INTRODUCED_IN(21);
+int sigdelset64(sigset64_t* __set, int __signal) __INTRODUCED_IN(28);
 int sigemptyset(sigset_t* __set) __INTRODUCED_IN(21);
+int sigemptyset64(sigset64_t* __set) __INTRODUCED_IN(28);
 int sigfillset(sigset_t* __set) __INTRODUCED_IN(21);
+int sigfillset64(sigset64_t* __set) __INTRODUCED_IN(28);
 int sigismember(const sigset_t* __set, int __signal) __INTRODUCED_IN(21);
+int sigismember64(const sigset64_t* __set, int __signal) __INTRODUCED_IN(28);
 #else
 // Implemented as static inlines before 21.
 #endif
 
 int sigpending(sigset_t* __set);
+int sigpending64(sigset64_t* __set) __INTRODUCED_IN(28);
 int sigprocmask(int __how, const sigset_t* __new_set, sigset_t* __old_set);
+int sigprocmask64(int __how, const sigset64_t* __new_set, sigset64_t* __old_set) __INTRODUCED_IN(28);
 int sigsuspend(const sigset_t* __mask);
+int sigsuspend64(const sigset64_t* __mask) __INTRODUCED_IN(28);
 int sigwait(const sigset_t* __set, int* __signal);
+int sigwait64(const sigset64_t* __set, int* __signal) __INTRODUCED_IN(28);
 
 int sighold(int __signal)
   __attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead")))
@@ -162,13 +202,16 @@
 
 int pthread_kill(pthread_t __pthread, int __signal);
 int pthread_sigmask(int __how, const sigset_t* __new_set, sigset_t* __old_set);
+int pthread_sigmask64(int __how, const sigset64_t* __new_set, sigset64_t* __old_set) __INTRODUCED_IN(28);
 
 int sigqueue(pid_t __pid, int __signal, const union sigval __value) __INTRODUCED_IN(23);
 int sigtimedwait(const sigset_t* __set, siginfo_t* __info, const struct timespec* __timeout) __INTRODUCED_IN(23);
+int sigtimedwait64(const sigset64_t* __set, siginfo_t* __info, const struct timespec* __timeout) __INTRODUCED_IN(28);
 int sigwaitinfo(const sigset_t* __set, siginfo_t* __info) __INTRODUCED_IN(23);
+int sigwaitinfo64(const sigset64_t* __set, siginfo_t* __info) __INTRODUCED_IN(28);
 
 __END_DECLS
 
 #include <android/legacy_signal_inlines.h>
 
-#endif /* _SIGNAL_H_ */
+#endif
diff --git a/libc/include/spawn.h b/libc/include/spawn.h
index ea4bb19..2e239bf 100644
--- a/libc/include/spawn.h
+++ b/libc/include/spawn.h
@@ -50,36 +50,40 @@
 typedef struct __posix_spawnattr* posix_spawnattr_t;
 typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t;
 
-int posix_spawn(pid_t* __pid, const char* __path, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN_FUTURE;
-int posix_spawnp(pid_t* __pid, const char* __file, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN_FUTURE;
+int posix_spawn(pid_t* __pid, const char* __path, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN(28);
+int posix_spawnp(pid_t* __pid, const char* __file, const posix_spawn_file_actions_t* __actions, const posix_spawnattr_t* __attr, char* const __argv[], char* const __env[]) __INTRODUCED_IN(28);
 
-int posix_spawnattr_init(posix_spawnattr_t* __attr) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_destroy(posix_spawnattr_t* __attr) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_init(posix_spawnattr_t* __attr) __INTRODUCED_IN(28);
+int posix_spawnattr_destroy(posix_spawnattr_t* __attr) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setflags(posix_spawnattr_t* __attr, short __flags) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_getflags(const posix_spawnattr_t* __attr, short* __flags) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_setflags(posix_spawnattr_t* __attr, short __flags) __INTRODUCED_IN(28);
+int posix_spawnattr_getflags(const posix_spawnattr_t* __attr, short* __flags) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setpgroup(posix_spawnattr_t* __attr, pid_t __pgroup) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_getpgroup(const posix_spawnattr_t* __attr, pid_t* __pgroup) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_setpgroup(posix_spawnattr_t* __attr, pid_t __pgroup) __INTRODUCED_IN(28);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t* __attr, pid_t* __pgroup) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setsigmask(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_getsigmask(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_setsigmask(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigmask64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigmask64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setsigdefault(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_setsigdefault(posix_spawnattr_t* __attr, const sigset_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_setsigdefault64(posix_spawnattr_t* __attr, const sigset64_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t* __attr, sigset_t* __mask) __INTRODUCED_IN(28);
+int posix_spawnattr_getsigdefault64(const posix_spawnattr_t* __attr, sigset64_t* __mask) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setschedparam(posix_spawnattr_t* __attr, const struct sched_param* __param) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_getschedparam(const posix_spawnattr_t* __attr, struct sched_param* __param) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_setschedparam(posix_spawnattr_t* __attr, const struct sched_param* __param) __INTRODUCED_IN(28);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t* __attr, struct sched_param* __param) __INTRODUCED_IN(28);
 
-int posix_spawnattr_setschedpolicy(posix_spawnattr_t* __attr, int __policy) __INTRODUCED_IN_FUTURE;
-int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* __attr, int* __policy) __INTRODUCED_IN_FUTURE;
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t* __attr, int __policy) __INTRODUCED_IN(28);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t* __attr, int* __policy) __INTRODUCED_IN(28);
 
-int posix_spawn_file_actions_init(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN_FUTURE;
-int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN_FUTURE;
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* __actions) __INTRODUCED_IN(28);
 
-int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* __actions, int __fd, const char* __path, int __flags, mode_t __mode) __INTRODUCED_IN_FUTURE;
-int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* __actions, int __fd) __INTRODUCED_IN_FUTURE;
-int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* __actions, int __fd, int __new_fd) __INTRODUCED_IN_FUTURE;
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* __actions, int __fd, const char* __path, int __flags, mode_t __mode) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* __actions, int __fd) __INTRODUCED_IN(28);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* __actions, int __fd, int __new_fd) __INTRODUCED_IN(28);
 
 __END_DECLS
 
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index e02a371..2d9cc31 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -260,16 +260,16 @@
 #endif
 
 #if defined(__USE_BSD)
-int fflush_unlocked(FILE* __fp) __INTRODUCED_IN_FUTURE;
-int fgetc_unlocked(FILE* __fp) __INTRODUCED_IN_FUTURE;
-int fputc_unlocked(int __ch, FILE* __fp) __INTRODUCED_IN_FUTURE;
-size_t fread_unlocked(void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN_FUTURE;
-size_t fwrite_unlocked(const void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN_FUTURE;
+int fflush_unlocked(FILE* __fp) __INTRODUCED_IN(28);
+int fgetc_unlocked(FILE* __fp) __INTRODUCED_IN(28);
+int fputc_unlocked(int __ch, FILE* __fp) __INTRODUCED_IN(28);
+size_t fread_unlocked(void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN(28);
+size_t fwrite_unlocked(const void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN(28);
 #endif
 
 #if defined(__USE_GNU)
-int fputs_unlocked(const char* __s, FILE* __fp) __INTRODUCED_IN_FUTURE;
-char* fgets_unlocked(char* __buf, int __size, FILE* __fp) __INTRODUCED_IN_FUTURE;
+int fputs_unlocked(const char* __s, FILE* __fp) __INTRODUCED_IN(28);
+char* fgets_unlocked(char* __buf, int __size, FILE* __fp) __INTRODUCED_IN(28);
 #endif
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
diff --git a/libc/include/stdio_ext.h b/libc/include/stdio_ext.h
index 66a3ab9..2f0f438 100644
--- a/libc/include/stdio_ext.h
+++ b/libc/include/stdio_ext.h
@@ -37,9 +37,9 @@
 
 size_t __fbufsize(FILE* __fp) __INTRODUCED_IN(23);
 int __freadable(FILE* __fp) __INTRODUCED_IN(23);
-int __freading(FILE* __fp) __INTRODUCED_IN_FUTURE;
+int __freading(FILE* __fp) __INTRODUCED_IN(28);
 int __fwritable(FILE* __fp) __INTRODUCED_IN(23);
-int __fwriting(FILE* __fp) __INTRODUCED_IN_FUTURE;
+int __fwriting(FILE* __fp) __INTRODUCED_IN(28);
 int __flbf(FILE* __fp) __INTRODUCED_IN(23);
 void __fpurge(FILE* __fp) __INTRODUCED_IN(23);
 size_t __fpending(FILE* __fp) __INTRODUCED_IN(23);
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 1ae3c6e..944d72b 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -172,12 +172,17 @@
 #include <bits/fortify/stdlib.h>
 #endif
 
+#if __ANDROID_API__ >= __ANDROID_API_K__
+int abs(int __x) __attribute_const__ __INTRODUCED_IN(19);
+long labs(long __x) __attribute_const__ __INTRODUCED_IN(19);
+long long llabs(long long __x) __attribute_const__ __INTRODUCED_IN(19);
+#else
+// Implemented as static inlines before 19.
+#endif
+
 #if __ANDROID_API__ >= __ANDROID_API_L__
 float strtof(const char* __s, char** __end_ptr) __INTRODUCED_IN(21);
 double atof(const char* __s) __attribute_pure__ __INTRODUCED_IN(21);
-int abs(int __x) __attribute_const__ __INTRODUCED_IN(21);
-long labs(long __x) __attribute_const__ __INTRODUCED_IN(21);
-long long llabs(long long __x) __attribute_const__ __INTRODUCED_IN(21);
 int rand(void) __INTRODUCED_IN(21);
 void srand(unsigned int __seed) __INTRODUCED_IN(21);
 long random(void) __INTRODUCED_IN(21);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 3cf6723..be07007 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -300,6 +300,13 @@
  * inline` without making them available externally.
  */
 #    define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline
+/*
+ * We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
+ * for variadic functions because compilers cannot inline them.
+ * The __always_inline attribute is useless, misleading, and could trigger
+ * clang compiler bug to incorrectly inline variadic functions.
+ */
+#    define __BIONIC_FORTIFY_VARIADIC static __inline__
 /* Error functions don't have bodies, so they can just be static. */
 #    define __BIONIC_ERROR_FUNCTION_VISIBILITY static
 #  else
@@ -311,6 +318,8 @@
 #    define __call_bypassing_fortify(fn) (fn)
 /* __BIONIC_FORTIFY_NONSTATIC_INLINE is pointless in GCC's FORTIFY */
 #    define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
+/* __always_inline is probably okay and ignored by gcc in __BIONIC_FORTIFY_VARIADIC */
+#    define __BIONIC_FORTIFY_VARIADIC __BIONIC_FORTIFY_INLINE
 #  endif
 #else
 /* Further increase sharing for some inline functions */
diff --git a/libc/include/sys/epoll.h b/libc/include/sys/epoll.h
index 2bc16f5..a213a90 100644
--- a/libc/include/sys/epoll.h
+++ b/libc/include/sys/epoll.h
@@ -58,6 +58,7 @@
 int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __event);
 int epoll_wait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms);
 int epoll_pwait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms, const sigset_t* __mask) __INTRODUCED_IN(21);
+int epoll_pwait64(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms, const sigset64_t* __mask) __INTRODUCED_IN(28);
 
 __END_DECLS
 
diff --git a/libc/include/sys/ioctl.h b/libc/include/sys/ioctl.h
index 76dc1ff..b48b7f9 100644
--- a/libc/include/sys/ioctl.h
+++ b/libc/include/sys/ioctl.h
@@ -36,8 +36,6 @@
  * terminal-related ioctl data structures such as struct winsize.
  */
 #include <linux/termios.h>
-#include <asm/ioctls.h>
-#include <asm/termbits.h>
 #include <linux/tty.h>
 
 #include <bits/ioctl.h>
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index 3475652..4b849f3 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -38,9 +38,9 @@
 
 /* See also arc4random_buf in <stdlib.h>, which is available in all API levels. */
 
-int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN_FUTURE;
+int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
 
-ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN_FUTURE;
+ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
 
 __END_DECLS
 
diff --git a/libc/include/sys/select.h b/libc/include/sys/select.h
index ac51d3f..603a5a6 100644
--- a/libc/include/sys/select.h
+++ b/libc/include/sys/select.h
@@ -75,6 +75,7 @@
 
 int select(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, struct timeval* __timeout);
 int pselect(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset_t* __mask);
+int pselect64(int __fd_count, fd_set* __read_fds, fd_set* __write_fds, fd_set* __exception_fds, const struct timespec* __timeout, const sigset64_t* __mask);
 
 __END_DECLS
 
diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h
index 315622c..2337cd7 100644
--- a/libc/include/sys/signalfd.h
+++ b/libc/include/sys/signalfd.h
@@ -37,6 +37,7 @@
 __BEGIN_DECLS
 
 int signalfd(int __fd, const sigset_t* __mask, int __flags) __INTRODUCED_IN(18);
+int signalfd64(int __fd, const sigset64_t* __mask, int __flags) __INTRODUCED_IN(28);
 
 __END_DECLS
 
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index ef75c84..f191028 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -98,7 +98,7 @@
 int execlp(const char* __file, const char* __arg0, ...) __attribute__((__sentinel__));
 int execle(const char* __path, const char* __arg0, ... /*,  char* const* __envp */)
     __attribute__((__sentinel__(1)));
-int fexecve(int __fd, char* const* __argv, char* const* __envp) __INTRODUCED_IN_FUTURE;
+int fexecve(int __fd, char* const* __argv, char* const* __envp) __INTRODUCED_IN(28);
 
 int nice(int __incr);
 
@@ -119,7 +119,7 @@
 int getresuid(uid_t* __ruid, uid_t* __euid, uid_t* __suid);
 int getresgid(gid_t* __rgid, gid_t* __egid, gid_t* __sgid);
 char* getlogin(void);
-int getlogin_r(char* __buffer, size_t __buffer_size) __INTRODUCED_IN_FUTURE;
+int getlogin_r(char* __buffer, size_t __buffer_size) __INTRODUCED_IN(28);
 
 long fpathconf(int __fd, int __name);
 long pathconf(const char* __path, int __name);
@@ -152,7 +152,7 @@
 
 void sync(void);
 #if defined(__USE_GNU)
-int syncfs(int __fd) __INTRODUCED_IN_FUTURE;
+int syncfs(int __fd) __INTRODUCED_IN(28);
 #endif
 
 int close(int __fd);
@@ -243,7 +243,7 @@
 int getdomainname(char* __buf, size_t __buf_size) __INTRODUCED_IN(26);
 int setdomainname(const char* __name, size_t __n) __INTRODUCED_IN(26);
 
-void swab(const void* __src, void* __dst, ssize_t __byte_count) __INTRODUCED_IN_FUTURE;
+void swab(const void* __src, void* __dst, ssize_t __byte_count) __INTRODUCED_IN(28);
 
 #if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
 #include <bits/fortify/unistd.h>
@@ -251,4 +251,4 @@
 
 __END_DECLS
 
-#endif /* _UNISTD_H_ */
+#endif
diff --git a/libc/kernel/android/scsi/scsi/scsi_proto.h b/libc/kernel/android/scsi/scsi/scsi_proto.h
index 7f3abd9..1b56ecb 100644
--- a/libc/kernel/android/scsi/scsi/scsi_proto.h
+++ b/libc/kernel/android/scsi/scsi/scsi_proto.h
@@ -176,17 +176,32 @@
 #define SCSI_ACCESS_STATE_MASK 0x0f
 #define SCSI_ACCESS_STATE_PREFERRED 0x80
 enum zbc_zone_reporting_options {
-  ZBC_ZONE_REPORTING_OPTION_ALL = 0,
-  ZBC_ZONE_REPORTING_OPTION_EMPTY,
-  ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN,
-  ZBC_ZONE_REPORTING_OPTION_EXPLICIT_OPEN,
-  ZBC_ZONE_REPORTING_OPTION_CLOSED,
-  ZBC_ZONE_REPORTING_OPTION_FULL,
-  ZBC_ZONE_REPORTING_OPTION_READONLY,
-  ZBC_ZONE_REPORTING_OPTION_OFFLINE,
+  ZBC_ZONE_REPORTING_OPTION_ALL = 0x00,
+  ZBC_ZONE_REPORTING_OPTION_EMPTY = 0x01,
+  ZBC_ZONE_REPORTING_OPTION_IMPLICIT_OPEN = 0x02,
+  ZBC_ZONE_REPORTING_OPTION_EXPLICIT_OPEN = 0x03,
+  ZBC_ZONE_REPORTING_OPTION_CLOSED = 0x04,
+  ZBC_ZONE_REPORTING_OPTION_FULL = 0x05,
+  ZBC_ZONE_REPORTING_OPTION_READONLY = 0x06,
+  ZBC_ZONE_REPORTING_OPTION_OFFLINE = 0x07,
   ZBC_ZONE_REPORTING_OPTION_NEED_RESET_WP = 0x10,
-  ZBC_ZONE_REPORTING_OPTION_NON_SEQWRITE,
+  ZBC_ZONE_REPORTING_OPTION_NON_SEQWRITE = 0x11,
   ZBC_ZONE_REPORTING_OPTION_NON_WP = 0x3f,
 };
 #define ZBC_REPORT_ZONE_PARTIAL 0x80
+enum zbc_zone_type {
+  ZBC_ZONE_TYPE_CONV = 0x1,
+  ZBC_ZONE_TYPE_SEQWRITE_REQ = 0x2,
+  ZBC_ZONE_TYPE_SEQWRITE_PREF = 0x3,
+};
+enum zbc_zone_cond {
+  ZBC_ZONE_COND_NO_WP = 0x0,
+  ZBC_ZONE_COND_EMPTY = 0x1,
+  ZBC_ZONE_COND_IMP_OPEN = 0x2,
+  ZBC_ZONE_COND_EXP_OPEN = 0x3,
+  ZBC_ZONE_COND_CLOSED = 0x4,
+  ZBC_ZONE_COND_READONLY = 0xd,
+  ZBC_ZONE_COND_FULL = 0xe,
+  ZBC_ZONE_COND_OFFLINE = 0xf,
+};
 #endif
diff --git a/libc/kernel/android/uapi/linux/compiler_types.h b/libc/kernel/android/uapi/linux/compiler_types.h
new file mode 100644
index 0000000..94f4fbe
--- /dev/null
+++ b/libc/kernel/android/uapi/linux/compiler_types.h
@@ -0,0 +1,5 @@
+/*
+ * The compiler.h file has been split into compiler.h and compiler_types.h.
+ * However, to compile bionic we only need the compiler.h.
+ */
+#include <linux/compiler.h>
diff --git a/libc/kernel/uapi/asm-arm/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-arm/asm/bpf_perf_event.h
new file mode 100644
index 0000000..fa7bc48
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm/asm/bpf_perf_event.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/bpf_perf_event.h>
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
index 2332ae2..448a773 100644
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm/asm/kvm.h
@@ -106,6 +106,9 @@
 #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)
@@ -157,6 +160,7 @@
 #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_TYPE_SHIFT 24
 #define KVM_ARM_IRQ_TYPE_MASK 0xff
 #define KVM_ARM_IRQ_VCPU_SHIFT 16
diff --git a/libc/kernel/uapi/asm-arm/asm/ptrace.h b/libc/kernel/uapi/asm-arm/asm/ptrace.h
index dcc3826..b0291dc 100644
--- a/libc/kernel/uapi/asm-arm/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm/asm/ptrace.h
@@ -34,6 +34,9 @@
 #define PTRACE_SETVFPREGS 28
 #define PTRACE_GETHBPREGS 29
 #define PTRACE_SETHBPREGS 30
+#define PTRACE_GETFDPIC 31
+#define PTRACE_GETFDPIC_EXEC 0
+#define PTRACE_GETFDPIC_INTERP 1
 #define USR26_MODE 0x00000000
 #define FIQ26_MODE 0x00000001
 #define IRQ26_MODE 0x00000002
@@ -42,6 +45,7 @@
 #define SVC_MODE 0x00000013
 #define FIQ_MODE 0x00000011
 #define IRQ_MODE 0x00000012
+#define MON_MODE 0x00000016
 #define ABT_MODE 0x00000017
 #define HYP_MODE 0x0000001a
 #define UND_MODE 0x0000001b
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd.h b/libc/kernel/uapi/asm-arm/asm/unistd.h
index d14fd73..f4b1f3a 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd.h
@@ -29,4 +29,5 @@
 #define __ARM_NR_usr26 (__ARM_NR_BASE + 3)
 #define __ARM_NR_usr32 (__ARM_NR_BASE + 4)
 #define __ARM_NR_set_tls (__ARM_NR_BASE + 5)
+#define __ARM_NR_get_tls (__ARM_NR_BASE + 6)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-arm64/asm/bpf_perf_event.h
new file mode 100644
index 0000000..cad04bf
--- /dev/null
+++ b/libc/kernel/uapi/asm-arm64/asm/bpf_perf_event.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__
+#define _UAPI__ASM_BPF_PERF_EVENT_H__
+#include <asm/ptrace.h>
+typedef struct user_pt_regs bpf_user_pt_regs_t;
+#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 60b8305..4e95b95 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -35,4 +35,10 @@
 #define HWCAP_FCMA (1 << 14)
 #define HWCAP_LRCPC (1 << 15)
 #define HWCAP_DCPOP (1 << 16)
+#define HWCAP_SHA3 (1 << 17)
+#define HWCAP_SM3 (1 << 18)
+#define HWCAP_SM4 (1 << 19)
+#define HWCAP_ASIMDDP (1 << 20)
+#define HWCAP_SHA512 (1 << 21)
+#define HWCAP_SVE (1 << 22)
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index a68a8a2..c4178a1 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -117,6 +117,9 @@
 #define ARM64_SYS_REG_SHIFT_MASK(x,n) (((x) << KVM_REG_ARM64_SYSREG_ ##n ##_SHIFT) & KVM_REG_ARM64_SYSREG_ ##n ##_MASK)
 #define __ARM64_SYS_REG(op0,op1,crn,crm,op2) (KVM_REG_ARM64 | KVM_REG_ARM64_SYSREG | ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | ARM64_SYS_REG_SHIFT_MASK(op2, OP2))
 #define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
+#define KVM_REG_ARM_PTIMER_CTL ARM64_SYS_REG(3, 3, 14, 2, 1)
+#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)
@@ -144,6 +147,7 @@
 #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_VCPU_PMU_V3_CTRL 0
 #define KVM_ARM_VCPU_PMU_V3_IRQ 0
 #define KVM_ARM_VCPU_PMU_V3_INIT 1
diff --git a/libc/kernel/uapi/asm-arm64/asm/ptrace.h b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
index 0eccf79..4e6c755 100644
--- a/libc/kernel/uapi/asm-arm64/asm/ptrace.h
+++ b/libc/kernel/uapi/asm-arm64/asm/ptrace.h
@@ -20,6 +20,7 @@
 #define _UAPI__ASM_PTRACE_H
 #include <linux/types.h>
 #include <asm/hwcap.h>
+#include <asm/sigcontext.h>
 #define PSR_MODE_EL0t 0x00000000
 #define PSR_MODE_EL1t 0x00000004
 #define PSR_MODE_EL1h 0x00000005
@@ -35,7 +36,6 @@
 #define PSR_D_BIT 0x00000200
 #define PSR_PAN_BIT 0x00400000
 #define PSR_UAO_BIT 0x00800000
-#define PSR_Q_BIT 0x08000000
 #define PSR_V_BIT 0x10000000
 #define PSR_C_BIT 0x20000000
 #define PSR_Z_BIT 0x40000000
@@ -45,6 +45,7 @@
 #define PSR_x 0x0000ff00
 #define PSR_c 0x000000ff
 #ifndef __ASSEMBLY__
+#include <linux/prctl.h>
 struct user_pt_regs {
   __u64 regs[31];
   __u64 sp;
@@ -66,5 +67,39 @@
     __u32 pad;
   } dbg_regs[16];
 };
+struct user_sve_header {
+  __u32 size;
+  __u32 max_size;
+  __u16 vl;
+  __u16 max_vl;
+  __u16 flags;
+  __u16 __reserved;
+};
+#define SVE_PT_REGS_MASK (1 << 0)
+#define SVE_PT_REGS_FPSIMD 0
+#define SVE_PT_REGS_SVE SVE_PT_REGS_MASK
+#define SVE_PT_VL_INHERIT (PR_SVE_VL_INHERIT >> 16)
+#define SVE_PT_VL_ONEXEC (PR_SVE_SET_VL_ONEXEC >> 16)
+#define SVE_PT_REGS_OFFSET ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_FPSIMD_OFFSET SVE_PT_REGS_OFFSET
+#define SVE_PT_FPSIMD_SIZE(vq,flags) (sizeof(struct user_fpsimd_state))
+#define SVE_PT_SVE_ZREG_SIZE(vq) SVE_SIG_ZREG_SIZE(vq)
+#define SVE_PT_SVE_PREG_SIZE(vq) SVE_SIG_PREG_SIZE(vq)
+#define SVE_PT_SVE_FFR_SIZE(vq) SVE_SIG_FFR_SIZE(vq)
+#define SVE_PT_SVE_FPSR_SIZE sizeof(__u32)
+#define SVE_PT_SVE_FPCR_SIZE sizeof(__u32)
+#define __SVE_SIG_TO_PT(offset) ((offset) - SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET)
+#define SVE_PT_SVE_OFFSET SVE_PT_REGS_OFFSET
+#define SVE_PT_SVE_ZREGS_OFFSET __SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET)
+#define SVE_PT_SVE_ZREG_OFFSET(vq,n) __SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n))
+#define SVE_PT_SVE_ZREGS_SIZE(vq) (SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
+#define SVE_PT_SVE_PREGS_OFFSET(vq) __SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq))
+#define SVE_PT_SVE_PREG_OFFSET(vq,n) __SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n))
+#define SVE_PT_SVE_PREGS_SIZE(vq) (SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_PT_SVE_PREGS_OFFSET(vq))
+#define SVE_PT_SVE_FFR_OFFSET(vq) __SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq))
+#define SVE_PT_SVE_FPSR_OFFSET(vq) ((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_SVE_FPCR_OFFSET(vq) (SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE)
+#define SVE_PT_SVE_SIZE(vq,flags) ((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE - SVE_PT_SVE_OFFSET + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_SIZE(vq,flags) (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ? SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags) : SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index be2464e..b0617de 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -18,6 +18,7 @@
  ****************************************************************************/
 #ifndef _UAPI__ASM_SIGCONTEXT_H
 #define _UAPI__ASM_SIGCONTEXT_H
+#ifndef __ASSEMBLY__
 #include <linux/types.h>
 struct sigcontext {
   __u64 fault_address;
@@ -50,4 +51,34 @@
   __u32 size;
   __u32 __reserved[3];
 };
+#define SVE_MAGIC 0x53564501
+struct sve_context {
+  struct _aarch64_ctx head;
+  __u16 vl;
+  __u16 __reserved[3];
+};
+#endif
+#define SVE_VQ_BYTES 16
+#define SVE_VQ_MIN 1
+#define SVE_VQ_MAX 512
+#define SVE_VL_MIN (SVE_VQ_MIN * SVE_VQ_BYTES)
+#define SVE_VL_MAX (SVE_VQ_MAX * SVE_VQ_BYTES)
+#define SVE_NUM_ZREGS 32
+#define SVE_NUM_PREGS 16
+#define sve_vl_valid(vl) ((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)
+#define sve_vq_from_vl(vl) ((vl) / SVE_VQ_BYTES)
+#define sve_vl_from_vq(vq) ((vq) * SVE_VQ_BYTES)
+#define SVE_SIG_ZREG_SIZE(vq) ((__u32) (vq) * SVE_VQ_BYTES)
+#define SVE_SIG_PREG_SIZE(vq) ((__u32) (vq) * (SVE_VQ_BYTES / 8))
+#define SVE_SIG_FFR_SIZE(vq) SVE_SIG_PREG_SIZE(vq)
+#define SVE_SIG_REGS_OFFSET ((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1)) / SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_SIG_ZREGS_OFFSET SVE_SIG_REGS_OFFSET
+#define SVE_SIG_ZREG_OFFSET(vq,n) (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n))
+#define SVE_SIG_ZREGS_SIZE(vq) (SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET)
+#define SVE_SIG_PREGS_OFFSET(vq) (SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq))
+#define SVE_SIG_PREG_OFFSET(vq,n) (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n))
+#define SVE_SIG_PREGS_SIZE(vq) (SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq))
+#define SVE_SIG_FFR_OFFSET(vq) (SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq))
+#define SVE_SIG_REGS_SIZE(vq) (SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)
+#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
 #endif
diff --git a/libc/kernel/uapi/asm-generic/bpf_perf_event.h b/libc/kernel/uapi/asm-generic/bpf_perf_event.h
new file mode 100644
index 0000000..794927b
--- /dev/null
+++ b/libc/kernel/uapi/asm-generic/bpf_perf_event.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
+#define _UAPI__ASM_GENERIC_BPF_PERF_EVENT_H__
+#include <linux/ptrace.h>
+typedef struct pt_regs bpf_user_pt_regs_t;
+#endif
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index a15624a..e752bb6 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -27,6 +27,7 @@
 #define PROT_GROWSUP 0x02000000
 #define MAP_SHARED 0x01
 #define MAP_PRIVATE 0x02
+#define MAP_SHARED_VALIDATE 0x03
 #define MAP_TYPE 0x0f
 #define MAP_FIXED 0x10
 #define MAP_ANONYMOUS 0x20
diff --git a/libc/kernel/uapi/asm-generic/mman.h b/libc/kernel/uapi/asm-generic/mman.h
index 0452237..84caab7 100644
--- a/libc/kernel/uapi/asm-generic/mman.h
+++ b/libc/kernel/uapi/asm-generic/mman.h
@@ -28,6 +28,7 @@
 #define MAP_NONBLOCK 0x10000
 #define MAP_STACK 0x20000
 #define MAP_HUGETLB 0x40000
+#define MAP_SYNC 0x80000
 #define MCL_CURRENT 1
 #define MCL_FUTURE 2
 #define MCL_ONFAULT 4
diff --git a/libc/kernel/uapi/asm-mips/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-mips/asm/bpf_perf_event.h
new file mode 100644
index 0000000..fa7bc48
--- /dev/null
+++ b/libc/kernel/uapi/asm-mips/asm/bpf_perf_event.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/bpf_perf_event.h>
diff --git a/libc/kernel/uapi/asm-mips/asm/mman.h b/libc/kernel/uapi/asm-mips/asm/mman.h
index b976885..5e8e28a 100644
--- a/libc/kernel/uapi/asm-mips/asm/mman.h
+++ b/libc/kernel/uapi/asm-mips/asm/mman.h
@@ -27,6 +27,7 @@
 #define PROT_GROWSUP 0x02000000
 #define MAP_SHARED 0x001
 #define MAP_PRIVATE 0x002
+#define MAP_SHARED_VALIDATE 0x003
 #define MAP_TYPE 0x00f
 #define MAP_FIXED 0x010
 #define MAP_RENAME 0x020
diff --git a/libc/kernel/uapi/asm-x86/asm/bpf_perf_event.h b/libc/kernel/uapi/asm-x86/asm/bpf_perf_event.h
new file mode 100644
index 0000000..fa7bc48
--- /dev/null
+++ b/libc/kernel/uapi/asm-x86/asm/bpf_perf_event.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/bpf_perf_event.h>
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index f0f8dd2..85f9d7e 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -81,7 +81,10 @@
 #define X86_CR3_PWT _BITUL(X86_CR3_PWT_BIT)
 #define X86_CR3_PCD_BIT 4
 #define X86_CR3_PCD _BITUL(X86_CR3_PCD_BIT)
-#define X86_CR3_PCID_MASK _AC(0x00000fff, UL)
+#define X86_CR3_PCID_BITS 12
+#define X86_CR3_PCID_MASK (_AC((1UL << X86_CR3_PCID_BITS) - 1, UL))
+#define X86_CR3_PCID_NOFLUSH_BIT 63
+#define X86_CR3_PCID_NOFLUSH _BITULL(X86_CR3_PCID_NOFLUSH_BIT)
 #define X86_CR4_VME_BIT 0
 #define X86_CR4_VME _BITUL(X86_CR4_VME_BIT)
 #define X86_CR4_PVI_BIT 1
@@ -104,6 +107,8 @@
 #define X86_CR4_OSFXSR _BITUL(X86_CR4_OSFXSR_BIT)
 #define X86_CR4_OSXMMEXCPT_BIT 10
 #define X86_CR4_OSXMMEXCPT _BITUL(X86_CR4_OSXMMEXCPT_BIT)
+#define X86_CR4_UMIP_BIT 11
+#define X86_CR4_UMIP _BITUL(X86_CR4_UMIP_BIT)
 #define X86_CR4_LA57_BIT 12
 #define X86_CR4_LA57 _BITUL(X86_CR4_LA57_BIT)
 #define X86_CR4_VMXE_BIT 13
@@ -138,4 +143,5 @@
 #define CX86_DIR1 0xff
 #define CX86_ARR_BASE 0xc4
 #define CX86_RCR_BASE 0xdc
+#define CR0_STATE (X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM | X86_CR0_PG)
 #endif
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 6ae9c9c..1cdae16 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -35,6 +35,8 @@
 #define DRM_AMDGPU_GEM_USERPTR 0x11
 #define DRM_AMDGPU_WAIT_FENCES 0x12
 #define DRM_AMDGPU_VM 0x13
+#define DRM_AMDGPU_FENCE_TO_HANDLE 0x14
+#define DRM_AMDGPU_SCHED 0x15
 #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
 #define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
 #define DRM_IOCTL_AMDGPU_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CTX, union drm_amdgpu_ctx)
@@ -49,6 +51,8 @@
 #define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
 #define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
 #define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
+#define DRM_IOCTL_AMDGPU_FENCE_TO_HANDLE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_FENCE_TO_HANDLE, union drm_amdgpu_fence_to_handle)
+#define DRM_IOCTL_AMDGPU_SCHED DRM_IOW(DRM_COMMAND_BASE + DRM_AMDGPU_SCHED, union drm_amdgpu_sched)
 #define AMDGPU_GEM_DOMAIN_CPU 0x1
 #define AMDGPU_GEM_DOMAIN_GTT 0x2
 #define AMDGPU_GEM_DOMAIN_VRAM 0x4
@@ -61,6 +65,8 @@
 #define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
 #define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
 #define AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS (1 << 5)
+#define AMDGPU_GEM_CREATE_VM_ALWAYS_VALID (1 << 6)
+#define AMDGPU_GEM_CREATE_EXPLICIT_SYNC (1 << 7)
 struct drm_amdgpu_gem_create_in {
   __u64 bo_size;
   __u64 alignment;
@@ -104,11 +110,17 @@
 #define AMDGPU_CTX_GUILTY_RESET 1
 #define AMDGPU_CTX_INNOCENT_RESET 2
 #define AMDGPU_CTX_UNKNOWN_RESET 3
+#define AMDGPU_CTX_PRIORITY_UNSET - 2048
+#define AMDGPU_CTX_PRIORITY_VERY_LOW - 1023
+#define AMDGPU_CTX_PRIORITY_LOW - 512
+#define AMDGPU_CTX_PRIORITY_NORMAL 0
+#define AMDGPU_CTX_PRIORITY_HIGH 512
+#define AMDGPU_CTX_PRIORITY_VERY_HIGH 1023
 struct drm_amdgpu_ctx_in {
   __u32 op;
   __u32 flags;
   __u32 ctx_id;
-  __u32 _pad;
+  __s32 priority;
 };
 union drm_amdgpu_ctx_out {
   struct {
@@ -138,6 +150,16 @@
   struct drm_amdgpu_vm_in in;
   struct drm_amdgpu_vm_out out;
 };
+#define AMDGPU_SCHED_OP_PROCESS_PRIORITY_OVERRIDE 1
+struct drm_amdgpu_sched_in {
+  __u32 op;
+  __u32 fd;
+  __s32 priority;
+  __u32 flags;
+};
+union drm_amdgpu_sched {
+  struct drm_amdgpu_sched_in in;
+};
 #define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
 #define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
 #define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
@@ -331,6 +353,19 @@
 struct drm_amdgpu_cs_chunk_sem {
   __u32 handle;
 };
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1
+#define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2
+union drm_amdgpu_fence_to_handle {
+  struct {
+    struct drm_amdgpu_fence fence;
+    __u32 what;
+    __u32 pad;
+  } in;
+  struct {
+    __u32 handle;
+  } out;
+};
 struct drm_amdgpu_cs_chunk_data {
   union {
     struct drm_amdgpu_cs_chunk_ib ib_data;
@@ -381,6 +416,7 @@
 #define AMDGPU_INFO_SENSOR_VDDNB 0x6
 #define AMDGPU_INFO_SENSOR_VDDGFX 0x7
 #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
+#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
 #define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 6863dc1..ec0c1fa 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -412,6 +412,20 @@
   __u32 count_handles;
   __u32 pad;
 };
+struct drm_crtc_get_sequence {
+  __u32 crtc_id;
+  __u32 active;
+  __u64 sequence;
+  __s64 sequence_ns;
+};
+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001
+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002
+struct drm_crtc_queue_sequence {
+  __u32 crtc_id;
+  __u32 flags;
+  __u64 sequence;
+  __u64 user_data;
+};
 #ifdef __cplusplus
 #endif
 #include "drm_mode.h"
@@ -478,6 +492,8 @@
 #define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather)
 #define DRM_IOCTL_SG_FREE DRM_IOW(0x39, struct drm_scatter_gather)
 #define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
 #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
 #define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
 #define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
@@ -517,6 +533,10 @@
 #define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
 #define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
 #define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
 #define DRM_COMMAND_BASE 0x40
 #define DRM_COMMAND_END 0xA0
 struct drm_event {
@@ -525,6 +545,7 @@
 };
 #define DRM_EVENT_VBLANK 0x01
 #define DRM_EVENT_FLIP_COMPLETE 0x02
+#define DRM_EVENT_CRTC_SEQUENCE 0x03
 struct drm_event_vblank {
   struct drm_event base;
   __u64 user_data;
@@ -533,6 +554,12 @@
   __u32 sequence;
   __u32 crtc_id;
 };
+struct drm_event_crtc_sequence {
+  struct drm_event base;
+  __u64 user_data;
+  __s64 time_ns;
+  __u64 sequence;
+};
 typedef struct drm_clip_rect drm_clip_rect_t;
 typedef struct drm_drawable_info drm_drawable_info_t;
 typedef struct drm_tex_region drm_tex_region_t;
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index 5e97a72..2c9defb 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -427,6 +427,26 @@
 struct drm_mode_destroy_blob {
   __u32 blob_id;
 };
+struct drm_mode_create_lease {
+  __u64 object_ids;
+  __u32 object_count;
+  __u32 flags;
+  __u32 lessee_id;
+  __u32 fd;
+};
+struct drm_mode_list_lessees {
+  __u32 count_lessees;
+  __u32 pad;
+  __u64 lessees_ptr;
+};
+struct drm_mode_get_lease {
+  __u32 count_objects;
+  __u32 pad;
+  __u64 objects_ptr;
+};
+struct drm_mode_revoke_lease {
+  __u32 lessee_id;
+};
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/etnaviv_drm.h b/libc/kernel/uapi/drm/etnaviv_drm.h
index 6376e25..58bd536 100644
--- a/libc/kernel/uapi/drm/etnaviv_drm.h
+++ b/libc/kernel/uapi/drm/etnaviv_drm.h
@@ -91,6 +91,17 @@
   __u32 handle;
   __u64 presumed;
 };
+#define ETNA_PM_PROCESS_PRE 0x0001
+#define ETNA_PM_PROCESS_POST 0x0002
+struct drm_etnaviv_gem_submit_pmr {
+  __u32 flags;
+  __u8 domain;
+  __u8 pad;
+  __u16 signal;
+  __u32 sequence;
+  __u32 read_offset;
+  __u32 read_idx;
+};
 #define ETNA_SUBMIT_NO_IMPLICIT 0x0001
 #define ETNA_SUBMIT_FENCE_FD_IN 0x0002
 #define ETNA_SUBMIT_FENCE_FD_OUT 0x0004
@@ -110,6 +121,9 @@
   __u64 stream;
   __u32 flags;
   __s32 fence_fd;
+  __u64 pmrs;
+  __u32 nr_pmrs;
+  __u32 pad;
 };
 #define ETNA_WAIT_NONBLOCK 0x01
 struct drm_etnaviv_wait_fence {
@@ -134,6 +148,21 @@
   __u32 pad;
   struct drm_etnaviv_timespec timeout;
 };
+struct drm_etnaviv_pm_domain {
+  __u32 pipe;
+  __u8 iter;
+  __u8 id;
+  __u16 nr_signals;
+  char name[64];
+};
+struct drm_etnaviv_pm_signal {
+  __u32 pipe;
+  __u8 domain;
+  __u8 pad;
+  __u16 iter;
+  __u16 id;
+  char name[64];
+};
 #define DRM_ETNAVIV_GET_PARAM 0x00
 #define DRM_ETNAVIV_GEM_NEW 0x02
 #define DRM_ETNAVIV_GEM_INFO 0x03
@@ -143,7 +172,9 @@
 #define DRM_ETNAVIV_WAIT_FENCE 0x07
 #define DRM_ETNAVIV_GEM_USERPTR 0x08
 #define DRM_ETNAVIV_GEM_WAIT 0x09
-#define DRM_ETNAVIV_NUM_IOCTLS 0x0a
+#define DRM_ETNAVIV_PM_QUERY_DOM 0x0a
+#define DRM_ETNAVIV_PM_QUERY_SIG 0x0b
+#define DRM_ETNAVIV_NUM_IOCTLS 0x0c
 #define DRM_IOCTL_ETNAVIV_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GET_PARAM, struct drm_etnaviv_param)
 #define DRM_IOCTL_ETNAVIV_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_NEW, struct drm_etnaviv_gem_new)
 #define DRM_IOCTL_ETNAVIV_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_INFO, struct drm_etnaviv_gem_info)
@@ -153,6 +184,8 @@
 #define DRM_IOCTL_ETNAVIV_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_WAIT_FENCE, struct drm_etnaviv_wait_fence)
 #define DRM_IOCTL_ETNAVIV_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_USERPTR, struct drm_etnaviv_gem_userptr)
 #define DRM_IOCTL_ETNAVIV_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_ETNAVIV_GEM_WAIT, struct drm_etnaviv_gem_wait)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_DOM DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_DOM, struct drm_etnaviv_pm_domain)
+#define DRM_IOCTL_ETNAVIV_PM_QUERY_SIG DRM_IOWR(DRM_COMMAND_BASE + DRM_ETNAVIV_PM_QUERY_SIG, struct drm_etnaviv_pm_signal)
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 50ea43a..34342bf 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -293,6 +293,9 @@
 #define I915_PARAM_MIN_EU_IN_POOL 39
 #define I915_PARAM_MMAP_GTT_VERSION 40
 #define I915_PARAM_HAS_SCHEDULER 41
+#define I915_SCHEDULER_CAP_ENABLED (1ul << 0)
+#define I915_SCHEDULER_CAP_PRIORITY (1ul << 1)
+#define I915_SCHEDULER_CAP_PREEMPTION (1ul << 2)
 #define I915_PARAM_HUC_STATUS 42
 #define I915_PARAM_HAS_EXEC_ASYNC 43
 #define I915_PARAM_HAS_EXEC_FENCE 44
@@ -633,6 +636,7 @@
 };
 struct drm_i915_reg_read {
   __u64 offset;
+#define I915_REG_READ_8B_WA (1ul << 0)
   __u64 val;
 };
 struct drm_i915_reset_stats {
@@ -660,6 +664,10 @@
 #define I915_CONTEXT_PARAM_GTT_SIZE 0x3
 #define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
 #define I915_CONTEXT_PARAM_BANNABLE 0x5
+#define I915_CONTEXT_PARAM_PRIORITY 0x6
+#define I915_CONTEXT_MAX_USER_PRIORITY 1023
+#define I915_CONTEXT_DEFAULT_PRIORITY 0
+#define I915_CONTEXT_MIN_USER_PRIORITY - 1023
   __u64 value;
 };
 enum drm_i915_oa_format {
@@ -709,9 +717,9 @@
   __u32 n_mux_regs;
   __u32 n_boolean_regs;
   __u32 n_flex_regs;
-  __u64 __user mux_regs_ptr;
-  __u64 __user boolean_regs_ptr;
-  __u64 __user flex_regs_ptr;
+  __u64 mux_regs_ptr;
+  __u64 boolean_regs_ptr;
+  __u64 flex_regs_ptr;
 };
 #ifdef __cplusplus
 #endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 4f1a423..d2f1b57 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -38,6 +38,7 @@
 #define MSM_PARAM_MAX_FREQ 0x04
 #define MSM_PARAM_TIMESTAMP 0x05
 #define MSM_PARAM_GMEM_BASE 0x06
+#define MSM_PARAM_NR_RINGS 0x07
 struct drm_msm_param {
   __u32 pipe;
   __u32 param;
@@ -113,11 +114,13 @@
   __u64 bos;
   __u64 cmds;
   __s32 fence_fd;
+  __u32 queueid;
 };
 struct drm_msm_wait_fence {
   __u32 fence;
   __u32 pad;
   struct drm_msm_timespec timeout;
+  __u32 queueid;
 };
 #define MSM_MADV_WILLNEED 0
 #define MSM_MADV_DONTNEED 1
@@ -127,6 +130,12 @@
   __u32 madv;
   __u32 retained;
 };
+#define MSM_SUBMITQUEUE_FLAGS (0)
+struct drm_msm_submitqueue {
+  __u32 flags;
+  __u32 prio;
+  __u32 id;
+};
 #define DRM_MSM_GET_PARAM 0x00
 #define DRM_MSM_GEM_NEW 0x02
 #define DRM_MSM_GEM_INFO 0x03
@@ -135,6 +144,8 @@
 #define DRM_MSM_GEM_SUBMIT 0x06
 #define DRM_MSM_WAIT_FENCE 0x07
 #define DRM_MSM_GEM_MADVISE 0x08
+#define DRM_MSM_SUBMITQUEUE_NEW 0x0A
+#define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B
 #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
 #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
 #define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info)
@@ -143,6 +154,8 @@
 #define DRM_IOCTL_MSM_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit)
 #define DRM_IOCTL_MSM_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence)
 #define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue)
+#define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32)
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/drm/vc4_drm.h b/libc/kernel/uapi/drm/vc4_drm.h
index d96c49d..3ca378f 100644
--- a/libc/kernel/uapi/drm/vc4_drm.h
+++ b/libc/kernel/uapi/drm/vc4_drm.h
@@ -32,6 +32,7 @@
 #define DRM_VC4_SET_TILING 0x08
 #define DRM_VC4_GET_TILING 0x09
 #define DRM_VC4_LABEL_BO 0x0a
+#define DRM_VC4_GEM_MADVISE 0x0b
 #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
 #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
 #define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo)
@@ -43,6 +44,7 @@
 #define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
 #define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
 #define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
+#define DRM_IOCTL_VC4_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GEM_MADVISE, struct drm_vc4_gem_madvise)
 struct drm_vc4_submit_rcl_surface {
   __u32 hindex;
   __u32 offset;
@@ -142,6 +144,7 @@
 #define DRM_VC4_PARAM_SUPPORTS_ETC1 4
 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
 #define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
+#define DRM_VC4_PARAM_SUPPORTS_MADVISE 7
 struct drm_vc4_get_param {
   __u32 param;
   __u32 pad;
@@ -162,6 +165,16 @@
   __u32 len;
   __u64 name;
 };
+#define VC4_MADV_WILLNEED 0
+#define VC4_MADV_DONTNEED 1
+#define __VC4_MADV_PURGED 2
+#define __VC4_MADV_NOTSUPP 3
+struct drm_vc4_gem_madvise {
+  __u32 handle;
+  __u32 madv;
+  __u32 retained;
+  __u32 pad;
+};
 #ifdef __cplusplus
 #endif
 #endif
diff --git a/libc/kernel/uapi/linux/audit.h b/libc/kernel/uapi/linux/audit.h
index 3edd1d4..be48b44 100644
--- a/libc/kernel/uapi/linux/audit.h
+++ b/libc/kernel/uapi/linux/audit.h
@@ -78,6 +78,7 @@
 #define AUDIT_FEATURE_CHANGE 1328
 #define AUDIT_REPLACE 1329
 #define AUDIT_KERN_MODULE 1330
+#define AUDIT_FANOTIFY 1331
 #define AUDIT_AVC 1400
 #define AUDIT_SELINUX_ERR 1401
 #define AUDIT_AVC_PATH 1402
@@ -116,7 +117,8 @@
 #define AUDIT_FILTER_WATCH 0x03
 #define AUDIT_FILTER_EXIT 0x04
 #define AUDIT_FILTER_TYPE 0x05
-#define AUDIT_NR_FILTERS 6
+#define AUDIT_FILTER_FS 0x06
+#define AUDIT_NR_FILTERS 7
 #define AUDIT_FILTER_PREPEND 0x10
 #define AUDIT_NEVER 0
 #define AUDIT_POSSIBLE 1
@@ -190,6 +192,7 @@
 #define AUDIT_OBJ_LEV_HIGH 23
 #define AUDIT_LOGINUID_SET 24
 #define AUDIT_SESSIONID 25
+#define AUDIT_FSTYPE 26
 #define AUDIT_DEVMAJOR 100
 #define AUDIT_DEVMINOR 101
 #define AUDIT_INODE 102
@@ -242,7 +245,8 @@
 #define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008
 #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010
 #define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020
-#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | AUDIT_FEATURE_BITMAP_LOST_RESET)
+#define AUDIT_FEATURE_BITMAP_FILTER_FS 0x00000040
+#define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | AUDIT_FEATURE_BITMAP_LOST_RESET | AUDIT_FEATURE_BITMAP_FILTER_FS)
 #define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL
 #define AUDIT_VERSION_BACKLOG_LIMIT AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT
 #define AUDIT_VERSION_BACKLOG_WAIT_TIME AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME
diff --git a/libc/kernel/uapi/linux/bcache.h b/libc/kernel/uapi/linux/bcache.h
index 0933d51..4c7e32a 100644
--- a/libc/kernel/uapi/linux/bcache.h
+++ b/libc/kernel/uapi/linux/bcache.h
@@ -46,7 +46,7 @@
 #define START_KEY(k) KEY(KEY_INODE(k), KEY_START(k), 0)
 #define PTR_DEV_BITS 12
 #define PTR_CHECK_DEV ((1 << PTR_DEV_BITS) - 1)
-#define PTR(gen,offset,dev) ((((__u64) dev) << 51) | ((__u64) offset) << 8 | gen)
+#define MAKE_PTR(gen,offset,dev) ((((__u64) dev) << 51) | ((__u64) offset) << 8 | gen)
 #define bkey_copy(_dest,_src) memcpy(_dest, _src, bkey_bytes(_src))
 #define BKEY_PAD 8
 #define BKEY_PADDED(key) union { struct bkey key; __u64 key ##_pad[BKEY_PAD]; }
diff --git a/libc/kernel/uapi/linux/bfs_fs.h b/libc/kernel/uapi/linux/bfs_fs.h
index e828ce3..4a11e8a 100644
--- a/libc/kernel/uapi/linux/bfs_fs.h
+++ b/libc/kernel/uapi/linux/bfs_fs.h
@@ -66,5 +66,5 @@
 #define BFS_NZFILESIZE(ip) ((le32_to_cpu((ip)->i_eoffset) + 1) - le32_to_cpu((ip)->i_sblock) * BFS_BSIZE)
 #define BFS_FILESIZE(ip) ((ip)->i_sblock == 0 ? 0 : BFS_NZFILESIZE(ip))
 #define BFS_FILEBLOCKS(ip) ((ip)->i_sblock == 0 ? 0 : (le32_to_cpu((ip)->i_eblock) + 1) - le32_to_cpu((ip)->i_sblock))
-#define BFS_UNCLEAN(bfs_sb,sb) ((le32_to_cpu(bfs_sb->s_from) != - 1) && (le32_to_cpu(bfs_sb->s_to) != - 1) && ! (sb->s_flags & MS_RDONLY))
+#define BFS_UNCLEAN(bfs_sb,sb) ((le32_to_cpu(bfs_sb->s_from) != - 1) && (le32_to_cpu(bfs_sb->s_to) != - 1) && ! (sb->s_flags & SB_RDONLY))
 #endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 1dfb99f..9ac0729 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -82,6 +82,7 @@
   BPF_PROG_GET_FD_BY_ID,
   BPF_MAP_GET_FD_BY_ID,
   BPF_OBJ_GET_INFO_BY_FD,
+  BPF_PROG_QUERY,
 };
 enum bpf_map_type {
   BPF_MAP_TYPE_UNSPEC,
@@ -100,6 +101,7 @@
   BPF_MAP_TYPE_HASH_OF_MAPS,
   BPF_MAP_TYPE_DEVMAP,
   BPF_MAP_TYPE_SOCKMAP,
+  BPF_MAP_TYPE_CPUMAP,
 };
 enum bpf_prog_type {
   BPF_PROG_TYPE_UNSPEC,
@@ -117,6 +119,7 @@
   BPF_PROG_TYPE_LWT_XMIT,
   BPF_PROG_TYPE_SOCK_OPS,
   BPF_PROG_TYPE_SK_SKB,
+  BPF_PROG_TYPE_CGROUP_DEVICE,
 };
 enum bpf_attach_type {
   BPF_CGROUP_INET_INGRESS,
@@ -125,10 +128,12 @@
   BPF_CGROUP_SOCK_OPS,
   BPF_SK_SKB_STREAM_PARSER,
   BPF_SK_SKB_STREAM_VERDICT,
+  BPF_CGROUP_DEVICE,
   __MAX_BPF_ATTACH_TYPE
 };
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
+#define BPF_F_ALLOW_MULTI (1U << 1)
 #define BPF_F_STRICT_ALIGNMENT (1U << 0)
 #define BPF_PSEUDO_MAP_FD 1
 #define BPF_ANY 0
@@ -137,6 +142,10 @@
 #define BPF_F_NO_PREALLOC (1U << 0)
 #define BPF_F_NO_COMMON_LRU (1U << 1)
 #define BPF_F_NUMA_NODE (1U << 2)
+#define BPF_F_QUERY_EFFECTIVE (1U << 0)
+#define BPF_OBJ_NAME_LEN 16U
+#define BPF_F_RDONLY (1U << 3)
+#define BPF_F_WRONLY (1U << 4)
 union bpf_attr {
   struct {
     __u32 map_type;
@@ -146,6 +155,7 @@
     __u32 map_flags;
     __u32 inner_map_fd;
     __u32 numa_node;
+    char map_name[BPF_OBJ_NAME_LEN];
   };
   struct {
     __u32 map_fd;
@@ -166,10 +176,13 @@
     __aligned_u64 log_buf;
     __u32 kern_version;
     __u32 prog_flags;
+    char prog_name[BPF_OBJ_NAME_LEN];
+    __u32 prog_ifindex;
   };
   struct {
     __aligned_u64 pathname;
     __u32 bpf_fd;
+    __u32 file_flags;
   };
   struct {
     __u32 target_fd;
@@ -194,14 +207,23 @@
       __u32 map_id;
     };
     __u32 next_id;
+    __u32 open_flags;
   };
   struct {
     __u32 bpf_fd;
     __u32 info_len;
     __aligned_u64 info;
   } info;
+  struct {
+    __u32 target_fd;
+    __u32 attach_type;
+    __u32 query_flags;
+    __u32 attach_flags;
+    __aligned_u64 prog_ids;
+    __u32 prog_cnt;
+  } query;
 } __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),
+#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),
 #define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
 enum bpf_func_id {
   __BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -253,6 +275,7 @@
   __u32 local_ip6[4];
   __u32 remote_port;
   __u32 local_port;
+  __u32 data_meta;
 };
 struct bpf_tunnel_key {
   __u32 tunnel_id;
@@ -289,6 +312,7 @@
 struct xdp_md {
   __u32 data;
   __u32 data_end;
+  __u32 data_meta;
 };
 enum sk_action {
   SK_DROP = 0,
@@ -303,6 +327,11 @@
   __u32 xlated_prog_len;
   __aligned_u64 jited_prog_insns;
   __aligned_u64 xlated_prog_insns;
+  __u64 load_time;
+  __u32 created_by_uid;
+  __u32 nr_map_ids;
+  __aligned_u64 map_ids;
+  char name[BPF_OBJ_NAME_LEN];
 } __attribute__((aligned(8)));
 struct bpf_map_info {
   __u32 type;
@@ -311,6 +340,7 @@
   __u32 value_size;
   __u32 max_entries;
   __u32 map_flags;
+  char name[BPF_OBJ_NAME_LEN];
 } __attribute__((aligned(8)));
 struct bpf_sock_ops {
   __u32 op;
@@ -334,7 +364,23 @@
   BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
   BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
   BPF_SOCK_OPS_NEEDS_ECN,
+  BPF_SOCK_OPS_BASE_RTT,
 };
 #define TCP_BPF_IW 1001
 #define 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)
+struct bpf_cgroup_dev_ctx {
+  __u32 access_type;
+  __u32 major;
+  __u32 minor;
+};
 #endif
diff --git a/libc/kernel/uapi/linux/bpf_perf_event.h b/libc/kernel/uapi/linux/bpf_perf_event.h
index ef7bd18..7a8d212 100644
--- a/libc/kernel/uapi/linux/bpf_perf_event.h
+++ b/libc/kernel/uapi/linux/bpf_perf_event.h
@@ -18,10 +18,9 @@
  ****************************************************************************/
 #ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__
 #define _UAPI__LINUX_BPF_PERF_EVENT_H__
-#include <linux/types.h>
-#include <linux/ptrace.h>
+#include <asm/bpf_perf_event.h>
 struct bpf_perf_event_data {
-  struct pt_regs regs;
+  bpf_user_pt_regs_t regs;
   __u64 sample_period;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index a23ab58..aa7c105 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -339,9 +339,11 @@
 struct btrfs_ioctl_logical_ino_args {
   __u64 logical;
   __u64 size;
-  __u64 reserved[4];
+  __u64 reserved[3];
+  __u64 flags;
   __u64 inodes;
 };
+#define BTRFS_LOGICAL_INO_ARGS_IGNORE_OFFSET (1ULL << 0)
 enum btrfs_dev_stat_values {
   BTRFS_DEV_STAT_WRITE_ERRS,
   BTRFS_DEV_STAT_READ_ERRS,
@@ -469,4 +471,5 @@
 #define BTRFS_IOC_SET_FEATURES _IOW(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[2])
 #define BTRFS_IOC_GET_SUPPORTED_FEATURES _IOR(BTRFS_IOCTL_MAGIC, 57, struct btrfs_ioctl_feature_flags[3])
 #define BTRFS_IOC_RM_DEV_V2 _IOW(BTRFS_IOCTL_MAGIC, 58, struct btrfs_ioctl_vol_args_v2)
+#define BTRFS_IOC_LOGICAL_INO_V2 _IOWR(BTRFS_IOCTL_MAGIC, 59, struct btrfs_ioctl_logical_ino_args)
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs_tree.h b/libc/kernel/uapi/linux/btrfs_tree.h
index c75732e..c2fbd40 100644
--- a/libc/kernel/uapi/linux/btrfs_tree.h
+++ b/libc/kernel/uapi/linux/btrfs_tree.h
@@ -320,6 +320,7 @@
 #define BTRFS_FILE_EXTENT_INLINE 0
 #define BTRFS_FILE_EXTENT_REG 1
 #define BTRFS_FILE_EXTENT_PREALLOC 2
+#define BTRFS_FILE_EXTENT_TYPES 2
 struct btrfs_file_extent_item {
   __le64 generation;
   __le64 ram_bytes;
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 3fcee96..98892f7 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -130,6 +130,8 @@
 #define CEC_EVENT_LOST_MSGS 2
 #define CEC_EVENT_PIN_CEC_LOW 3
 #define CEC_EVENT_PIN_CEC_HIGH 4
+#define CEC_EVENT_PIN_HPD_LOW 5
+#define CEC_EVENT_PIN_HPD_HIGH 6
 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0)
 #define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1)
 struct cec_event_state_change {
diff --git a/libc/kernel/uapi/linux/cramfs_fs.h b/libc/kernel/uapi/linux/cramfs_fs.h
index 5d119ba..8872914 100644
--- a/libc/kernel/uapi/linux/cramfs_fs.h
+++ b/libc/kernel/uapi/linux/cramfs_fs.h
@@ -54,5 +54,10 @@
 #define CRAMFS_FLAG_HOLES 0x00000100
 #define CRAMFS_FLAG_WRONG_SIGNATURE 0x00000200
 #define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET 0x00000400
-#define CRAMFS_SUPPORTED_FLAGS (0x000000ff | CRAMFS_FLAG_HOLES | CRAMFS_FLAG_WRONG_SIGNATURE | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET)
+#define CRAMFS_FLAG_EXT_BLOCK_POINTERS 0x00000800
+#define CRAMFS_SUPPORTED_FLAGS (0x000000ff | CRAMFS_FLAG_HOLES | CRAMFS_FLAG_WRONG_SIGNATURE | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET | CRAMFS_FLAG_EXT_BLOCK_POINTERS)
+#define CRAMFS_BLK_FLAG_UNCOMPRESSED (1 << 31)
+#define CRAMFS_BLK_FLAG_DIRECT_PTR (1 << 30)
+#define CRAMFS_BLK_FLAGS (CRAMFS_BLK_FLAG_UNCOMPRESSED | CRAMFS_BLK_FLAG_DIRECT_PTR)
+#define CRAMFS_BLK_DIRECT_PTR_SHIFT 2
 #endif
diff --git a/libc/kernel/uapi/linux/dcbnl.h b/libc/kernel/uapi/linux/dcbnl.h
index 569efdd..2fe4cce 100644
--- a/libc/kernel/uapi/linux/dcbnl.h
+++ b/libc/kernel/uapi/linux/dcbnl.h
@@ -91,6 +91,7 @@
 #define IEEE_8021QAZ_APP_SEL_STREAM 2
 #define IEEE_8021QAZ_APP_SEL_DGRAM 3
 #define IEEE_8021QAZ_APP_SEL_ANY 4
+#define IEEE_8021QAZ_APP_SEL_DSCP 5
 struct dcb_app {
   __u8 selector;
   __u8 priority;
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index 8aa1011..bf35f6c 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -347,11 +347,13 @@
 #define NT_S390_VXRS_HIGH 0x30a
 #define NT_S390_GS_CB 0x30b
 #define NT_S390_GS_BC 0x30c
+#define NT_S390_RI_CB 0x30d
 #define NT_ARM_VFP 0x400
 #define NT_ARM_TLS 0x401
 #define NT_ARM_HW_BREAK 0x402
 #define NT_ARM_HW_WATCH 0x403
 #define NT_ARM_SYSTEM_CALL 0x404
+#define NT_ARM_SVE 0x405
 #define NT_METAG_CBUF 0x500
 #define NT_METAG_RPIPE 0x501
 #define NT_METAG_TLS 0x502
diff --git a/libc/kernel/uapi/linux/fanotify.h b/libc/kernel/uapi/linux/fanotify.h
index b10106e..73d92ca 100644
--- a/libc/kernel/uapi/linux/fanotify.h
+++ b/libc/kernel/uapi/linux/fanotify.h
@@ -38,6 +38,7 @@
 #define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)
 #define FAN_UNLIMITED_QUEUE 0x00000010
 #define FAN_UNLIMITED_MARKS 0x00000020
+#define FAN_ENABLE_AUDIT 0x00000040
 #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
 #define FAN_MARK_ADD 0x00000001
 #define FAN_MARK_REMOVE 0x00000002
@@ -67,6 +68,7 @@
 };
 #define FAN_ALLOW 0x01
 #define FAN_DENY 0x02
+#define FAN_AUDIT 0x10
 #define FAN_NOFD - 1
 #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
 #define FAN_EVENT_NEXT(meta,len) ((len) -= (meta)->event_len, (struct fanotify_event_metadata *) (((char *) (meta)) + (meta)->event_len))
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index f40321e..04b6dae 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -19,6 +19,7 @@
 #ifndef _UAPI_LINUX_IF_ETHER_H
 #define _UAPI_LINUX_IF_ETHER_H
 #include <linux/types.h>
+#include <linux/libc-compat.h>
 #define ETH_ALEN 6
 #define ETH_HLEN 14
 #define ETH_ZLEN 60
@@ -116,9 +117,11 @@
 #define ETH_P_CAIF 0x00F7
 #define ETH_P_XDSA 0x00F8
 #define ETH_P_MAP 0x00F9
+#if __UAPI_DEF_ETHHDR
 struct ethhdr {
   unsigned char h_dest[ETH_ALEN];
   unsigned char h_source[ETH_ALEN];
   __be16 h_proto;
 } __attribute__((packed));
 #endif
+#endif
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index c041c82..a43eaf7 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -136,6 +136,8 @@
   IFLA_PAD,
   IFLA_XDP,
   IFLA_EVENT,
+  IFLA_NEW_NETNSID,
+  IFLA_IF_NETNSID,
   __IFLA_MAX
 };
 #define IFLA_MAX (__IFLA_MAX - 1)
@@ -255,6 +257,8 @@
   IFLA_BRPORT_MCAST_TO_UCAST,
   IFLA_BRPORT_VLAN_TUNNEL,
   IFLA_BRPORT_BCAST_FLOOD,
+  IFLA_BRPORT_GROUP_FWD_MASK,
+  IFLA_BRPORT_NEIGH_SUPPRESS,
   __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -364,6 +368,7 @@
 enum {
   IFLA_IPVLAN_UNSPEC,
   IFLA_IPVLAN_MODE,
+  IFLA_IPVLAN_FLAGS,
   __IFLA_IPVLAN_MAX
 };
 #define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
@@ -373,6 +378,8 @@
   IPVLAN_MODE_L3S,
   IPVLAN_MODE_MAX
 };
+#define IPVLAN_F_PRIVATE 0x01
+#define IPVLAN_F_VEPA 0x02
 enum {
   IFLA_VXLAN_UNSPEC,
   IFLA_VXLAN_ID,
diff --git a/libc/kernel/uapi/linux/if_tun.h b/libc/kernel/uapi/linux/if_tun.h
index 4912d7b..d8757a1 100644
--- a/libc/kernel/uapi/linux/if_tun.h
+++ b/libc/kernel/uapi/linux/if_tun.h
@@ -51,6 +51,8 @@
 #define TUNGETVNETBE _IOR('T', 223, int)
 #define IFF_TUN 0x0001
 #define IFF_TAP 0x0002
+#define IFF_NAPI 0x0010
+#define IFF_NAPI_FRAGS 0x0020
 #define IFF_NO_PI 0x1000
 #define IFF_ONE_QUEUE 0x2000
 #define IFF_VNET_HDR 0x4000
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index bfc6479..8edc956 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -93,6 +93,7 @@
   TUNNEL_ENCAP_NONE,
   TUNNEL_ENCAP_FOU,
   TUNNEL_ENCAP_GUE,
+  TUNNEL_ENCAP_MPLS,
 };
 #define TUNNEL_ENCAP_FLAG_CSUM (1 << 0)
 #define TUNNEL_ENCAP_FLAG_CSUM6 (1 << 1)
diff --git a/libc/kernel/uapi/linux/ila.h b/libc/kernel/uapi/linux/ila.h
index 38386be..a5af23a 100644
--- a/libc/kernel/uapi/linux/ila.h
+++ b/libc/kernel/uapi/linux/ila.h
@@ -29,6 +29,8 @@
   ILA_ATTR_DIR,
   ILA_ATTR_PAD,
   ILA_ATTR_CSUM_MODE,
+  ILA_ATTR_IDENT_TYPE,
+  ILA_ATTR_HOOK_TYPE,
   __ILA_ATTR_MAX,
 };
 #define ILA_ATTR_MAX (__ILA_ATTR_MAX - 1)
@@ -46,5 +48,21 @@
   ILA_CSUM_ADJUST_TRANSPORT,
   ILA_CSUM_NEUTRAL_MAP,
   ILA_CSUM_NO_ACTION,
+  ILA_CSUM_NEUTRAL_MAP_AUTO,
+};
+enum {
+  ILA_ATYPE_IID = 0,
+  ILA_ATYPE_LUID,
+  ILA_ATYPE_VIRT_V4,
+  ILA_ATYPE_VIRT_UNI_V6,
+  ILA_ATYPE_VIRT_MULTI_V6,
+  ILA_ATYPE_NONLOCAL_ADDR,
+  ILA_ATYPE_RSVD_1,
+  ILA_ATYPE_RSVD_2,
+  ILA_ATYPE_USE_FORMAT = 32,
+};
+enum {
+  ILA_HOOK_ROUTE_OUTPUT,
+  ILA_HOOK_ROUTE_INPUT,
 };
 #endif
diff --git a/libc/kernel/uapi/linux/in6.h b/libc/kernel/uapi/linux/in6.h
index 1e3b49d..9da111c 100644
--- a/libc/kernel/uapi/linux/in6.h
+++ b/libc/kernel/uapi/linux/in6.h
@@ -175,4 +175,5 @@
 #define IPV6_TRANSPARENT 75
 #define IPV6_UNICAST_IF 76
 #define IPV6_RECVFRAGSIZE 77
+#define IPV6_FREEBIND 78
 #endif
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 346ec91..da90f1c 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -359,6 +359,7 @@
 #define BTN_TOOL_MOUSE 0x146
 #define BTN_TOOL_LENS 0x147
 #define BTN_TOOL_QUINTTAP 0x148
+#define BTN_STYLUS3 0x149
 #define BTN_TOUCH 0x14a
 #define BTN_STYLUS 0x14b
 #define BTN_STYLUS2 0x14c
diff --git a/libc/kernel/uapi/linux/ip6_tunnel.h b/libc/kernel/uapi/linux/ip6_tunnel.h
index b7df956..ba59235 100644
--- a/libc/kernel/uapi/linux/ip6_tunnel.h
+++ b/libc/kernel/uapi/linux/ip6_tunnel.h
@@ -29,6 +29,7 @@
 #define IP6_TNL_F_MIP6_DEV 0x8
 #define IP6_TNL_F_RCV_DSCP_COPY 0x10
 #define IP6_TNL_F_USE_ORIG_FWMARK 0x20
+#define IP6_TNL_F_ALLOW_LOCAL_REMOTE 0x40
 struct ip6_tnl_parm {
   char name[IFNAMSIZ];
   int link;
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index d07fa06..ff345a6 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -140,6 +140,7 @@
   DEVCONF_ADDR_GEN_MODE,
   DEVCONF_DISABLE_POLICY,
   DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
+  DEVCONF_NDISC_TCLASS,
   DEVCONF_MAX
 };
 #endif
diff --git a/libc/kernel/uapi/linux/iso_fs.h b/libc/kernel/uapi/linux/iso_fs.h
index d88d646..8227031 100644
--- a/libc/kernel/uapi/linux/iso_fs.h
+++ b/libc/kernel/uapi/linux/iso_fs.h
@@ -22,34 +22,34 @@
 #include <linux/magic.h>
 #define ISODCL(from,to) (to - from + 1)
 struct iso_volume_descriptor {
-  char type[ISODCL(1, 1)];
+  __u8 type[ISODCL(1, 1)];
   char id[ISODCL(2, 6)];
-  char version[ISODCL(7, 7)];
-  char data[ISODCL(8, 2048)];
+  __u8 version[ISODCL(7, 7)];
+  __u8 data[ISODCL(8, 2048)];
 };
 #define ISO_VD_PRIMARY 1
 #define ISO_VD_SUPPLEMENTARY 2
 #define ISO_VD_END 255
 #define ISO_STANDARD_ID "CD001"
 struct iso_primary_descriptor {
-  char type[ISODCL(1, 1)];
+  __u8 type[ISODCL(1, 1)];
   char id[ISODCL(2, 6)];
-  char version[ISODCL(7, 7)];
-  char unused1[ISODCL(8, 8)];
+  __u8 version[ISODCL(7, 7)];
+  __u8 unused1[ISODCL(8, 8)];
   char system_id[ISODCL(9, 40)];
   char volume_id[ISODCL(41, 72)];
-  char unused2[ISODCL(73, 80)];
-  char volume_space_size[ISODCL(81, 88)];
-  char unused3[ISODCL(89, 120)];
-  char volume_set_size[ISODCL(121, 124)];
-  char volume_sequence_number[ISODCL(125, 128)];
-  char logical_block_size[ISODCL(129, 132)];
-  char path_table_size[ISODCL(133, 140)];
-  char type_l_path_table[ISODCL(141, 144)];
-  char opt_type_l_path_table[ISODCL(145, 148)];
-  char type_m_path_table[ISODCL(149, 152)];
-  char opt_type_m_path_table[ISODCL(153, 156)];
-  char root_directory_record[ISODCL(157, 190)];
+  __u8 unused2[ISODCL(73, 80)];
+  __u8 volume_space_size[ISODCL(81, 88)];
+  __u8 unused3[ISODCL(89, 120)];
+  __u8 volume_set_size[ISODCL(121, 124)];
+  __u8 volume_sequence_number[ISODCL(125, 128)];
+  __u8 logical_block_size[ISODCL(129, 132)];
+  __u8 path_table_size[ISODCL(133, 140)];
+  __u8 type_l_path_table[ISODCL(141, 144)];
+  __u8 opt_type_l_path_table[ISODCL(145, 148)];
+  __u8 type_m_path_table[ISODCL(149, 152)];
+  __u8 opt_type_m_path_table[ISODCL(153, 156)];
+  __u8 root_directory_record[ISODCL(157, 190)];
   char volume_set_id[ISODCL(191, 318)];
   char publisher_id[ISODCL(319, 446)];
   char preparer_id[ISODCL(447, 574)];
@@ -57,34 +57,34 @@
   char copyright_file_id[ISODCL(703, 739)];
   char abstract_file_id[ISODCL(740, 776)];
   char bibliographic_file_id[ISODCL(777, 813)];
-  char creation_date[ISODCL(814, 830)];
-  char modification_date[ISODCL(831, 847)];
-  char expiration_date[ISODCL(848, 864)];
-  char effective_date[ISODCL(865, 881)];
-  char file_structure_version[ISODCL(882, 882)];
-  char unused4[ISODCL(883, 883)];
-  char application_data[ISODCL(884, 1395)];
-  char unused5[ISODCL(1396, 2048)];
+  __u8 creation_date[ISODCL(814, 830)];
+  __u8 modification_date[ISODCL(831, 847)];
+  __u8 expiration_date[ISODCL(848, 864)];
+  __u8 effective_date[ISODCL(865, 881)];
+  __u8 file_structure_version[ISODCL(882, 882)];
+  __u8 unused4[ISODCL(883, 883)];
+  __u8 application_data[ISODCL(884, 1395)];
+  __u8 unused5[ISODCL(1396, 2048)];
 };
 struct iso_supplementary_descriptor {
-  char type[ISODCL(1, 1)];
+  __u8 type[ISODCL(1, 1)];
   char id[ISODCL(2, 6)];
-  char version[ISODCL(7, 7)];
-  char flags[ISODCL(8, 8)];
+  __u8 version[ISODCL(7, 7)];
+  __u8 flags[ISODCL(8, 8)];
   char system_id[ISODCL(9, 40)];
   char volume_id[ISODCL(41, 72)];
-  char unused2[ISODCL(73, 80)];
-  char volume_space_size[ISODCL(81, 88)];
-  char escape[ISODCL(89, 120)];
-  char volume_set_size[ISODCL(121, 124)];
-  char volume_sequence_number[ISODCL(125, 128)];
-  char logical_block_size[ISODCL(129, 132)];
-  char path_table_size[ISODCL(133, 140)];
-  char type_l_path_table[ISODCL(141, 144)];
-  char opt_type_l_path_table[ISODCL(145, 148)];
-  char type_m_path_table[ISODCL(149, 152)];
-  char opt_type_m_path_table[ISODCL(153, 156)];
-  char root_directory_record[ISODCL(157, 190)];
+  __u8 unused2[ISODCL(73, 80)];
+  __u8 volume_space_size[ISODCL(81, 88)];
+  __u8 escape[ISODCL(89, 120)];
+  __u8 volume_set_size[ISODCL(121, 124)];
+  __u8 volume_sequence_number[ISODCL(125, 128)];
+  __u8 logical_block_size[ISODCL(129, 132)];
+  __u8 path_table_size[ISODCL(133, 140)];
+  __u8 type_l_path_table[ISODCL(141, 144)];
+  __u8 opt_type_l_path_table[ISODCL(145, 148)];
+  __u8 type_m_path_table[ISODCL(149, 152)];
+  __u8 opt_type_m_path_table[ISODCL(153, 156)];
+  __u8 root_directory_record[ISODCL(157, 190)];
   char volume_set_id[ISODCL(191, 318)];
   char publisher_id[ISODCL(319, 446)];
   char preparer_id[ISODCL(447, 574)];
@@ -92,59 +92,59 @@
   char copyright_file_id[ISODCL(703, 739)];
   char abstract_file_id[ISODCL(740, 776)];
   char bibliographic_file_id[ISODCL(777, 813)];
-  char creation_date[ISODCL(814, 830)];
-  char modification_date[ISODCL(831, 847)];
-  char expiration_date[ISODCL(848, 864)];
-  char effective_date[ISODCL(865, 881)];
-  char file_structure_version[ISODCL(882, 882)];
-  char unused4[ISODCL(883, 883)];
-  char application_data[ISODCL(884, 1395)];
-  char unused5[ISODCL(1396, 2048)];
+  __u8 creation_date[ISODCL(814, 830)];
+  __u8 modification_date[ISODCL(831, 847)];
+  __u8 expiration_date[ISODCL(848, 864)];
+  __u8 effective_date[ISODCL(865, 881)];
+  __u8 file_structure_version[ISODCL(882, 882)];
+  __u8 unused4[ISODCL(883, 883)];
+  __u8 application_data[ISODCL(884, 1395)];
+  __u8 unused5[ISODCL(1396, 2048)];
 };
 #define HS_STANDARD_ID "CDROM"
 struct hs_volume_descriptor {
-  char foo[ISODCL(1, 8)];
-  char type[ISODCL(9, 9)];
+  __u8 foo[ISODCL(1, 8)];
+  __u8 type[ISODCL(9, 9)];
   char id[ISODCL(10, 14)];
-  char version[ISODCL(15, 15)];
-  char data[ISODCL(16, 2048)];
+  __u8 version[ISODCL(15, 15)];
+  __u8 data[ISODCL(16, 2048)];
 };
 struct hs_primary_descriptor {
-  char foo[ISODCL(1, 8)];
-  char type[ISODCL(9, 9)];
-  char id[ISODCL(10, 14)];
-  char version[ISODCL(15, 15)];
-  char unused1[ISODCL(16, 16)];
+  __u8 foo[ISODCL(1, 8)];
+  __u8 type[ISODCL(9, 9)];
+  __u8 id[ISODCL(10, 14)];
+  __u8 version[ISODCL(15, 15)];
+  __u8 unused1[ISODCL(16, 16)];
   char system_id[ISODCL(17, 48)];
   char volume_id[ISODCL(49, 80)];
-  char unused2[ISODCL(81, 88)];
-  char volume_space_size[ISODCL(89, 96)];
-  char unused3[ISODCL(97, 128)];
-  char volume_set_size[ISODCL(129, 132)];
-  char volume_sequence_number[ISODCL(133, 136)];
-  char logical_block_size[ISODCL(137, 140)];
-  char path_table_size[ISODCL(141, 148)];
-  char type_l_path_table[ISODCL(149, 152)];
-  char unused4[ISODCL(153, 180)];
-  char root_directory_record[ISODCL(181, 214)];
+  __u8 unused2[ISODCL(81, 88)];
+  __u8 volume_space_size[ISODCL(89, 96)];
+  __u8 unused3[ISODCL(97, 128)];
+  __u8 volume_set_size[ISODCL(129, 132)];
+  __u8 volume_sequence_number[ISODCL(133, 136)];
+  __u8 logical_block_size[ISODCL(137, 140)];
+  __u8 path_table_size[ISODCL(141, 148)];
+  __u8 type_l_path_table[ISODCL(149, 152)];
+  __u8 unused4[ISODCL(153, 180)];
+  __u8 root_directory_record[ISODCL(181, 214)];
 };
 struct iso_path_table {
-  unsigned char name_len[2];
-  char extent[4];
-  char parent[2];
+  __u8 name_len[2];
+  __u8 extent[4];
+  __u8 parent[2];
   char name[0];
 } __attribute__((packed));
 struct iso_directory_record {
-  char length[ISODCL(1, 1)];
-  char ext_attr_length[ISODCL(2, 2)];
-  char extent[ISODCL(3, 10)];
-  char size[ISODCL(11, 18)];
-  char date[ISODCL(19, 25)];
-  char flags[ISODCL(26, 26)];
-  char file_unit_size[ISODCL(27, 27)];
-  char interleave[ISODCL(28, 28)];
-  char volume_sequence_number[ISODCL(29, 32)];
-  unsigned char name_len[ISODCL(33, 33)];
+  __u8 length[ISODCL(1, 1)];
+  __u8 ext_attr_length[ISODCL(2, 2)];
+  __u8 extent[ISODCL(3, 10)];
+  __u8 size[ISODCL(11, 18)];
+  __u8 date[ISODCL(19, 25)];
+  __u8 flags[ISODCL(26, 26)];
+  __u8 file_unit_size[ISODCL(27, 27)];
+  __u8 interleave[ISODCL(28, 28)];
+  __u8 volume_sequence_number[ISODCL(29, 32)];
+  __u8 name_len[ISODCL(33, 33)];
   char name[0];
 } __attribute__((packed));
 #define ISOFS_BLOCK_BITS 11
diff --git a/libc/kernel/uapi/linux/kcov.h b/libc/kernel/uapi/linux/kcov.h
index 9688c38..40f9912 100644
--- a/libc/kernel/uapi/linux/kcov.h
+++ b/libc/kernel/uapi/linux/kcov.h
@@ -22,4 +22,11 @@
 #define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
 #define KCOV_ENABLE _IO('c', 100)
 #define KCOV_DISABLE _IO('c', 101)
+enum {
+  KCOV_TRACE_PC = 0,
+  KCOV_TRACE_CMP = 1,
+};
+#define KCOV_CMP_CONST (1 << 0)
+#define KCOV_CMP_SIZE(n) ((n) << 1)
+#define KCOV_CMP_MASK KCOV_CMP_SIZE(3)
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index f870cd6..d4582a1 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -125,7 +125,7 @@
 #define KFD_IOC_WAIT_RESULT_COMPLETE 0
 #define KFD_IOC_WAIT_RESULT_TIMEOUT 1
 #define KFD_IOC_WAIT_RESULT_FAIL 2
-#define KFD_SIGNAL_EVENT_LIMIT 256
+#define KFD_SIGNAL_EVENT_LIMIT 4096
 struct kfd_ioctl_create_event_args {
   __u64 event_page_offset;
   __u32 event_trigger_data;
@@ -175,19 +175,19 @@
   __u32 wait_result;
 };
 struct kfd_ioctl_set_scratch_backing_va_args {
-  uint64_t va_addr;
-  uint32_t gpu_id;
-  uint32_t pad;
+  __u64 va_addr;
+  __u32 gpu_id;
+  __u32 pad;
 };
 struct kfd_ioctl_get_tile_config_args {
-  uint64_t tile_config_ptr;
-  uint64_t macro_tile_config_ptr;
-  uint32_t num_tile_configs;
-  uint32_t num_macro_tile_configs;
-  uint32_t gpu_id;
-  uint32_t gb_addr_config;
-  uint32_t num_banks;
-  uint32_t num_ranks;
+  __u64 tile_config_ptr;
+  __u64 macro_tile_config_ptr;
+  __u32 num_tile_configs;
+  __u32 num_macro_tile_configs;
+  __u32 gpu_id;
+  __u32 gb_addr_config;
+  __u32 num_banks;
+  __u32 num_ranks;
 };
 #define AMDKFD_IOCTL_BASE 'K'
 #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 6bd4701..d04832a 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -728,6 +728,9 @@
 #define KVM_CAP_PPC_SMT_POSSIBLE 147
 #define KVM_CAP_HYPERV_SYNIC2 148
 #define KVM_CAP_HYPERV_VP_INDEX 149
+#define KVM_CAP_S390_AIS_MIGRATION 150
+#define KVM_CAP_PPC_GET_CPU_CHAR 151
+#define KVM_CAP_S390_BPB 152
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -966,6 +969,7 @@
 #define KVM_PPC_RESIZE_HPT_COMMIT _IOR(KVMIO, 0xae, struct kvm_ppc_resize_hpt)
 #define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)
 #define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)
+#define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)
 #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
 #define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr)
 #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr)
diff --git a/libc/kernel/uapi/linux/libc-compat.h b/libc/kernel/uapi/linux/libc-compat.h
index e5a2b03..c9a8b74 100644
--- a/libc/kernel/uapi/linux/libc-compat.h
+++ b/libc/kernel/uapi/linux/libc-compat.h
@@ -90,31 +90,86 @@
 #define __UAPI_DEF_XATTR 1
 #endif
 #else
+#ifndef __UAPI_DEF_IF_IFCONF
 #define __UAPI_DEF_IF_IFCONF 1
+#endif
+#ifndef __UAPI_DEF_IF_IFMAP
 #define __UAPI_DEF_IF_IFMAP 1
+#endif
+#ifndef __UAPI_DEF_IF_IFNAMSIZ
 #define __UAPI_DEF_IF_IFNAMSIZ 1
+#endif
+#ifndef __UAPI_DEF_IF_IFREQ
 #define __UAPI_DEF_IF_IFREQ 1
+#endif
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS
 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1
+#endif
+#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO
 #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1
+#endif
+#ifndef __UAPI_DEF_IN_ADDR
 #define __UAPI_DEF_IN_ADDR 1
+#endif
+#ifndef __UAPI_DEF_IN_IPPROTO
 #define __UAPI_DEF_IN_IPPROTO 1
+#endif
+#ifndef __UAPI_DEF_IN_PKTINFO
 #define __UAPI_DEF_IN_PKTINFO 1
+#endif
+#ifndef __UAPI_DEF_IP_MREQ
 #define __UAPI_DEF_IP_MREQ 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IN
 #define __UAPI_DEF_SOCKADDR_IN 1
+#endif
+#ifndef __UAPI_DEF_IN_CLASS
 #define __UAPI_DEF_IN_CLASS 1
+#endif
+#ifndef __UAPI_DEF_IN6_ADDR
 #define __UAPI_DEF_IN6_ADDR 1
+#endif
+#ifndef __UAPI_DEF_IN6_ADDR_ALT
 #define __UAPI_DEF_IN6_ADDR_ALT 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IN6
 #define __UAPI_DEF_SOCKADDR_IN6 1
+#endif
+#ifndef __UAPI_DEF_IPV6_MREQ
 #define __UAPI_DEF_IPV6_MREQ 1
+#endif
+#ifndef __UAPI_DEF_IPPROTO_V6
 #define __UAPI_DEF_IPPROTO_V6 1
+#endif
+#ifndef __UAPI_DEF_IPV6_OPTIONS
 #define __UAPI_DEF_IPV6_OPTIONS 1
+#endif
+#ifndef __UAPI_DEF_IN6_PKTINFO
 #define __UAPI_DEF_IN6_PKTINFO 1
+#endif
+#ifndef __UAPI_DEF_IP6_MTUINFO
 #define __UAPI_DEF_IP6_MTUINFO 1
+#endif
+#ifndef __UAPI_DEF_SOCKADDR_IPX
 #define __UAPI_DEF_SOCKADDR_IPX 1
+#endif
+#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION
 #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1
+#endif
+#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION
 #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1
+#endif
+#ifndef __UAPI_DEF_IPX_CONFIG_DATA
 #define __UAPI_DEF_IPX_CONFIG_DATA 1
+#endif
+#ifndef __UAPI_DEF_IPX_ROUTE_DEF
 #define __UAPI_DEF_IPX_ROUTE_DEF 1
+#endif
+#ifndef __UAPI_DEF_XATTR
 #define __UAPI_DEF_XATTR 1
 #endif
 #endif
+#ifndef __UAPI_DEF_ETHHDR
+#define __UAPI_DEF_ETHHDR 1
+#endif
+#endif
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index 6e0ddf7..68b4c65 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -61,6 +61,7 @@
 #define OPENPROM_SUPER_MAGIC 0x9fa1
 #define QNX4_SUPER_MAGIC 0x002f
 #define QNX6_SUPER_MAGIC 0x68191122
+#define AFS_FS_MAGIC 0x6B414653
 #define REISERFS_SUPER_MAGIC 0x52654973
 #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
diff --git a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
index 5192a54..0d35c15 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_conntrack_common.h
@@ -30,7 +30,7 @@
 };
 #define NF_CT_STATE_INVALID_BIT (1 << 0)
 #define NF_CT_STATE_BIT(ctinfo) (1 << ((ctinfo) % IP_CT_IS_REPLY + 1))
-#define NF_CT_STATE_UNTRACKED_BIT (1 << (IP_CT_UNTRACKED + 1))
+#define NF_CT_STATE_UNTRACKED_BIT (1 << 6)
 enum ip_conntrack_status {
   IPS_EXPECTED_BIT = 0,
   IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
diff --git a/libc/kernel/uapi/linux/nfc.h b/libc/kernel/uapi/linux/nfc.h
index e212b31..72e3520 100644
--- a/libc/kernel/uapi/linux/nfc.h
+++ b/libc/kernel/uapi/linux/nfc.h
@@ -54,6 +54,7 @@
   NFC_CMD_SE_IO,
   NFC_CMD_ACTIVATE_TARGET,
   NFC_CMD_VENDOR,
+  NFC_CMD_DEACTIVATE_TARGET,
   __NFC_CMD_AFTER_LAST
 };
 #define NFC_CMD_MAX (__NFC_CMD_AFTER_LAST - 1)
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index bb9a835..ebf9448 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -158,6 +158,8 @@
   NL80211_CMD_UPDATE_CONNECT_PARAMS,
   NL80211_CMD_SET_PMK,
   NL80211_CMD_DEL_PMK,
+  NL80211_CMD_PORT_AUTHORIZED,
+  NL80211_CMD_RELOAD_REGDB,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -904,6 +906,7 @@
 enum nl80211_mfp {
   NL80211_MFP_NO,
   NL80211_MFP_REQUIRED,
+  NL80211_MFP_OPTIONAL,
 };
 enum nl80211_wpa_versions {
   NL80211_WPA_VERSION_1 = 1 << 0,
@@ -1194,6 +1197,11 @@
   NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
   NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
   NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
+  NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME,
+  NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
+  NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
+  NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
+  NL80211_EXT_FEATURE_MFP_OPTIONAL,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
@@ -1218,6 +1226,10 @@
   NL80211_SCAN_FLAG_FLUSH = 1 << 1,
   NL80211_SCAN_FLAG_AP = 1 << 2,
   NL80211_SCAN_FLAG_RANDOM_ADDR = 1 << 3,
+  NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME = 1 << 4,
+  NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1 << 5,
+  NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1 << 6,
+  NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1 << 7,
 };
 enum nl80211_acl_policy {
   NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED,
diff --git a/libc/kernel/uapi/linux/openvswitch.h b/libc/kernel/uapi/linux/openvswitch.h
index 7247171..bea44d0 100644
--- a/libc/kernel/uapi/linux/openvswitch.h
+++ b/libc/kernel/uapi/linux/openvswitch.h
@@ -123,6 +123,8 @@
   OVS_VPORT_ATTR_UPCALL_PID,
   OVS_VPORT_ATTR_STATS,
   OVS_VPORT_ATTR_PAD,
+  OVS_VPORT_ATTR_IFINDEX,
+  OVS_VPORT_ATTR_NETNSID,
   __OVS_VPORT_ATTR_MAX
 };
 #define OVS_VPORT_ATTR_MAX (__OVS_VPORT_ATTR_MAX - 1)
@@ -182,6 +184,7 @@
   OVS_KEY_ATTR_CT_LABELS,
   OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
   OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
+  OVS_KEY_ATTR_NSH,
   __OVS_KEY_ATTR_MAX
 };
 #define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
@@ -298,6 +301,25 @@
   __be16 dst_port;
   __u8 ipv6_proto;
 };
+enum ovs_nsh_key_attr {
+  OVS_NSH_KEY_ATTR_UNSPEC,
+  OVS_NSH_KEY_ATTR_BASE,
+  OVS_NSH_KEY_ATTR_MD1,
+  OVS_NSH_KEY_ATTR_MD2,
+  __OVS_NSH_KEY_ATTR_MAX
+};
+#define OVS_NSH_KEY_ATTR_MAX (__OVS_NSH_KEY_ATTR_MAX - 1)
+struct ovs_nsh_key_base {
+  __u8 flags;
+  __u8 ttl;
+  __u8 mdtype;
+  __u8 np;
+  __be32 path_hdr;
+};
+#define NSH_MD1_CONTEXT_SIZE 4
+struct ovs_nsh_key_md1 {
+  __be32 context[NSH_MD1_CONTEXT_SIZE];
+};
 enum ovs_flow_attr {
   OVS_FLOW_ATTR_UNSPEC,
   OVS_FLOW_ATTR_KEY,
@@ -398,7 +420,50 @@
   OVS_ACTION_ATTR_TRUNC,
   OVS_ACTION_ATTR_PUSH_ETH,
   OVS_ACTION_ATTR_POP_ETH,
+  OVS_ACTION_ATTR_CT_CLEAR,
+  OVS_ACTION_ATTR_PUSH_NSH,
+  OVS_ACTION_ATTR_POP_NSH,
+  OVS_ACTION_ATTR_METER,
   __OVS_ACTION_ATTR_MAX,
 };
 #define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1)
+#define OVS_METER_FAMILY "ovs_meter"
+#define OVS_METER_MCGROUP "ovs_meter"
+#define OVS_METER_VERSION 0x1
+enum ovs_meter_cmd {
+  OVS_METER_CMD_UNSPEC,
+  OVS_METER_CMD_FEATURES,
+  OVS_METER_CMD_SET,
+  OVS_METER_CMD_DEL,
+  OVS_METER_CMD_GET
+};
+enum ovs_meter_attr {
+  OVS_METER_ATTR_UNSPEC,
+  OVS_METER_ATTR_ID,
+  OVS_METER_ATTR_KBPS,
+  OVS_METER_ATTR_STATS,
+  OVS_METER_ATTR_BANDS,
+  OVS_METER_ATTR_USED,
+  OVS_METER_ATTR_CLEAR,
+  OVS_METER_ATTR_MAX_METERS,
+  OVS_METER_ATTR_MAX_BANDS,
+  OVS_METER_ATTR_PAD,
+  __OVS_METER_ATTR_MAX
+};
+#define OVS_METER_ATTR_MAX (__OVS_METER_ATTR_MAX - 1)
+enum ovs_band_attr {
+  OVS_BAND_ATTR_UNSPEC,
+  OVS_BAND_ATTR_TYPE,
+  OVS_BAND_ATTR_RATE,
+  OVS_BAND_ATTR_BURST,
+  OVS_BAND_ATTR_STATS,
+  __OVS_BAND_ATTR_MAX
+};
+#define OVS_BAND_ATTR_MAX (__OVS_BAND_ATTR_MAX - 1)
+enum ovs_meter_band_type {
+  OVS_METER_BAND_TYPE_UNSPEC,
+  OVS_METER_BAND_TYPE_DROP,
+  __OVS_METER_BAND_TYPE_MAX
+};
+#define OVS_METER_BAND_TYPE_MAX (__OVS_METER_BAND_TYPE_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index c7f8381..148f2b4 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -640,6 +640,7 @@
 #define PCI_ERR_ROOT_FIRST_FATAL 0x00000010
 #define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020
 #define PCI_ERR_ROOT_FATAL_RCV 0x00000040
+#define PCI_ERR_ROOT_AER_IRQ 0xf8000000
 #define PCI_ERR_ROOT_ERR_SRC 52
 #define PCI_VC_PORT_CAP1 4
 #define PCI_VC_CAP1_EVCC 0x00000007
@@ -799,9 +800,13 @@
 #define PCI_SATA_REGS_INLINE 0xF
 #define PCI_SATA_SIZEOF_SHORT 8
 #define PCI_SATA_SIZEOF_LONG 16
+#define PCI_REBAR_CAP 4
+#define PCI_REBAR_CAP_SIZES 0x00FFFFF0
 #define PCI_REBAR_CTRL 8
-#define PCI_REBAR_CTRL_NBAR_MASK (7 << 5)
+#define PCI_REBAR_CTRL_BAR_IDX 0x00000007
+#define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0
 #define PCI_REBAR_CTRL_NBAR_SHIFT 5
+#define PCI_REBAR_CTRL_BAR_SIZE 0x00001F00
 #define PCI_DPA_CAP 4
 #define PCI_DPA_CAP_SUBSTATE_MASK 0x1F
 #define PCI_DPA_BASE_SIZEOF 16
@@ -814,6 +819,7 @@
 #define PCI_TPH_CAP_ST_SHIFT 16
 #define PCI_TPH_BASE_SIZEOF 12
 #define PCI_EXP_DPC_CAP 4
+#define PCI_EXP_DPC_IRQ 0x1f
 #define PCI_EXP_DPC_CAP_RP_EXT 0x20
 #define PCI_EXP_DPC_CAP_POISONED_TLP 0x40
 #define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80
@@ -842,17 +848,23 @@
 #define PCI_PTM_CTRL 0x08
 #define PCI_PTM_CTRL_ENABLE 0x00000001
 #define PCI_PTM_CTRL_ROOT 0x00000002
-#define PCI_L1SS_CAP 4
-#define PCI_L1SS_CAP_PCIPM_L1_2 1
-#define PCI_L1SS_CAP_PCIPM_L1_1 2
-#define PCI_L1SS_CAP_ASPM_L1_2 4
-#define PCI_L1SS_CAP_ASPM_L1_1 8
-#define PCI_L1SS_CAP_L1_PM_SS 16
-#define PCI_L1SS_CTL1 8
-#define PCI_L1SS_CTL1_PCIPM_L1_2 1
-#define PCI_L1SS_CTL1_PCIPM_L1_1 2
-#define PCI_L1SS_CTL1_ASPM_L1_2 4
-#define PCI_L1SS_CTL1_ASPM_L1_1 8
-#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000F
-#define PCI_L1SS_CTL2 0xC
+#define PCI_L1SS_CAP 0x04
+#define PCI_L1SS_CAP_PCIPM_L1_2 0x00000001
+#define PCI_L1SS_CAP_PCIPM_L1_1 0x00000002
+#define PCI_L1SS_CAP_ASPM_L1_2 0x00000004
+#define PCI_L1SS_CAP_ASPM_L1_1 0x00000008
+#define PCI_L1SS_CAP_L1_PM_SS 0x00000010
+#define PCI_L1SS_CAP_CM_RESTORE_TIME 0x0000ff00
+#define PCI_L1SS_CAP_P_PWR_ON_SCALE 0x00030000
+#define PCI_L1SS_CAP_P_PWR_ON_VALUE 0x00f80000
+#define PCI_L1SS_CTL1 0x08
+#define PCI_L1SS_CTL1_PCIPM_L1_2 0x00000001
+#define PCI_L1SS_CTL1_PCIPM_L1_1 0x00000002
+#define PCI_L1SS_CTL1_ASPM_L1_2 0x00000004
+#define PCI_L1SS_CTL1_ASPM_L1_1 0x00000008
+#define PCI_L1SS_CTL1_L1SS_MASK 0x0000000f
+#define PCI_L1SS_CTL1_CM_RESTORE_TIME 0x0000ff00
+#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000
+#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000
+#define PCI_L1SS_CTL2 0x0c
 #endif
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 326827e..97a2e99 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -329,6 +329,7 @@
 #define PERF_AUX_FLAG_TRUNCATED 0x01
 #define PERF_AUX_FLAG_OVERWRITE 0x02
 #define PERF_AUX_FLAG_PARTIAL 0x04
+#define PERF_AUX_FLAG_COLLISION 0x08
 #define PERF_FLAG_FD_NO_GROUP (1UL << 0)
 #define PERF_FLAG_FD_OUTPUT (1UL << 1)
 #define PERF_FLAG_PID_CGROUP (1UL << 2)
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index 7d3ff96..a3f2adf 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -49,6 +49,7 @@
 #define TC_H_ROOT (0xFFFFFFFFU)
 #define TC_H_INGRESS (0xFFFFFFF1U)
 #define TC_H_CLSACT TC_H_INGRESS
+#define TC_H_MIN_PRIORITY 0xFFE0U
 #define TC_H_MIN_INGRESS 0xFFF2U
 #define TC_H_MIN_EGRESS 0xFFF3U
 enum tc_link_layer {
@@ -403,6 +404,9 @@
   TCA_NETEM_ECN,
   TCA_NETEM_RATE64,
   TCA_NETEM_PAD,
+  TCA_NETEM_LATENCY64,
+  TCA_NETEM_JITTER64,
+  TCA_NETEM_SLOT,
   __TCA_NETEM_MAX,
 };
 #define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1)
@@ -433,6 +437,12 @@
   __u32 cell_size;
   __s32 cell_overhead;
 };
+struct tc_netem_slot {
+  __s64 min_delay;
+  __s64 max_delay;
+  __s32 max_packets;
+  __s32 max_bytes;
+};
 enum {
   NETEM_LOSS_UNSPEC,
   NETEM_LOSS_GI,
@@ -472,6 +482,18 @@
   __TC_MQPRIO_HW_OFFLOAD_MAX
 };
 #define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1)
+enum {
+  TC_MQPRIO_MODE_DCB,
+  TC_MQPRIO_MODE_CHANNEL,
+  __TC_MQPRIO_MODE_MAX
+};
+#define __TC_MQPRIO_MODE_MAX (__TC_MQPRIO_MODE_MAX - 1)
+enum {
+  TC_MQPRIO_SHAPER_DCB,
+  TC_MQPRIO_SHAPER_BW_RATE,
+  __TC_MQPRIO_SHAPER_MAX
+};
+#define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1)
 struct tc_mqprio_qopt {
   __u8 num_tc;
   __u8 prio_tc_map[TC_QOPT_BITMASK + 1];
@@ -479,6 +501,19 @@
   __u16 count[TC_QOPT_MAX_QUEUE];
   __u16 offset[TC_QOPT_MAX_QUEUE];
 };
+#define TC_MQPRIO_F_MODE 0x1
+#define TC_MQPRIO_F_SHAPER 0x2
+#define TC_MQPRIO_F_MIN_RATE 0x4
+#define TC_MQPRIO_F_MAX_RATE 0x8
+enum {
+  TCA_MQPRIO_UNSPEC,
+  TCA_MQPRIO_MODE,
+  TCA_MQPRIO_SHAPER,
+  TCA_MQPRIO_MIN_RATE64,
+  TCA_MQPRIO_MAX_RATE64,
+  __TCA_MQPRIO_MAX,
+};
+#define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1)
 enum {
   TCA_SFB_UNSPEC,
   TCA_SFB_PARMS,
@@ -654,4 +689,18 @@
   __u32 maxq;
   __u32 ecn_mark;
 };
+struct tc_cbs_qopt {
+  __u8 offload;
+  __u8 _pad[3];
+  __s32 hicredit;
+  __s32 locredit;
+  __s32 idleslope;
+  __s32 sendslope;
+};
+enum {
+  TCA_CBS_UNSPEC,
+  TCA_CBS_PARMS,
+  __TCA_CBS_MAX,
+};
+#define TCA_CBS_MAX (__TCA_CBS_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index a30fe17..55098f5 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -129,4 +129,9 @@
 #define PR_CAP_AMBIENT_RAISE 2
 #define PR_CAP_AMBIENT_LOWER 3
 #define PR_CAP_AMBIENT_CLEAR_ALL 4
+#define PR_SVE_SET_VL 50
+#define PR_SVE_SET_VL_ONEXEC (1 << 18)
+#define PR_SVE_GET_VL 51
+#define PR_SVE_VL_LEN_MASK 0xffff
+#define PR_SVE_VL_INHERIT (1 << 17)
 #endif
diff --git a/libc/kernel/uapi/linux/qrtr.h b/libc/kernel/uapi/linux/qrtr.h
index 4040b4c..c0a4c72 100644
--- a/libc/kernel/uapi/linux/qrtr.h
+++ b/libc/kernel/uapi/linux/qrtr.h
@@ -20,9 +20,39 @@
 #define _LINUX_QRTR_H
 #include <linux/socket.h>
 #include <linux/types.h>
+#define QRTR_NODE_BCAST 0xffffffffu
+#define QRTR_PORT_CTRL 0xfffffffeu
 struct sockaddr_qrtr {
   __kernel_sa_family_t sq_family;
   __u32 sq_node;
   __u32 sq_port;
 };
+enum qrtr_pkt_type {
+  QRTR_TYPE_DATA = 1,
+  QRTR_TYPE_HELLO = 2,
+  QRTR_TYPE_BYE = 3,
+  QRTR_TYPE_NEW_SERVER = 4,
+  QRTR_TYPE_DEL_SERVER = 5,
+  QRTR_TYPE_DEL_CLIENT = 6,
+  QRTR_TYPE_RESUME_TX = 7,
+  QRTR_TYPE_EXIT = 8,
+  QRTR_TYPE_PING = 9,
+  QRTR_TYPE_NEW_LOOKUP = 10,
+  QRTR_TYPE_DEL_LOOKUP = 11,
+};
+struct qrtr_ctrl_pkt {
+  __le32 cmd;
+  union {
+    struct {
+      __le32 service;
+      __le32 instance;
+      __le32 node;
+      __le32 port;
+    } server;
+    struct {
+      __le32 node;
+      __le32 port;
+    } client;
+  };
+} __packed;
 #endif
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index c363e34..80ba16e 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -318,6 +318,8 @@
 #define RTAX_QUICKACK RTAX_QUICKACK
   RTAX_CC_ALGO,
 #define RTAX_CC_ALGO RTAX_CC_ALGO
+  RTAX_FASTOPEN_NO_COOKIE,
+#define RTAX_FASTOPEN_NO_COOKIE RTAX_FASTOPEN_NO_COOKIE
   __RTAX_MAX
 };
 #define RTAX_MAX (__RTAX_MAX - 1)
@@ -402,6 +404,7 @@
   TCA_PAD,
   TCA_DUMP_INVISIBLE,
   TCA_CHAIN,
+  TCA_HW_OFFLOAD,
   __TCA_MAX
 };
 #define TCA_MAX (__TCA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/rxrpc.h b/libc/kernel/uapi/linux/rxrpc.h
index b8b7b04..1690111 100644
--- a/libc/kernel/uapi/linux/rxrpc.h
+++ b/libc/kernel/uapi/linux/rxrpc.h
@@ -22,12 +22,12 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 struct sockaddr_rxrpc {
-  sa_family_t srx_family;
-  u16 srx_service;
-  u16 transport_type;
-  u16 transport_len;
+  __kernel_sa_family_t srx_family;
+  __u16 srx_service;
+  __u16 transport_type;
+  __u16 transport_len;
   union {
-    sa_family_t family;
+    __kernel_sa_family_t family;
     struct sockaddr_in sin;
     struct sockaddr_in6 sin6;
   } transport;
@@ -50,6 +50,7 @@
   RXRPC_EXCLUSIVE_CALL = 10,
   RXRPC_UPGRADE_SERVICE = 11,
   RXRPC_TX_LENGTH = 12,
+  RXRPC_SET_CALL_TIMEOUT = 13,
   RXRPC__SUPPORTED
 };
 #define RXRPC_SECURITY_PLAIN 0
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 9a55459..cc714ff 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -77,6 +77,8 @@
 #define SCTP_RESET_ASSOC 120
 #define SCTP_ADD_STREAMS 121
 #define SCTP_SOCKOPT_PEELOFF_FLAGS 122
+#define SCTP_STREAM_SCHEDULER 123
+#define SCTP_STREAM_SCHEDULER_VALUE 124
 #define SCTP_PR_SCTP_NONE 0x0000
 #define SCTP_PR_SCTP_TTL 0x0010
 #define SCTP_PR_SCTP_RTX 0x0020
@@ -443,6 +445,11 @@
   sctp_assoc_t assoc_id;
   uint32_t assoc_value;
 };
+struct sctp_stream_value {
+  sctp_assoc_t assoc_id;
+  uint16_t stream_id;
+  uint16_t stream_value;
+};
 struct sctp_paddrinfo {
   sctp_assoc_t spinfo_assoc_id;
   struct sockaddr_storage spinfo_address;
@@ -616,4 +623,10 @@
   uint16_t sas_instrms;
   uint16_t sas_outstrms;
 };
+enum sctp_sched_type {
+  SCTP_SS_FCFS,
+  SCTP_SS_PRIO,
+  SCTP_SS_RR,
+  SCTP_SS_MAX = SCTP_SS_RR
+};
 #endif
diff --git a/libc/kernel/uapi/linux/seg6.h b/libc/kernel/uapi/linux/seg6.h
index 6f7b8dd..f180485 100644
--- a/libc/kernel/uapi/linux/seg6.h
+++ b/libc/kernel/uapi/linux/seg6.h
@@ -27,7 +27,7 @@
   __u8 segments_left;
   __u8 first_segment;
   __u8 flags;
-  __u16 reserved;
+  __u16 tag;
   struct in6_addr segments[0];
 };
 #define SR6_FLAG1_PROTECTED (1 << 6)
diff --git a/libc/kernel/uapi/linux/serial_reg.h b/libc/kernel/uapi/linux/serial_reg.h
index 95c9956..b6648f8 100644
--- a/libc/kernel/uapi/linux/serial_reg.h
+++ b/libc/kernel/uapi/linux/serial_reg.h
@@ -113,6 +113,7 @@
 #define UART_SCR 7
 #define UART_DLL 0
 #define UART_DLM 1
+#define UART_DIV_MAX 0xFFFF
 #define UART_EFR 2
 #define UART_XR_EFR 9
 #define UART_EFR_CTS 0x80
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 467a27a..b9f0c3e 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -158,7 +158,6 @@
   LINUX_MIB_TCPRENORECOVERY,
   LINUX_MIB_TCPSACKRECOVERY,
   LINUX_MIB_TCPSACKRENEGING,
-  LINUX_MIB_TCPFACKREORDER,
   LINUX_MIB_TCPSACKREORDER,
   LINUX_MIB_TCPRENOREORDER,
   LINUX_MIB_TCPTSREORDER,
diff --git a/libc/kernel/uapi/linux/stddef.h b/libc/kernel/uapi/linux/stddef.h
index a04729b..2a5fd95 100644
--- a/libc/kernel/uapi/linux/stddef.h
+++ b/libc/kernel/uapi/linux/stddef.h
@@ -16,7 +16,7 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#include <linux/compiler.h>
+#include <linux/compiler_types.h>
 #ifndef __always_inline
 #define __always_inline inline
 #endif
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 13354e6..0bf9559 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -87,6 +87,8 @@
 #define TCP_FASTOPEN_CONNECT 30
 #define TCP_ULP 31
 #define TCP_MD5SIG_EXT 32
+#define TCP_FASTOPEN_KEY 33
+#define TCP_FASTOPEN_NO_COOKIE 34
 struct tcp_repair_opt {
   __u32 opt_code;
   __u32 opt_val;
diff --git a/libc/kernel/uapi/linux/tipc.h b/libc/kernel/uapi/linux/tipc.h
index cf16725..b8b4965 100644
--- a/libc/kernel/uapi/linux/tipc.h
+++ b/libc/kernel/uapi/linux/tipc.h
@@ -121,6 +121,16 @@
 #define TIPC_SOCK_RECVQ_DEPTH 132
 #define TIPC_MCAST_BROADCAST 133
 #define TIPC_MCAST_REPLICAST 134
+#define TIPC_GROUP_JOIN 135
+#define TIPC_GROUP_LEAVE 136
+#define TIPC_GROUP_LOOPBACK 0x1
+#define TIPC_GROUP_MEMBER_EVTS 0x2
+struct tipc_group_req {
+  __u32 type;
+  __u32 instance;
+  __u32 scope;
+  __u32 flags;
+};
 #define TIPC_MAX_MEDIA_NAME 16
 #define TIPC_MAX_IF_NAME 16
 #define TIPC_MAX_BEARER_NAME 32
diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h
index 73618e0..925cf80 100644
--- a/libc/kernel/uapi/linux/tls.h
+++ b/libc/kernel/uapi/linux/tls.h
@@ -19,10 +19,6 @@
 #ifndef _UAPI_LINUX_TLS_H
 #define _UAPI_LINUX_TLS_H
 #include <linux/types.h>
-#include <asm/byteorder.h>
-#include <linux/socket.h>
-#include <linux/tcp.h>
-#include <net/tcp.h>
 #define TLS_TX 1
 #define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
 #define TLS_VERSION_MAJOR(ver) (((ver) >> 8) & 0xFF)
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index 38e7ae7..a7cf43a 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -79,6 +79,8 @@
 #define TEST_SE0_NAK 3
 #define TEST_PACKET 4
 #define TEST_FORCE_EN 5
+#define USB_STATUS_TYPE_STANDARD 0
+#define USB_STATUS_TYPE_PTM 1
 #define USB_DEVICE_U1_ENABLE 48
 #define USB_DEVICE_U2_ENABLE 49
 #define USB_DEVICE_LTM_ENABLE 50
@@ -367,6 +369,7 @@
   __le16 bmBandGroup;
   __u8 bReserved;
 } __attribute__((packed));
+#define USB_DT_USB_WIRELESS_CAP_SIZE 11
 #define USB_CAP_TYPE_EXT 2
 struct usb_ext_cap_descriptor {
   __u8 bLength;
@@ -504,6 +507,7 @@
   __u8 bDescriptorType;
   __u8 bDevCapabilityType;
 } __attribute__((packed));
+#define USB_DT_USB_PTM_ID_SIZE 3
 #define USB_DT_USB_SSP_CAP_SIZE(ssac) (16 + ssac * 4)
 struct usb_wireless_ep_comp_descriptor {
   __u8 bLength;
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 7714cb7..70b6963 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 265728
+#define LINUX_VERSION_CODE 265984
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/vm_sockets_diag.h b/libc/kernel/uapi/linux/vm_sockets_diag.h
new file mode 100644
index 0000000..2f9840b
--- /dev/null
+++ b/libc/kernel/uapi/linux/vm_sockets_diag.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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__VM_SOCKETS_DIAG_H__
+#define _UAPI__VM_SOCKETS_DIAG_H__
+#include <linux/types.h>
+struct vsock_diag_req {
+  __u8 sdiag_family;
+  __u8 sdiag_protocol;
+  __u16 pad;
+  __u32 vdiag_states;
+  __u32 vdiag_ino;
+  __u32 vdiag_show;
+  __u32 vdiag_cookie[2];
+};
+struct vsock_diag_msg {
+  __u8 vdiag_family;
+  __u8 vdiag_type;
+  __u8 vdiag_state;
+  __u8 vdiag_shutdown;
+  __u32 vdiag_src_cid;
+  __u32 vdiag_src_port;
+  __u32 vdiag_dst_cid;
+  __u32 vdiag_dst_port;
+  __u32 vdiag_ino;
+  __u32 vdiag_cookie[2];
+};
+#endif
diff --git a/libc/kernel/uapi/linux/wmi.h b/libc/kernel/uapi/linux/wmi.h
new file mode 100644
index 0000000..26f54d9
--- /dev/null
+++ b/libc/kernel/uapi/linux/wmi.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   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_WMI_H
+#define _UAPI_LINUX_WMI_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define WMI_IOC 'W'
+struct wmi_ioctl_buffer {
+  __u64 length;
+  __u8 data[];
+};
+struct calling_interface_buffer {
+  __u16 cmd_class;
+  __u16 cmd_select;
+  volatile __u32 input[4];
+  volatile __u32 output[4];
+} __packed;
+struct dell_wmi_extensions {
+  __u32 argattrib;
+  __u32 blength;
+  __u8 data[];
+} __packed;
+struct dell_wmi_smbios_buffer {
+  __u64 length;
+  struct calling_interface_buffer std;
+  struct dell_wmi_extensions ext;
+} __packed;
+#define CLASS_TOKEN_READ 0
+#define CLASS_TOKEN_WRITE 1
+#define SELECT_TOKEN_STD 0
+#define SELECT_TOKEN_BAT 1
+#define SELECT_TOKEN_AC 2
+#define CLASS_FLASH_INTERFACE 7
+#define SELECT_FLASH_INTERFACE 3
+#define CLASS_ADMIN_PROP 10
+#define SELECT_ADMIN_PROP 3
+#define CLASS_INFO 17
+#define SELECT_RFKILL 11
+#define SELECT_APP_REGISTRATION 3
+#define SELECT_DOCK 22
+#define CAPSULE_EN_TOKEN 0x0461
+#define CAPSULE_DIS_TOKEN 0x0462
+#define WSMT_EN_TOKEN 0x04EC
+#define WSMT_DIS_TOKEN 0x04ED
+#define DELL_WMI_SMBIOS_CMD _IOWR(WMI_IOC, 0, struct dell_wmi_smbios_buffer)
+#endif
diff --git a/libc/kernel/uapi/linux/xattr.h b/libc/kernel/uapi/linux/xattr.h
index efa99e7..7c098f4 100644
--- a/libc/kernel/uapi/linux/xattr.h
+++ b/libc/kernel/uapi/linux/xattr.h
@@ -56,6 +56,8 @@
 #define XATTR_NAME_SMACKEXEC XATTR_SECURITY_PREFIX XATTR_SMACK_EXEC
 #define XATTR_NAME_SMACKTRANSMUTE XATTR_SECURITY_PREFIX XATTR_SMACK_TRANSMUTE
 #define XATTR_NAME_SMACKMMAP XATTR_SECURITY_PREFIX XATTR_SMACK_MMAP
+#define XATTR_APPARMOR_SUFFIX "apparmor"
+#define XATTR_NAME_APPARMOR XATTR_SECURITY_PREFIX XATTR_APPARMOR_SUFFIX
 #define XATTR_CAPS_SUFFIX "capability"
 #define XATTR_NAME_CAPS XATTR_SECURITY_PREFIX XATTR_CAPS_SUFFIX
 #define XATTR_POSIX_ACL_ACCESS "posix_acl_access"
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index ff3ebcb..03a2fcd 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -75,7 +75,8 @@
   IB_USER_VERBS_EX_CMD_MODIFY_WQ,
   IB_USER_VERBS_EX_CMD_DESTROY_WQ,
   IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL,
-  IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL
+  IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL,
+  IB_USER_VERBS_EX_CMD_MODIFY_CQ
 };
 struct ib_uverbs_async_event_desc {
   __u64 element;
@@ -85,6 +86,11 @@
 struct ib_uverbs_comp_event_desc {
   __u64 cq_handle;
 };
+struct ib_uverbs_cq_moderation_caps {
+  __u16 max_cq_moderation_count;
+  __u16 max_cq_moderation_period;
+  __u32 reserved;
+};
 #define IB_USER_VERBS_CMD_COMMAND_MASK 0xff
 #define IB_USER_VERBS_CMD_FLAGS_MASK 0xff000000u
 #define IB_USER_VERBS_CMD_FLAGS_SHIFT 24
@@ -194,6 +200,7 @@
   __u32 max_wq_type_rq;
   __u32 raw_packet_caps;
   struct ib_uverbs_tm_caps tm_caps;
+  struct ib_uverbs_cq_moderation_caps cq_moderation_caps;
 };
 struct ib_uverbs_query_port {
   __u64 response;
@@ -952,5 +959,15 @@
   __u32 comp_mask;
   __u32 ind_tbl_handle;
 };
+struct ib_uverbs_cq_moderation {
+  __u16 cq_count;
+  __u16 cq_period;
+};
+struct ib_uverbs_ex_modify_cq {
+  __u32 cq_handle;
+  __u32 attr_mask;
+  struct ib_uverbs_cq_moderation attr;
+  __u32 reserved;
+};
 #define IB_DEVICE_NAME_MAX 64
 #endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index b51ff4e..9347cf3 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -23,6 +23,7 @@
 enum {
   MLX5_QP_FLAG_SIGNATURE = 1 << 0,
   MLX5_QP_FLAG_SCATTER_CQE = 1 << 1,
+  MLX5_QP_FLAG_TUNNEL_OFFLOADS = 1 << 2,
 };
 enum {
   MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
@@ -126,6 +127,23 @@
   __u32 sw_parsing_offloads;
   __u32 supported_qpts;
 };
+struct mlx5_ib_striding_rq_caps {
+  __u32 min_single_stride_log_num_of_bytes;
+  __u32 max_single_stride_log_num_of_bytes;
+  __u32 min_single_wqe_log_num_of_strides;
+  __u32 max_single_wqe_log_num_of_strides;
+  __u32 supported_qpts;
+  __u32 reserved;
+};
+enum mlx5_ib_query_dev_resp_flags {
+  MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0,
+  MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_PAD = 1 << 1,
+};
+enum mlx5_ib_tunnel_offloads {
+  MLX5_IB_TUNNELED_OFFLOADS_VXLAN = 1 << 0,
+  MLX5_IB_TUNNELED_OFFLOADS_GRE = 1 << 1,
+  MLX5_IB_TUNNELED_OFFLOADS_GENEVE = 1 << 2
+};
 struct mlx5_ib_query_device_resp {
   __u32 comp_mask;
   __u32 response_length;
@@ -134,8 +152,14 @@
   struct mlx5_ib_cqe_comp_caps cqe_comp_caps;
   struct mlx5_packet_pacing_caps packet_pacing_caps;
   __u32 mlx5_ib_support_multi_pkt_send_wqes;
-  __u32 reserved;
+  __u32 flags;
   struct mlx5_ib_sw_parsing_caps sw_parsing_caps;
+  struct mlx5_ib_striding_rq_caps striding_rq_caps;
+  __u32 tunnel_offloads_caps;
+  __u32 reserved;
+};
+enum mlx5_ib_create_cq_flags {
+  MLX5_IB_CREATE_CQ_FLAGS_CQE_128B_PAD = 1 << 0,
 };
 struct mlx5_ib_create_cq {
   __u64 buf_addr;
@@ -143,7 +167,7 @@
   __u32 cqe_size;
   __u8 cqe_comp_en;
   __u8 cqe_comp_res_format;
-  __u16 reserved;
+  __u16 flags;
 };
 struct mlx5_ib_create_cq_resp {
   __u32 cqn;
@@ -189,7 +213,8 @@
   MLX5_RX_HASH_SRC_PORT_TCP = 1 << 4,
   MLX5_RX_HASH_DST_PORT_TCP = 1 << 5,
   MLX5_RX_HASH_SRC_PORT_UDP = 1 << 6,
-  MLX5_RX_HASH_DST_PORT_UDP = 1 << 7
+  MLX5_RX_HASH_DST_PORT_UDP = 1 << 7,
+  MLX5_RX_HASH_INNER = 1 << 31
 };
 struct mlx5_ib_create_qp_rss {
   __u64 rx_hash_fields_mask;
@@ -198,7 +223,7 @@
   __u8 reserved[6];
   __u8 rx_hash_key[128];
   __u32 comp_mask;
-  __u32 reserved1;
+  __u32 flags;
 };
 struct mlx5_ib_create_qp_resp {
   __u32 bfreg_index;
@@ -209,6 +234,9 @@
   __u8 reserved1;
   __u16 reserved2;
 };
+enum mlx5_ib_create_wq_mask {
+  MLX5_IB_CREATE_WQ_STRIDING_RQ = (1 << 0),
+};
 struct mlx5_ib_create_wq {
   __u64 buf_addr;
   __u64 db_addr;
@@ -217,7 +245,9 @@
   __u32 user_index;
   __u32 flags;
   __u32 comp_mask;
-  __u32 reserved;
+  __u32 single_stride_log_num_of_bytes;
+  __u32 single_wqe_log_num_of_strides;
+  __u32 two_byte_shift_en;
 };
 struct mlx5_ib_create_ah_resp {
   __u32 response_length;
diff --git a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
index 2062366..7c13680 100644
--- a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
+++ b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
@@ -119,6 +119,8 @@
 };
 struct pvrdma_create_srq {
   __u64 buf_addr;
+  __u32 buf_size;
+  __u32 reserved;
 };
 struct pvrdma_create_srq_resp {
   __u32 srqn;
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index abab364..839c406 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1325,6 +1325,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1356,26 +1357,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index d464a0c..a39a233 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1245,6 +1245,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1276,26 +1277,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 97965ac..b3bfa8a 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1350,6 +1350,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1381,26 +1382,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 930a1ca..2a93132 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1309,6 +1309,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1340,26 +1341,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index d464a0c..a39a233 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1245,6 +1245,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1276,26 +1277,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 27b9743..d2e7399 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1307,6 +1307,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1338,26 +1339,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index d464a0c..a39a233 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1245,6 +1245,7 @@
     endhostent;
     endnetent;
     endprotoent;
+    epoll_pwait64;
     fexecve;
     fflush_unlocked;
     fgetc_unlocked;
@@ -1276,26 +1277,48 @@
     posix_spawnattr_getschedparam;
     posix_spawnattr_getschedpolicy;
     posix_spawnattr_getsigdefault;
+    posix_spawnattr_getsigdefault64;
     posix_spawnattr_getsigmask;
+    posix_spawnattr_getsigmask64;
     posix_spawnattr_init;
     posix_spawnattr_setflags;
     posix_spawnattr_setpgroup;
     posix_spawnattr_setschedparam;
     posix_spawnattr_setschedpolicy;
     posix_spawnattr_setsigdefault;
+    posix_spawnattr_setsigdefault64;
     posix_spawnattr_setsigmask;
+    posix_spawnattr_setsigmask64;
     posix_spawn_file_actions_addclose;
     posix_spawn_file_actions_adddup2;
     posix_spawn_file_actions_addopen;
     posix_spawn_file_actions_destroy;
     posix_spawn_file_actions_init;
     posix_spawnp;
+    ppoll64;
+    pselect64;
     pthread_attr_getinheritsched;
     pthread_attr_setinheritsched;
+    pthread_mutexattr_getprotocol;
+    pthread_mutexattr_setprotocol;
     pthread_setschedprio;
+    pthread_sigmask64;
     sethostent;
     setnetent;
     setprotoent;
+    sigaction64;
+    sigaddset64;
+    sigdelset64;
+    sigemptyset64;
+    sigfillset64;
+    sigismember64;
+    signalfd64;
+    sigpending64;
+    sigprocmask64;
+    sigsuspend64;
+    sigtimedwait64;
+    sigwait64;
+    sigwaitinfo64;
     swab;
     syncfs;
 } LIBC_O;
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index 06fc426..ede2431 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -13,7 +13,10 @@
 
     stl: "libc++_static",
 
-    whole_static_libs: ["libasync_safe", "libdemangle"],
+    whole_static_libs: [
+        "libasync_safe",
+        "libdemangle",
+    ],
 
     include_dirs: ["bionic/libc"],
 
@@ -117,7 +120,10 @@
     whole_static_libs: ["libc_malloc_debug"],
 
     local_include_dirs: ["tests"],
-    include_dirs: ["bionic/libc", "bionic/libc/async_safe/include"],
+    include_dirs: [
+        "bionic/libc",
+        "bionic/libc/async_safe/include",
+    ],
 
     shared_libs: ["libbase"],
 
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index d597280..57d8f2a 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -59,13 +59,10 @@
 bool BacktraceData::Initialize(const Config& config) {
   enabled_ = config.backtrace_enabled();
   if (config.backtrace_enable_on_signal()) {
-    struct sigaction enable_act;
-    memset(&enable_act, 0, sizeof(enable_act));
-
+    struct sigaction64 enable_act = {};
     enable_act.sa_sigaction = ToggleBacktraceEnable;
     enable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
-    sigemptyset(&enable_act.sa_mask);
-    if (sigaction(config.backtrace_signal(), &enable_act, nullptr) != 0) {
+    if (sigaction64(config.backtrace_signal(), &enable_act, nullptr) != 0) {
       error_log("Unable to set up backtrace signal enable function: %s", strerror(errno));
       return false;
     }
@@ -73,13 +70,10 @@
              config.backtrace_signal(), getpid());
   }
 
-  struct sigaction act;
-  memset(&act, 0, sizeof(act));
-
+  struct sigaction64 act = {};
   act.sa_sigaction = EnableDump;
   act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
-  sigemptyset(&act.sa_mask);
-  if (sigaction(config.backtrace_dump_signal(), &act, nullptr) != 0) {
+  if (sigaction64(config.backtrace_dump_signal(), &act, nullptr) != 0) {
     error_log("Unable to set up backtrace dump signal function: %s", strerror(errno));
     return false;
   }
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index d6ca998..76f8fbb 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -94,16 +94,25 @@
   if (track != nullptr) {
     track->PrepareFork();
   }
+  if (free_track != nullptr) {
+    free_track->PrepareFork();
+  }
 }
 
 void DebugData::PostForkParent() {
   if (track != nullptr) {
     track->PostForkParent();
   }
+  if (free_track != nullptr) {
+    free_track->PostForkParent();
+  }
 }
 
 void DebugData::PostForkChild() {
   if (track != nullptr) {
     track->PostForkChild();
   }
+  if (free_track != nullptr) {
+    free_track->PostForkChild();
+  }
 }
diff --git a/libc/malloc_debug/FreeTrackData.h b/libc/malloc_debug/FreeTrackData.h
index 1758ef5..0e8c177 100644
--- a/libc/malloc_debug/FreeTrackData.h
+++ b/libc/malloc_debug/FreeTrackData.h
@@ -57,6 +57,12 @@
 
   void LogBacktrace(const Header* header);
 
+  void PrepareFork() { pthread_mutex_lock(&mutex_); }
+
+  void PostForkParent() { pthread_mutex_unlock(&mutex_); }
+
+  void PostForkChild() { pthread_mutex_init(&mutex_, NULL); }
+
  private:
   void LogFreeError(const Header* header, const uint8_t* pointer);
   void VerifyAndFree(const Header* header);
diff --git a/libc/malloc_debug/MapData.h b/libc/malloc_debug/MapData.h
index 0238139..895f78f 100644
--- a/libc/malloc_debug/MapData.h
+++ b/libc/malloc_debug/MapData.h
@@ -41,7 +41,7 @@
   MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len)
       : start(start), end(end), offset(offset), name(name, name_len) {}
 
-  MapEntry(uintptr_t pc) : start(pc), end(pc) {}
+  explicit MapEntry(uintptr_t pc) : start(pc), end(pc) {}
 
   uintptr_t start;
   uintptr_t end;
diff --git a/libc/malloc_debug/OptionData.h b/libc/malloc_debug/OptionData.h
index 80190f5..5c2d272 100644
--- a/libc/malloc_debug/OptionData.h
+++ b/libc/malloc_debug/OptionData.h
@@ -34,7 +34,7 @@
 
 class OptionData {
  public:
-  OptionData(DebugData* debug) : debug_(debug) {}
+  explicit OptionData(DebugData* debug) : debug_(debug) {}
   ~OptionData() = default;
 
  protected:
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index bb56cb8..b7a12a5 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -484,15 +484,15 @@
     adb shell setprop libc.debug.malloc.options backtrace
     adb shell start
 
-Enable multiple options (backtrace and guards):
+Enable multiple options (backtrace and guard):
 
     adb shell stop
-    adb shell setprop libc.debug.malloc.options "\"backtrace guards\""
+    adb shell setprop libc.debug.malloc.options "\"backtrace guard\""
     adb shell start
 
 Note: The two levels of quoting in the adb shell command is necessary.
 The outer layer of quoting is for the shell on the host, to ensure that the
-inner layer of quoting is sent to the device, to make 'backtrace guards'
+inner layer of quoting is sent to the device, to make 'backtrace guard'
 a single argument.
 
 Enable malloc debug using an environment variable (pre-O Android release):
diff --git a/libc/malloc_debug/README_marshmallow_and_earlier.md b/libc/malloc_debug/README_marshmallow_and_earlier.md
index 3513711..c8be656 100644
--- a/libc/malloc_debug/README_marshmallow_and_earlier.md
+++ b/libc/malloc_debug/README_marshmallow_and_earlier.md
@@ -4,10 +4,10 @@
 Malloc debug is a method of debugging native memory problems. It can help
 detect memory corruption, memory leaks, and use after free issues.
 
-This documentation describes how to enable this feature on versions of
-the Android OS, Marshmallow or older. Note: malloc debug was full of bugs
-and was not fully functional until KitKat, so using it on a version older
-than that is not guaranteed to work at all.
+This documentation describes how to enable this feature on API level
+23 or older. Note: malloc debug was full of bugs and was not fully
+functional until API level 19, so using it on a version older than that
+is not guaranteed to work at all.
 
 The documentation for malloc debug on newer versions of Android is
 [here](README.md).
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 5a68deb..55d9943 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -179,13 +179,10 @@
 }
 
 bool RecordData::Initialize(const Config& config) {
-  struct sigaction dump_act;
-  memset(&dump_act, 0, sizeof(dump_act));
-
+  struct sigaction64 dump_act = {};
   dump_act.sa_sigaction = RecordDump;
   dump_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
-  sigemptyset(&dump_act.sa_mask);
-  if (sigaction(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
+  if (sigaction64(config.record_allocs_signal(), &dump_act, nullptr) != 0) {
     error_log("Unable to set up record dump signal function: %s", strerror(errno));
     return false;
   }
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index 6e19923..ccabac2 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -66,7 +66,7 @@
 
 class AllocEntry : public RecordEntry {
  public:
-  AllocEntry(void* pointer);
+  explicit AllocEntry(void* pointer);
   virtual ~AllocEntry() = default;
 
  protected:
@@ -92,7 +92,7 @@
 
 class FreeEntry : public AllocEntry {
  public:
-  FreeEntry(void* pointer);
+  explicit FreeEntry(void* pointer);
   virtual ~FreeEntry() = default;
 
   std::string GetString() const override;
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
index f7486e9..9a649b9 100644
--- a/libc/malloc_debug/TrackData.h
+++ b/libc/malloc_debug/TrackData.h
@@ -46,7 +46,7 @@
 
 class TrackData : public OptionData {
  public:
-  TrackData(DebugData* debug_data);
+  explicit TrackData(DebugData* debug_data);
   virtual ~TrackData() = default;
 
   void GetList(std::vector<const Header*>* list);
diff --git a/libc/private/CachedProperty.h b/libc/private/CachedProperty.h
index 84ead01..bd67d74 100644
--- a/libc/private/CachedProperty.h
+++ b/libc/private/CachedProperty.h
@@ -38,7 +38,7 @@
 class CachedProperty {
  public:
   // The lifetime of `property_name` must be greater than that of this CachedProperty.
-  CachedProperty(const char* property_name)
+  explicit CachedProperty(const char* property_name)
     : property_name_(property_name),
       prop_info_(nullptr),
       cached_area_serial_(0),
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index 68d4999..747186c 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -32,7 +32,7 @@
 // constituents for easy access.
 class KernelArgumentBlock {
  public:
-  KernelArgumentBlock(void* raw_args) {
+  explicit KernelArgumentBlock(void* raw_args) {
     uintptr_t* args = reinterpret_cast<uintptr_t*>(raw_args);
     argc = static_cast<int>(*args);
     argv = reinterpret_cast<char**>(args + 1);
diff --git a/libc/private/ScopedSignalBlocker.h b/libc/private/ScopedSignalBlocker.h
index 35d1c58..7582068 100644
--- a/libc/private/ScopedSignalBlocker.h
+++ b/libc/private/ScopedSignalBlocker.h
@@ -24,9 +24,9 @@
 class ScopedSignalBlocker {
  public:
   explicit ScopedSignalBlocker() {
-    sigset_t set;
-    sigfillset(&set);
-    sigprocmask(SIG_BLOCK, &set, &old_set_);
+    sigset64_t set;
+    sigfillset64(&set);
+    sigprocmask64(SIG_SETMASK, &set, &old_set_);
   }
 
   ~ScopedSignalBlocker() {
@@ -34,11 +34,11 @@
   }
 
   void reset() {
-    sigprocmask(SIG_SETMASK, &old_set_, nullptr);
+    sigprocmask64(SIG_SETMASK, &old_set_, nullptr);
   }
 
  private:
-  sigset_t old_set_;
+  sigset64_t old_set_;
 
   DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
 };
diff --git a/libc/bionic/sigwaitinfo.cpp b/libc/private/SigSetConverter.h
similarity index 87%
rename from libc/bionic/sigwaitinfo.cpp
rename to libc/private/SigSetConverter.h
index 43e2395..7d0b215 100644
--- a/libc/bionic/sigwaitinfo.cpp
+++ b/libc/private/SigSetConverter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,8 +26,10 @@
  * SUCH DAMAGE.
  */
 
-#include <signal.h>
+#pragma once
 
-int sigwaitinfo(const sigset_t* set, siginfo_t* info) {
-  return sigtimedwait(set, info, NULL);
-}
+union SigSetConverter {
+  int bsd;
+  sigset_t sigset;
+  sigset64_t sigset64;
+};
diff --git a/libc/private/bionic_futex.h b/libc/private/bionic_futex.h
index 9b89131..fd68007 100644
--- a/libc/private/bionic_futex.h
+++ b/libc/private/bionic_futex.h
@@ -70,4 +70,11 @@
 __LIBC_HIDDEN__ int __futex_wait_ex(volatile void* ftx, bool shared, int value,
                                     bool use_realtime_clock, const timespec* abs_timeout);
 
+static inline int __futex_pi_unlock(volatile void* ftx, bool shared) {
+  return __futex(ftx, shared ? FUTEX_UNLOCK_PI : FUTEX_UNLOCK_PI_PRIVATE, 0, nullptr, 0);
+}
+
+__LIBC_HIDDEN__ int __futex_pi_lock_ex(volatile void* ftx, bool shared, bool use_realtime_clock,
+                                       const timespec* abs_timeout);
+
 #endif /* _BIONIC_FUTEX_H */
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 292959a..352115a 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -29,6 +29,7 @@
 #ifndef _BIONIC_MBSTATE_H
 #define _BIONIC_MBSTATE_H
 
+#include <errno.h>
 #include <wchar.h>
 
 __BEGIN_DECLS
diff --git a/libc/private/bionic_vdso.h b/libc/private/bionic_vdso.h
index ed11501..da19b29 100644
--- a/libc/private/bionic_vdso.h
+++ b/libc/private/bionic_vdso.h
@@ -35,10 +35,12 @@
 #define VDSO_CLOCK_GETTIME_SYMBOL "__kernel_clock_gettime"
 #define VDSO_CLOCK_GETRES_SYMBOL  "__kernel_clock_getres"
 #define VDSO_GETTIMEOFDAY_SYMBOL  "__kernel_gettimeofday"
+#define VDSO_TIME_SYMBOL          "__kernel_time"
 #else
 #define VDSO_CLOCK_GETTIME_SYMBOL "__vdso_clock_gettime"
 #define VDSO_CLOCK_GETRES_SYMBOL  "__vdso_clock_getres"
 #define VDSO_GETTIMEOFDAY_SYMBOL  "__vdso_gettimeofday"
+#define VDSO_TIME_SYMBOL          "__vdso_time"
 #endif
 
 extern "C" int __clock_gettime(int, timespec*);
@@ -54,6 +56,7 @@
   VDSO_CLOCK_GETTIME = 0,
   VDSO_CLOCK_GETRES,
   VDSO_GETTIMEOFDAY,
+  VDSO_TIME,
   VDSO_END
 };
 
diff --git a/libc/private/kernel_sigset_t.h b/libc/private/kernel_sigset_t.h
deleted file mode 100644
index 9415fcf..0000000
--- a/libc/private/kernel_sigset_t.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 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 LIBC_PRIVATE_KERNEL_SIGSET_T_H_
-#define LIBC_PRIVATE_KERNEL_SIGSET_T_H_
-
-#include <signal.h>
-
-// Our sigset_t is wrong for ARM and x86. It's 32-bit but the kernel expects 64 bits.
-// This means we can't support real-time signals correctly until we can change the ABI.
-// In the meantime, we can use this union to pass an appropriately-sized block of memory
-// to the kernel, at the cost of not being able to refer to real-time signals.
-union kernel_sigset_t {
-  kernel_sigset_t() {
-    clear();
-  }
-
-  kernel_sigset_t(const sigset_t* value) {
-    clear();
-    set(value);
-  }
-
-  void clear() {
-    __builtin_memset(this, 0, sizeof(*this));
-  }
-
-  void set(const sigset_t* value) {
-    bionic = *value;
-  }
-
-  sigset_t* get() {
-    return &bionic;
-  }
-
-  sigset_t bionic;
-#ifndef __mips__
-  uint32_t kernel[2];
-#endif
-};
-
-#endif
diff --git a/libc/seccomp/Android.bp b/libc/seccomp/Android.bp
index b3707bc..ae99857 100644
--- a/libc/seccomp/Android.bp
+++ b/libc/seccomp/Android.bp
@@ -2,21 +2,30 @@
     name: "libseccomp_policy",
     srcs: [
         "seccomp_policy.cpp",
-        "arm_policy.cpp",
+        "arm_app_policy.cpp",
         "arm_global_policy.cpp",
-        "arm64_policy.cpp",
+        "arm_system_policy.cpp",
+        "arm64_app_policy.cpp",
         "arm64_global_policy.cpp",
-        "x86_policy.cpp",
+        "arm64_system_policy.cpp",
+        "x86_app_policy.cpp",
         "x86_global_policy.cpp",
-        "x86_64_policy.cpp",
+        "x86_system_policy.cpp",
+        "x86_64_app_policy.cpp",
         "x86_64_global_policy.cpp",
-        "mips_policy.cpp",
+        "x86_64_system_policy.cpp",
+        "mips_app_policy.cpp",
         "mips_global_policy.cpp",
-        "mips64_policy.cpp",
+        "mips_system_policy.cpp",
+        "mips64_app_policy.cpp",
         "mips64_global_policy.cpp",
+        "mips64_system_policy.cpp",
     ],
     export_include_dirs: ["include"],
-    cflags: ["-Wall", "-Werror"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
     shared: {
         shared_libs: ["libbase"],
     },
diff --git a/libc/seccomp/arm64_app_policy.cpp b/libc/seccomp/arm64_app_policy.cpp
new file mode 100644
index 0000000..f7f0dc4
--- /dev/null
+++ b/libc/seccomp/arm64_app_policy.cpp
@@ -0,0 +1,69 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter arm64_app_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 58),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 52, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 52, 51), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 39, 51, 50), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 49, 48), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 48, 47), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 59, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 45, 44), //fchmod|fchmodat|fchownat|fchown|openat|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 44, 43), //pipe2|quotactl|getdents64|lseek|read|write|readv|writev|pread64|pwrite64|preadv|pwritev|sendfile|pselect6|ppoll|signalfd4|vmsplice|splice|tee|readlinkat|newfstatat|fstat|sync|fsync|fdatasync|sync_file_range|timerfd_create|timerfd_settime|timerfd_gettime|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 42, 41), //capget
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 99, 41, 40), //personality|exit|exit_group|waitid|set_tid_address|unshare|futex
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 143, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 113, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 107, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 37, 36), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 112, 36, 35), //timer_create|timer_gettime|timer_getoverrun|timer_settime|timer_delete
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 34, 33), //clock_gettime|clock_getres|clock_nanosleep
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 142, 33, 32), //ptrace|sched_setparam|sched_setscheduler|sched_getscheduler|sched_getparam|sched_setaffinity|sched_getaffinity|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|restart_syscall|kill|tkill|tgkill|sigaltstack|rt_sigsuspend|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigreturn|setpriority|getpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 148, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 144, 30, 29), //setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 29, 28), //getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 151, 28, 27), //getresgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 226, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 163, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 160, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 159, 23, 22), //times|setpgid|getpgid|getsid|setsid|getgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 161, 22, 21), //uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 170, 20, 19), //getrlimit|setrlimit|getrusage|umask|prctl|getcpu|gettimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 19, 18), //getpid|getppid|getuid|geteuid|getgid|getegid|gettid|sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 16, 15), //socket|socketpair|bind|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 15, 14), //connect|getsockname|getpeername|sendto|recvfrom|setsockopt|getsockopt|shutdown|sendmsg|recvmsg|readahead|brk|munmap|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 14, 13), //clone|execve|mmap|fadvise64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 274, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 260, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 240, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 234, 10, 9), //mprotect|msync|mlock|munlock|mlockall|munlockall|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 9, 8), //rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 267, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 7, 6), //wait4|prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 6, 5), //syncfs|setns|sendmmsg|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 281, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 2), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t arm64_app_filter_size = sizeof(arm64_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm64_global_policy.cpp b/libc/seccomp/arm64_global_policy.cpp
index e2c594e..0a898de 100644
--- a/libc/seccomp/arm64_global_policy.cpp
+++ b/libc/seccomp/arm64_global_policy.cpp
@@ -5,37 +5,35 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter arm64_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 32),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 30),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 27, 26), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 26, 25), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat|umount2|mount|pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 25, 24), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 24, 23), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat|umount2|mount|pivot_root
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 59, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 24, 23), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir|chroot|fchmod|fchmodat|fchownat|fchown|openat|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 99, 23, 22), //pipe2|quotactl|getdents64|lseek|read|write|readv|writev|pread64|pwrite64|preadv|pwritev|sendfile|pselect6|ppoll|signalfd4|vmsplice|splice|tee|readlinkat|newfstatat|fstat|sync|fsync|fdatasync|sync_file_range|timerfd_create|timerfd_settime|timerfd_gettime|utimensat|acct|capget|capset|personality|exit|exit_group|waitid|set_tid_address|unshare|futex
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 22, 21), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir|chroot|fchmod|fchmodat|fchownat|fchown|openat|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 99, 21, 20), //pipe2|quotactl|getdents64|lseek|read|write|readv|writev|pread64|pwrite64|preadv|pwritev|sendfile|pselect6|ppoll|signalfd4|vmsplice|splice|tee|readlinkat|newfstatat|fstat|sync|fsync|fdatasync|sync_file_range|timerfd_create|timerfd_settime|timerfd_gettime|utimensat|acct|capget|capset|personality|exit|exit_group|waitid|set_tid_address|unshare|futex
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 105, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 20, 19), //nanosleep|getitimer|setitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 19, 18), //init_module|delete_module|timer_create|timer_gettime|timer_getoverrun|timer_settime|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|syslog|ptrace|sched_setparam|sched_setscheduler|sched_getscheduler|sched_getparam|sched_setaffinity|sched_getaffinity|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|restart_syscall|kill|tkill|tgkill|sigaltstack|rt_sigsuspend|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigreturn|setpriority|getpriority|reboot|setregid|setgid|setreuid|setuid|setresuid|getresuid|setresgid|getresgid|setfsuid|setfsgid|times|setpgid|getpgid|getsid|setsid|getgroups|setgroups|uname|sethostname|setdomainname|getrlimit|setrlimit|getrusage|umask|prctl|getcpu|gettimeofday|settimeofday|adjtimex|getpid|getppid|getuid|geteuid|getgid|getegid|gettid|sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 18, 17), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 17, 16), //init_module|delete_module|timer_create|timer_gettime|timer_getoverrun|timer_settime|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|syslog|ptrace|sched_setparam|sched_setscheduler|sched_getscheduler|sched_getparam|sched_setaffinity|sched_getaffinity|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|restart_syscall|kill|tkill|tgkill|sigaltstack|rt_sigsuspend|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigreturn|setpriority|getpriority|reboot|setregid|setgid|setreuid|setuid|setresuid|getresuid|setresgid|getresgid|setfsuid|setfsgid|times|setpgid|getpgid|getsid|setsid|getgroups|setgroups|uname|sethostname|setdomainname|getrlimit|setrlimit|getrusage|umask|prctl|getcpu|gettimeofday|settimeofday|adjtimex|getpid|getppid|getuid|geteuid|getgid|getegid|gettid|sysinfo
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 17, 16), //socket|socketpair|bind|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 16, 15), //connect|getsockname|getpeername|sendto|recvfrom|setsockopt|getsockopt|shutdown|sendmsg|recvmsg|readahead|brk|munmap|mremap|add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 15, 14), //socket|socketpair|bind|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 14, 13), //connect|getsockname|getpeername|sendto|recvfrom|setsockopt|getsockopt|shutdown|sendmsg|recvmsg|readahead|brk|munmap|mremap|add_key
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 266, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 240, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 226, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 225, 12, 11), //keyctl|clone|execve|mmap|fadvise64|swapon
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 234, 11, 10), //mprotect|msync|mlock|munlock|mlockall|munlockall|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 225, 10, 9), //keyctl|clone|execve|mmap|fadvise64|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 234, 9, 8), //mprotect|msync|mlock|munlock|mlockall|munlockall|mincore|madvise
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 260, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 9, 8), //rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 8, 7), //wait4|prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 281, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 7, 6), //rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 6, 5), //wait4|prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 5, 4), //clock_adjtime|syncfs|setns|sendmmsg|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 4, 3), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 3, 2), //clock_adjtime|syncfs|setns|sendmmsg|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 2, 1), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
diff --git a/libc/seccomp/arm64_policy.cpp b/libc/seccomp/arm64_system_policy.cpp
similarity index 67%
rename from libc/seccomp/arm64_policy.cpp
rename to libc/seccomp/arm64_system_policy.cpp
index c52c737..51bf12d 100644
--- a/libc/seccomp/arm64_policy.cpp
+++ b/libc/seccomp/arm64_system_policy.cpp
@@ -4,40 +4,38 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter arm64_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 32),
+const sock_filter arm64_system_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 30),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 27, 26), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 26, 25), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat|umount2|mount|pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 18, 25, 24), //io_setup|io_destroy|io_submit|io_cancel|io_getevents|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|getcwd
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 42, 24, 23), //eventfd2|epoll_create1|epoll_ctl|epoll_pwait|dup|dup3|fcntl|inotify_init1|inotify_add_watch|inotify_rm_watch|ioctl|ioprio_set|ioprio_get|flock|mknodat|mkdirat|unlinkat|symlinkat|linkat|renameat|umount2|mount|pivot_root
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 59, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 24, 23), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir|chroot|fchmod|fchmodat|fchownat|fchown|openat|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 99, 23, 22), //pipe2|quotactl|getdents64|lseek|read|write|readv|writev|pread64|pwrite64|preadv|pwritev|sendfile|pselect6|ppoll|signalfd4|vmsplice|splice|tee|readlinkat|newfstatat|fstat|sync|fsync|fdatasync|sync_file_range|timerfd_create|timerfd_settime|timerfd_gettime|utimensat|acct|capget|capset|personality|exit|exit_group|waitid|set_tid_address|unshare|futex
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 22, 21), //statfs|fstatfs|truncate|ftruncate|fallocate|faccessat|chdir|fchdir|chroot|fchmod|fchmodat|fchownat|fchown|openat|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 99, 21, 20), //pipe2|quotactl|getdents64|lseek|read|write|readv|writev|pread64|pwrite64|preadv|pwritev|sendfile|pselect6|ppoll|signalfd4|vmsplice|splice|tee|readlinkat|newfstatat|fstat|sync|fsync|fdatasync|sync_file_range|timerfd_create|timerfd_settime|timerfd_gettime|utimensat|acct|capget|capset|personality|exit|exit_group|waitid|set_tid_address|unshare|futex
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 105, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 20, 19), //nanosleep|getitimer|setitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 19, 18), //init_module|delete_module|timer_create|timer_gettime|timer_getoverrun|timer_settime|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|syslog|ptrace|sched_setparam|sched_setscheduler|sched_getscheduler|sched_getparam|sched_setaffinity|sched_getaffinity|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|restart_syscall|kill|tkill|tgkill|sigaltstack|rt_sigsuspend|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigreturn|setpriority|getpriority|reboot|setregid|setgid|setreuid|setuid|setresuid|getresuid|setresgid|getresgid|setfsuid|setfsgid|times|setpgid|getpgid|getsid|setsid|getgroups|setgroups|uname|sethostname|setdomainname|getrlimit|setrlimit|getrusage|umask|prctl|getcpu|gettimeofday|settimeofday|adjtimex|getpid|getppid|getuid|geteuid|getgid|getegid|gettid|sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 18, 17), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 17, 16), //init_module|delete_module|timer_create|timer_gettime|timer_getoverrun|timer_settime|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|syslog|ptrace|sched_setparam|sched_setscheduler|sched_getscheduler|sched_getparam|sched_setaffinity|sched_getaffinity|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|restart_syscall|kill|tkill|tgkill|sigaltstack|rt_sigsuspend|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigreturn|setpriority|getpriority|reboot|setregid|setgid|setreuid|setuid|setresuid|getresuid|setresgid|getresgid|setfsuid|setfsgid|times|setpgid|getpgid|getsid|setsid|getgroups|setgroups|uname|sethostname|setdomainname|getrlimit|setrlimit|getrusage|umask|prctl|getcpu|gettimeofday|settimeofday|adjtimex|getpid|getppid|getuid|geteuid|getgid|getegid|gettid|sysinfo
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 17, 16), //socket|socketpair|bind|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 16, 15), //connect|getsockname|getpeername|sendto|recvfrom|setsockopt|getsockopt|shutdown|sendmsg|recvmsg|readahead|brk|munmap|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 15, 14), //socket|socketpair|bind|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 14, 13), //connect|getsockname|getpeername|sendto|recvfrom|setsockopt|getsockopt|shutdown|sendmsg|recvmsg|readahead|brk|munmap|mremap
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 266, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 240, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 226, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 12, 11), //clone|execve|mmap|fadvise64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 234, 11, 10), //mprotect|msync|mlock|munlock|mlockall|munlockall|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 10, 9), //clone|execve|mmap|fadvise64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 234, 9, 8), //mprotect|msync|mlock|munlock|mlockall|munlockall|mincore|madvise
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 260, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 9, 8), //rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 8, 7), //wait4|prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 281, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 7, 6), //rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 6, 5), //wait4|prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 274, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 5, 4), //clock_adjtime|syncfs|setns|sendmmsg|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 4, 3), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 3, 2), //clock_adjtime|syncfs|setns|sendmmsg|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 2, 1), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t arm64_filter_size = sizeof(arm64_filter) / sizeof(struct sock_filter);
+const size_t arm64_system_filter_size = sizeof(arm64_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm_app_policy.cpp b/libc/seccomp/arm_app_policy.cpp
new file mode 100644
index 0000000..b5d98dc
--- /dev/null
+++ b/libc/seccomp/arm_app_policy.cpp
@@ -0,0 +1,143 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter arm_app_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 132),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 65, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 33, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 17, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 124, 123), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 123, 122), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 122, 121), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 120, 119), //lseek|getpid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 119, 118), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 116, 115), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 115, 114), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 113, 112), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 112, 111), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 108, 107), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 107, 106), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 105, 104), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 61, 104, 103), //umask
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 75, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 101, 100), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 100, 99), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 98, 97), //setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 97, 96), //getrusage|gettimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 122, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 92, 91), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 91, 90), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 89, 88), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 88, 87), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 85, 84), //setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 84, 83), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 82, 81), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 121, 81, 80), //fsync|sigreturn|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 125, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 77, 76), //uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 76, 75), //mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 74, 73), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 73, 72), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 70, 69), //_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 69, 68), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 67, 66), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 66, 65), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 33, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 17, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 207, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 186, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 185, 59, 58), //getcwd|capget
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 58, 57), //sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 57, 56), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 204, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 55, 54), //getuid32|getgid32|geteuid32|getegid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 206, 54, 53), //setregid32|getgroups32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 211, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 209, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 208, 51, 50), //fchown32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 210, 50, 49), //getresuid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 48, 47), //getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 47, 46), //getdents64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 263, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 43, 42), //mincore|madvise|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 42, 41), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 40, 39), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 39, 38), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 36, 35), //clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 35, 34), //arm_fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 33, 32), //waitid|socket|bind|connect|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 32, 31), //getsockname|getpeername|socketpair
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 27, 26), //sendto
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 26, 25), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 24, 23), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 23, 22), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 20, 19), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 19, 18), //splice|sync_file_range2|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 17, 16), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 16, 15), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 387, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 373, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 12, 11), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 11, 10), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 9, 8), //syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 386, 8, 7), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 5, 4), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 4, 3), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983043, 2, 1), //__ARM_NR_cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983046, 1, 0), //__ARM_NR_set_tls
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t arm_app_filter_size = sizeof(arm_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm_global_policy.cpp b/libc/seccomp/arm_global_policy.cpp
index d7b5d7e..ea158a5 100644
--- a/libc/seccomp/arm_global_policy.cpp
+++ b/libc/seccomp/arm_global_policy.cpp
@@ -5,132 +5,130 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter arm_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 130),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 65, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 33, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 17, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 128),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 63, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 122, 121), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 121, 120), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 120, 119), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 118, 117), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 117, 116), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 114, 113), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 113, 112), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 111, 110), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 110, 109), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 106, 105), //brk
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 105, 104), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 103, 102), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 102, 101), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 99, 98), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 98, 97), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 96, 95), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 95, 94), //sethostname|setrlimit
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 90, 89), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 89, 88), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 87, 86), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 86, 85), //munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 83, 82), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 82, 81), //getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 80, 79), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 79, 78), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 75, 74), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 74, 73), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 72, 71), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 71, 70), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 68, 67), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 67, 66), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 65, 64), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 64, 63), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 309, 31, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 58, 57), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 57, 56), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 55, 54), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 54, 53), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 51, 50), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 50, 49), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 48, 47), //getdents64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 47, 46), //mincore|madvise|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 43, 42), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 42, 41), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 40, 39), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 39, 38), //arm_fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 36, 35), //waitid|socket|bind|connect|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 35, 34), //getsockname|getpeername|socketpair
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 33, 32), //sendto
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 32, 31), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 310, 27, 26), //add_key
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 26, 25), //keyctl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 24, 23), //inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 23, 22), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 20, 19), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 19, 18), //splice|sync_file_range2|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 17, 16), //getcpu|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 16, 15), //utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 387, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 12, 11), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 11, 10), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 379, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 9, 8), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 386, 8, 7), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 121, 120), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 120, 119), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 118, 117), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 117, 116), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 114, 113), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 113, 112), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 111, 110), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 110, 109), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 106, 105), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 105, 104), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 103, 102), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 102, 101), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 99, 98), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 98, 97), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 96, 95), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 95, 94), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 90, 89), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 89, 88), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 87, 86), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 86, 85), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 83, 82), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 82, 81), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 80, 79), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 79, 78), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 75, 74), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 74, 73), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 72, 71), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 71, 70), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 68, 67), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 67, 66), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 65, 64), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 64, 63), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 58, 57), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 57, 56), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 55, 54), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 54, 53), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 51, 50), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 50, 49), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 48, 47), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 47, 46), //getdents64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 43, 42), //mincore|madvise|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 42, 41), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 40, 39), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 39, 38), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 36, 35), //arm_fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 35, 34), //waitid|socket|bind|connect|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 33, 32), //getsockname|getpeername|socketpair
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 32, 31), //sendto
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 309, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 27, 26), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 310, 26, 25), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 24, 23), //keyctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 23, 22), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 20, 19), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 19, 18), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 17, 16), //splice|sync_file_range2|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 16, 15), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 379, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 12, 11), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 11, 10), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 9, 8), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 8, 7), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 5, 4), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 5, 4), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 4, 3), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983043, 2, 1), //__ARM_NR_cacheflush
diff --git a/libc/seccomp/arm_policy.cpp b/libc/seccomp/arm_policy.cpp
deleted file mode 100644
index 2bc168a..0000000
--- a/libc/seccomp/arm_policy.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-// Autogenerated file - edit at your peril!!
-
-#include <linux/filter.h>
-#include <errno.h>
-
-#include "seccomp_bpfs.h"
-const sock_filter arm_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 126),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 63, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 119, 118), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 118, 117), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 116, 115), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 115, 114), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 112, 111), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 111, 110), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 109, 108), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 108, 107), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 104, 103), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 103, 102), //brk
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 101, 100), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 100, 99), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 97, 96), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 96, 95), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 94, 93), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 93, 92), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 88, 87), //sethostname|setrlimit
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 87, 86), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 88, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 85, 84), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 84, 83), //reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 81, 80), //munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 80, 79), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 78, 77), //getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 77, 76), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 73, 72), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 72, 71), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 70, 69), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 69, 68), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 66, 65), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 65, 64), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 63, 62), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 62, 61), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 31, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 56, 55), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 55, 54), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 53, 52), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 52, 51), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 49, 48), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 48, 47), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 46, 45), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 45, 44), //getdents64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 41, 40), //mincore|madvise|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 40, 39), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 38, 37), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 37, 36), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 34, 33), //arm_fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 33, 32), //waitid|socket|bind|connect|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 31, 30), //getsockname|getpeername|socketpair
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 30, 29), //sendto
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 25, 24), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 24, 23), //inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 22, 21), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 21, 20), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 18, 17), //splice|sync_file_range2|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 17, 16), //getcpu|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 15, 14), //utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 14, 13), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 10, 9), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 9, 8), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 387, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 386, 7, 6), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 6, 5), //execveat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 3, 2), //mlock2|copy_file_range|preadv2|pwritev2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983043, 2, 1), //__ARM_NR_cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983046, 1, 0), //__ARM_NR_set_tls
-BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
-};
-
-const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm_system_policy.cpp b/libc/seccomp/arm_system_policy.cpp
new file mode 100644
index 0000000..18df03b
--- /dev/null
+++ b/libc/seccomp/arm_system_policy.cpp
@@ -0,0 +1,135 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter arm_system_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 124),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 61, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 117, 116), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 116, 115), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 114, 113), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 113, 112), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 110, 109), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 109, 108), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 107, 106), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 106, 105), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 102, 101), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 101, 100), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 99, 98), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 98, 97), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 95, 94), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 94, 93), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 92, 91), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 91, 90), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 86, 85), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 85, 84), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 88, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 83, 82), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 82, 81), //reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 79, 78), //munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 78, 77), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 76, 75), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 75, 74), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 71, 70), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 70, 69), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 68, 67), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 67, 66), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 64, 63), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 63, 62), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 62, 61), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 290, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 56, 55), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 55, 54), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 53, 52), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 52, 51), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 49, 48), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 48, 47), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 46, 45), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 45, 44), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 219, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 41, 40), //getdents64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 40, 39), //mincore|madvise|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 249, 38, 37), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 37, 36), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 270, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 269, 34, 33), //set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 33, 32), //arm_fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 31, 30), //waitid|socket|bind|connect|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 30, 29), //getsockname|getpeername|socketpair
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 327, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 316, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 292, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 25, 24), //sendto
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 298, 24, 23), //recvfrom|shutdown|setsockopt|getsockopt|sendmsg|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 319, 22, 21), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 326, 21, 20), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 338, 18, 17), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 17, 16), //splice|sync_file_range2|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 348, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 347, 15, 14), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 14, 13), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 390, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 372, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 369, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 367, 10, 9), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg|accept4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 370, 9, 8), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 378, 7, 6), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 388, 6, 5), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983045, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983042, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 394, 3, 2), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983043, 2, 1), //__ARM_NR_cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 983046, 1, 0), //__ARM_NR_set_tls
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t arm_system_filter_size = sizeof(arm_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/include/seccomp_policy.h b/libc/seccomp/include/seccomp_policy.h
index e337dec..add17b9 100644
--- a/libc/seccomp/include/seccomp_policy.h
+++ b/libc/seccomp/include/seccomp_policy.h
@@ -20,8 +20,8 @@
 #include <stddef.h>
 #include <linux/filter.h>
 
-bool set_seccomp_filter();
+bool set_app_seccomp_filter();
+bool set_system_seccomp_filter();
 bool set_global_seccomp_filter();
-void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size);
 
 #endif
diff --git a/libc/seccomp/mips64_app_policy.cpp b/libc/seccomp/mips64_app_policy.cpp
new file mode 100644
index 0000000..6ff4d9a
--- /dev/null
+++ b/libc/seccomp/mips64_app_policy.cpp
@@ -0,0 +1,111 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter mips64_app_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 100),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5137, 49, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5091, 25, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5038, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5023, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5005, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5003, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5002, 93, 92), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5004, 92, 91), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5008, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5006, 90, 89), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5020, 89, 88), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5034, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5031, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5028, 86, 85), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5032, 85, 84), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5037, 84, 83), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5070, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5057, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5043, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5042, 80, 79), //getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5056, 79, 78), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5062, 78, 77), //execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5089, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5076, 75, 74), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5080, 74, 73), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5090, 73, 72), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5116, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5105, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5102, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5093, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5092, 68, 67), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5101, 67, 66), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5103, 66, 65), //getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5112, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5110, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5109, 63, 62), //geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5111, 62, 61), //setsid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5114, 61, 60), //setregid|getgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5125, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5122, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5117, 57, 56), //getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5120, 56, 55), //getresgid|getpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5124, 55, 54), //getsid|capget
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5134, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5132, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5130, 52, 51), //rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5133, 51, 50), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5136, 50, 49), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 25, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5194, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5157, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5153, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5151, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5150, 44, 43), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5152, 43, 42), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5155, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5154, 41, 40), //prctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5156, 40, 39), //setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5178, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5158, 37, 36), //sync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 36, 35), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 35, 34), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5211, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5200, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 31, 30), //futex|sched_setaffinity|sched_getaffinity|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 30, 29), //io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 29, 28), //epoll_ctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5222, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5215, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5214, 26, 25), //rt_sigreturn|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5221, 25, 24), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5226, 24, 23), //clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5279, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5247, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5244, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5242, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5238, 19, 18), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5243, 18, 17), //set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5246, 17, 16), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5271, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5252, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5251, 14, 13), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5267, 13, 12), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5276, 12, 11), //getcpu|epoll_pwait|ioprio_set|ioprio_get|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5308, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5301, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5297, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5295, 8, 7), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5298, 7, 6), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5306, 6, 5), //syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5319, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5316, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5315, 3, 2), //getdents64|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5317, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5323, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t mips64_app_filter_size = sizeof(mips64_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips64_global_policy.cpp b/libc/seccomp/mips64_global_policy.cpp
index 04c13b3..1084f7b 100644
--- a/libc/seccomp/mips64_global_policy.cpp
+++ b/libc/seccomp/mips64_global_policy.cpp
@@ -5,91 +5,89 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter mips64_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 86),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5168, 43, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 84),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 41, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 21, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5034, 11, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5008, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5005, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5003, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5002, 79, 78), //read|write
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5004, 78, 77), //close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5006, 77, 76), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5002, 77, 76), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5004, 76, 75), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5006, 75, 74), //fstat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5031, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5023, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5020, 74, 73), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|ioctl|pread64|pwrite64|readv|writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5028, 73, 72), //sched_yield|mremap|msync|mincore|madvise
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5032, 72, 71), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5020, 72, 71), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5028, 71, 70), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5032, 70, 69), //dup
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5057, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5043, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5038, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5037, 68, 67), //nanosleep|getitimer|setitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5042, 67, 66), //getpid|sendfile|socket|connect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5056, 66, 65), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5037, 66, 65), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5042, 65, 64), //getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5056, 64, 63), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5070, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5062, 64, 63), //execve|exit|wait4|kill|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5076, 63, 62), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5134, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5062, 62, 61), //execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5076, 61, 60), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5132, 9, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5093, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5091, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5089, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5080, 58, 57), //getcwd|chdir|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5090, 57, 56), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5092, 56, 55), //fchown
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5132, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5080, 56, 55), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5090, 55, 54), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5092, 54, 53), //fchown
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5110, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5109, 53, 52), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5130, 52, 51), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5133, 51, 50), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5153, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5151, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5137, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5136, 47, 46), //statfs|fstatfs
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5150, 46, 45), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5152, 45, 44), //pivot_root
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5163, 43, 42), //prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5167, 42, 41), //reboot|sethostname|setdomainname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5244, 21, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5211, 11, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5194, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5178, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5172, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5170, 36, 35), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 35, 34), //quotactl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5200, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 31, 30), //futex|sched_setaffinity|sched_getaffinity|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 30, 29), //io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 29, 28), //epoll_ctl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5239, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5215, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5214, 25, 24), //rt_sigreturn|set_tid_address|restart_syscall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5226, 24, 23), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5238, 23, 22), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5241, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5240, 21, 20), //add_key
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5243, 20, 19), //keyctl|set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5297, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5271, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5252, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5247, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5246, 15, 14), //inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5251, 14, 13), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5267, 13, 12), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5279, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5276, 11, 10), //getcpu|epoll_pwait|ioprio_set|ioprio_get|utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5295, 10, 9), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5316, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5307, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5300, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5298, 6, 5), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5306, 5, 4), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5315, 4, 3), //finit_module|getdents64|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5109, 52, 51), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5130, 51, 50), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5151, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5137, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5134, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5133, 47, 46), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5136, 46, 45), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5150, 45, 44), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5153, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5152, 43, 42), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5163, 42, 41), //prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2|swapon
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5241, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5178, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5172, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5168, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5167, 36, 35), //reboot|sethostname|setdomainname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5170, 35, 34), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 34, 33), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5200, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5194, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 31, 30), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 30, 29), //futex|sched_setaffinity|sched_getaffinity|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 29, 28), //io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5215, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5211, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 25, 24), //epoll_ctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5214, 24, 23), //rt_sigreturn|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5226, 23, 22), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5239, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5238, 21, 20), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5240, 20, 19), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5279, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5252, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5247, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5244, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5243, 15, 14), //keyctl|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5246, 14, 13), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5251, 13, 12), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5271, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5267, 11, 10), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5276, 10, 9), //getcpu|epoll_pwait|ioprio_set|ioprio_get|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5307, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5300, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5297, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5295, 6, 5), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5298, 5, 4), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5306, 4, 3), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5319, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5317, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5317, 2, 1), //finit_module|getdents64|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5323, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
diff --git a/libc/seccomp/mips64_policy.cpp b/libc/seccomp/mips64_policy.cpp
deleted file mode 100644
index 26967ce..0000000
--- a/libc/seccomp/mips64_policy.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-// Autogenerated file - edit at your peril!!
-
-#include <linux/filter.h>
-#include <errno.h>
-
-#include "seccomp_bpfs.h"
-const sock_filter mips64_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 84),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 41, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 21, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5034, 11, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5008, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5005, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5003, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5002, 77, 76), //read|write
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5004, 76, 75), //close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5006, 75, 74), //fstat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5031, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5023, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5020, 72, 71), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|ioctl|pread64|pwrite64|readv|writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5028, 71, 70), //sched_yield|mremap|msync|mincore|madvise
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5032, 70, 69), //dup
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5057, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5043, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5038, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5037, 66, 65), //nanosleep|getitimer|setitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5042, 65, 64), //getpid|sendfile|socket|connect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5056, 64, 63), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5070, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5062, 62, 61), //execve|exit|wait4|kill|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5076, 61, 60), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5132, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5093, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5091, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5089, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5080, 56, 55), //getcwd|chdir|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5090, 55, 54), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5092, 54, 53), //fchown
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5110, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5109, 52, 51), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5130, 51, 50), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5151, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5137, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5134, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5133, 47, 46), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5136, 46, 45), //statfs|fstatfs
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5150, 45, 44), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5153, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5152, 43, 42), //pivot_root
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5162, 42, 41), //prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5244, 21, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 11, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5178, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5172, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5168, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5167, 36, 35), //reboot|sethostname|setdomainname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5170, 35, 34), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 34, 33), //quotactl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5200, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5194, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 31, 30), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 30, 29), //futex|sched_setaffinity|sched_getaffinity|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 29, 28), //io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5215, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5211, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 25, 24), //epoll_ctl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5214, 24, 23), //rt_sigreturn|set_tid_address|restart_syscall
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5226, 23, 22), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5242, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5238, 21, 20), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5243, 20, 19), //set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5297, 9, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5271, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5252, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5247, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5246, 15, 14), //inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5251, 14, 13), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5267, 13, 12), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5279, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5276, 11, 10), //getcpu|epoll_pwait|ioprio_set|ioprio_get|utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5295, 10, 9), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5316, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5308, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5300, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5298, 6, 5), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5306, 5, 4), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5315, 4, 3), //getdents64|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5319, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5317, 2, 1), //execveat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5323, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
-BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
-};
-
-const size_t mips64_filter_size = sizeof(mips64_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips64_system_policy.cpp b/libc/seccomp/mips64_system_policy.cpp
new file mode 100644
index 0000000..6b76244
--- /dev/null
+++ b/libc/seccomp/mips64_system_policy.cpp
@@ -0,0 +1,93 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter mips64_system_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 82),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 41, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 21, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5034, 11, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5008, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5005, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5003, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5002, 75, 74), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5004, 74, 73), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5006, 73, 72), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5031, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5023, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5020, 70, 69), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5028, 69, 68), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5032, 68, 67), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5057, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5043, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5038, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5037, 64, 63), //nanosleep|getitimer|setitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5042, 63, 62), //getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5056, 62, 61), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5070, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5062, 60, 59), //execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5076, 59, 58), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5132, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5093, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5091, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5089, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5080, 54, 53), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5090, 53, 52), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5092, 52, 51), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5110, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5109, 50, 49), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid|syslog|getgid|setuid|setgid|geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5130, 49, 48), //setsid|setreuid|setregid|getgroups|setgroups|setresuid|getresuid|setresgid|getresgid|getpgid|setfsuid|setfsgid|getsid|capget|capset|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5151, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5137, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5134, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5133, 45, 44), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5136, 44, 43), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5150, 43, 42), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5153, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5152, 41, 40), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5162, 40, 39), //prctl|adjtimex|setrlimit|chroot|sync|acct|settimeofday|mount|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5242, 19, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5200, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5178, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5172, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5168, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5167, 34, 33), //reboot|sethostname|setdomainname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5170, 33, 32), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5173, 32, 31), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5194, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5193, 30, 29), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5198, 29, 28), //futex|sched_setaffinity|sched_getaffinity|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5215, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5211, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5208, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5206, 25, 24), //io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5209, 24, 23), //epoll_ctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5214, 23, 22), //rt_sigreturn|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5237, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5226, 21, 20), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5238, 20, 19), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5279, 9, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5252, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5247, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5244, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5243, 15, 14), //set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5246, 14, 13), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5251, 13, 12), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5271, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5267, 11, 10), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5276, 10, 9), //getcpu|epoll_pwait|ioprio_set|ioprio_get|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5308, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5300, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5297, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5295, 6, 5), //fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5298, 5, 4), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5306, 4, 3), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5319, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5317, 2, 1), //getdents64|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5323, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t mips64_system_filter_size = sizeof(mips64_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips_app_policy.cpp b/libc/seccomp/mips_app_policy.cpp
new file mode 100644
index 0000000..bc1a924
--- /dev/null
+++ b/libc/seccomp/mips_app_policy.cpp
@@ -0,0 +1,129 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter mips_app_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 118),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 59, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4024, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 111, 110), //exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 110, 109), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 108, 107), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4021, 107, 106), //lseek|getpid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 104, 103), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 103, 102), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 101, 100), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 100, 99), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4047, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 96, 95), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4046, 95, 94), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 93, 92), //getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4051, 92, 91), //geteuid|getegid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 89, 88), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 88, 87), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4061, 87, 86), //umask
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4104, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4080, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4071, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 82, 81), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 81, 80), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4075, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 79, 78), //setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4079, 78, 77), //setrlimit|getrlimit|getrusage|gettimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4081, 75, 74), //getgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 74, 73), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 72, 71), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 71, 70), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4122, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 67, 66), //setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 66, 65), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 64, 63), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4121, 63, 62), //fsync|sigreturn|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4125, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 60, 59), //uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 59, 58), //mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 58, 57), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4140, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 52, 51), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 51, 50), //_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 49, 48), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 48, 47), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 45, 44), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 44, 43), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4186, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4185, 42, 41), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 41, 40), //getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4191, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 37, 36), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 36, 35), //getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4206, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4205, 34, 33), //getcwd|capget
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 33, 32), //sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 30, 29), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 29, 28), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4263, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4262, 23, 22), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 22, 21), //clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4283, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 20, 19), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 19, 18), //set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 16, 15), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 15, 14), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 14, 13), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4349, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4319, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 10, 9), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 9, 8), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4342, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 7, 6), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4347, 6, 5), //syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4359, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4356, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4355, 3, 2), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4357, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4363, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t mips_app_filter_size = sizeof(mips_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips_global_policy.cpp b/libc/seccomp/mips_global_policy.cpp
index 103e544..b193c09 100644
--- a/libc/seccomp/mips_global_policy.cpp
+++ b/libc/seccomp/mips_global_policy.cpp
@@ -5,117 +5,115 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter mips_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 112),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 110),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 55, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 105, 104), //exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 104, 103), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 103, 102), //exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 102, 101), //creat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 102, 101), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 101, 100), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 100, 99), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 99, 98), //lseek|getpid|mount
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 98, 97), //setuid|getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 97, 96), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 96, 95), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 96, 95), //setuid|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 95, 94), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 94, 93), //access
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 92, 91), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 91, 90), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 90, 89), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 89, 88), //dup|pipe|times
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 89, 88), //brk|setgid|getgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 88, 87), //geteuid|getegid|acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 87, 86), //brk|setgid|getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 86, 85), //geteuid|getegid|acct|umount2
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 85, 84), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 84, 83), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 83, 82), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 83, 82), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 82, 81), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 81, 80), //umask|chroot
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 78, 77), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 77, 76), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 76, 75), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 75, 74), //setsid|sigaction
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 75, 74), //setreuid|setregid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 74, 73), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 73, 72), //setreuid|setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 72, 71), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4087, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 71, 70), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 70, 69), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 69, 68), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 69, 68), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 68, 67), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 67, 66), //mmap|munmap|truncate
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 65, 64), //fchmod|fchown|getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 64, 63), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 63, 62), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 62, 61), //syslog|setitimer|getitimer
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 62, 61), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 61, 60), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 60, 59), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 59, 58), //sysinfo
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 58, 57), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 57, 56), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 56, 55), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 56, 55), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 55, 54), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 54, 53), //init_module|delete_module
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 27, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 50, 49), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 49, 48), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 48, 47), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 47, 46), //personality
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 47, 46), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 46, 45), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 45, 44), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 44, 43), //getsid|fdatasync
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 43, 42), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 42, 41), //bind|connect|getpeername|getsockname|getsockopt|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 41, 40), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 41, 40), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 40, 39), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 39, 38), //recvfrom|recvmsg
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 37, 36), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 36, 35), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 35, 34), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 34, 33), //poll
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 34, 33), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 33, 32), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 32, 31), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 31, 30), //getcwd|capget|capset|sigaltstack|sendfile
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 30, 29), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 29, 28), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 28, 27), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 28, 27), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 27, 26), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 26, 25), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4280, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 23, 22), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 22, 21), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 21, 20), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 20, 19), //waitid
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4282, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4281, 20, 19), //add_key
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 19, 18), //keyctl|set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4281, 18, 17), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 17, 16), //keyctl|set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 16, 15), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 15, 14), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 14, 13), //getcpu|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4348, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 14, 13), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 13, 12), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 12, 11), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4319, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 10, 9), //utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 9, 8), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 7, 6), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4347, 6, 5), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 8, 7), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 7, 6), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 6, 5), //prlimit64
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4359, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4356, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4355, 3, 2), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4357, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4348, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4347, 3, 2), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4357, 2, 1), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4363, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
diff --git a/libc/seccomp/mips_policy.cpp b/libc/seccomp/mips_policy.cpp
deleted file mode 100644
index 7485b90..0000000
--- a/libc/seccomp/mips_policy.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Autogenerated file - edit at your peril!!
-
-#include <linux/filter.h>
-#include <errno.h>
-
-#include "seccomp_bpfs.h"
-const sock_filter mips_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 110),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 55, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 103, 102), //exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 102, 101), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 100, 99), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 99, 98), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 96, 95), //setuid|getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 95, 94), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 94, 93), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 90, 89), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 89, 88), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 87, 86), //brk|setgid|getgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 86, 85), //geteuid|getegid|acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 83, 82), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 82, 81), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 81, 80), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 76, 75), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 75, 74), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 73, 72), //setreuid|setregid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 72, 71), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4088, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 69, 68), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 68, 67), //reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 67, 66), //mmap|munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 63, 62), //fchmod|fchown|getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 62, 61), //syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 60, 59), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 59, 58), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 56, 55), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 55, 54), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 54, 53), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 27, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 48, 47), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 47, 46), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 45, 44), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 44, 43), //getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 41, 40), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 40, 39), //bind|connect|getpeername|getsockname|getsockopt|listen
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 39, 38), //recvfrom|recvmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 35, 34), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 34, 33), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 32, 31), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 31, 30), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 28, 27), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 27, 26), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 26, 25), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4319, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4283, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 21, 20), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 20, 19), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 18, 17), //set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 17, 16), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 14, 13), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 13, 12), //getcpu|epoll_pwait
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 12, 11), //utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4349, 5, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 8, 7), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 7, 6), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4347, 6, 5), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4359, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4356, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4355, 3, 2), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4357, 2, 1), //execveat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4363, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
-BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
-};
-
-const size_t mips_filter_size = sizeof(mips_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips_system_policy.cpp b/libc/seccomp/mips_system_policy.cpp
new file mode 100644
index 0000000..a88a6e3
--- /dev/null
+++ b/libc/seccomp/mips_system_policy.cpp
@@ -0,0 +1,119 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter mips_system_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 108),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4128, 53, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4036, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4023, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4010, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4008, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4007, 101, 100), //exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4009, 100, 99), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4019, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4013, 98, 97), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4022, 97, 96), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4033, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4026, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4025, 94, 93), //setuid|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4027, 93, 92), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4034, 92, 91), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4054, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4045, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4041, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4040, 88, 87), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4044, 87, 86), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4049, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4048, 85, 84), //brk|setgid|getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4053, 84, 83), //geteuid|getegid|acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4060, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4057, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4056, 81, 80), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4058, 80, 79), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4062, 79, 78), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4094, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4085, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4070, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4066, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4065, 74, 73), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4068, 73, 72), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4074, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4072, 71, 70), //setreuid|setregid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4082, 70, 69), //sethostname|setrlimit|getrlimit|getrusage|gettimeofday|settimeofday|getgroups|setgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4090, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4088, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4086, 67, 66), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4089, 66, 65), //reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4093, 65, 64), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4116, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4114, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4103, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4098, 61, 60), //fchmod|fchown|getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4106, 60, 59), //syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4115, 59, 58), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4124, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4117, 56, 55), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4123, 55, 54), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4126, 54, 53), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4222, 27, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4176, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4151, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4136, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4130, 48, 47), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4134, 47, 46), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4138, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4137, 45, 44), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4148, 44, 43), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|cacheflush
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4169, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4154, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4153, 41, 40), //getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4168, 40, 39), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4175, 39, 38), //bind|connect|getpeername|getsockname|getsockopt|listen
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4203, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4188, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4179, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4178, 35, 34), //recvfrom|recvmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4187, 34, 33), //sendmsg|sendto|setsockopt|shutdown|socket|socketpair|setresuid|getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4190, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4189, 32, 31), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4202, 31, 30), //setresgid|getresgid|prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4217, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4210, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4208, 28, 27), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4216, 27, 26), //mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4221, 26, 25), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4316, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4288, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4278, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4248, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4247, 21, 20), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|io_setup|io_destroy|io_getevents|io_submit|io_cancel|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4267, 20, 19), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|restart_syscall|fadvise64|statfs64|fstatfs64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4283, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4279, 18, 17), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4287, 17, 16), //set_thread_area|inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4312, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4293, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4292, 14, 13), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4308, 13, 12), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare|splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4314, 12, 11), //getcpu|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4341, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4338, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4319, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4317, 8, 7), //utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4336, 7, 6), //eventfd|fallocate|timerfd_create|timerfd_gettime|timerfd_settime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|accept4|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4339, 6, 5), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4359, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4349, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4347, 3, 2), //clock_adjtime|syncfs|sendmmsg|setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4357, 2, 1), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4363, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t mips_system_filter_size = sizeof(mips_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/seccomp_bpfs.h b/libc/seccomp/seccomp_bpfs.h
index a8f47ca..8728c36 100644
--- a/libc/seccomp/seccomp_bpfs.h
+++ b/libc/seccomp/seccomp_bpfs.h
@@ -20,28 +20,45 @@
 #include <stddef.h>
 #include <linux/seccomp.h>
 
-extern const struct sock_filter arm_filter[];
-extern const size_t arm_filter_size;
+extern const struct sock_filter arm_app_filter[];
+extern const size_t arm_app_filter_size;
+extern const struct sock_filter arm_system_filter[];
+extern const size_t arm_system_filter_size;
 extern const struct sock_filter arm_global_filter[];
 extern const size_t arm_global_filter_size;
-extern const struct sock_filter arm64_filter[];
-extern const size_t arm64_filter_size;
+
+extern const struct sock_filter arm64_app_filter[];
+extern const size_t arm64_app_filter_size;
+extern const struct sock_filter arm64_system_filter[];
+extern const size_t arm64_system_filter_size;
 extern const struct sock_filter arm64_global_filter[];
 extern const size_t arm64_global_filter_size;
-extern const struct sock_filter x86_filter[];
-extern const size_t x86_filter_size;
+
+extern const struct sock_filter x86_app_filter[];
+extern const size_t x86_app_filter_size;
+extern const struct sock_filter x86_system_filter[];
+extern const size_t x86_system_filter_size;
 extern const struct sock_filter x86_global_filter[];
 extern const size_t x86_global_filter_size;
-extern const struct sock_filter x86_64_filter[];
-extern const size_t x86_64_filter_size;
+
+extern const struct sock_filter x86_64_app_filter[];
+extern const size_t x86_64_app_filter_size;
+extern const struct sock_filter x86_64_system_filter[];
+extern const size_t x86_64_system_filter_size;
 extern const struct sock_filter x86_64_global_filter[];
 extern const size_t x86_64_global_filter_size;
-extern const struct sock_filter mips_filter[];
-extern const size_t mips_filter_size;
+
+extern const struct sock_filter mips_app_filter[];
+extern const size_t mips_app_filter_size;
+extern const struct sock_filter mips_system_filter[];
+extern const size_t mips_system_filter_size;
 extern const struct sock_filter mips_global_filter[];
 extern const size_t mips_global_filter_size;
-extern const struct sock_filter mips64_filter[];
-extern const size_t mips64_filter_size;
+
+extern const struct sock_filter mips64_app_filter[];
+extern const size_t mips64_app_filter_size;
+extern const struct sock_filter mips64_system_filter[];
+extern const size_t mips64_system_filter_size;
 extern const struct sock_filter mips64_global_filter[];
 extern const size_t mips64_global_filter_size;
 
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index 19ef299..3d617be 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -32,13 +32,17 @@
 
 #define DUAL_ARCH
 #define PRIMARY_ARCH AUDIT_ARCH_AARCH64
-static const struct sock_filter* primary_filter = arm64_filter;
-static const size_t primary_filter_size = arm64_filter_size;
+static const struct sock_filter* primary_app_filter = arm64_app_filter;
+static const size_t primary_app_filter_size = arm64_app_filter_size;
+static const struct sock_filter* primary_system_filter = arm64_system_filter;
+static const size_t primary_system_filter_size = arm64_system_filter_size;
 static const struct sock_filter* primary_global_filter = arm64_global_filter;
 static const size_t primary_global_filter_size = arm64_global_filter_size;
 #define SECONDARY_ARCH AUDIT_ARCH_ARM
-static const struct sock_filter* secondary_filter = arm_filter;
-static const size_t secondary_filter_size = arm_filter_size;
+static const struct sock_filter* secondary_app_filter = arm_app_filter;
+static const size_t secondary_app_filter_size = arm_app_filter_size;
+static const struct sock_filter* secondary_system_filter = arm_system_filter;
+static const size_t secondary_system_filter_size = arm_system_filter_size;
 static const struct sock_filter* secondary_global_filter = arm_global_filter;
 static const size_t secondary_global_filter_size = arm_global_filter_size;
 
@@ -46,13 +50,17 @@
 
 #define DUAL_ARCH
 #define PRIMARY_ARCH AUDIT_ARCH_X86_64
-static const struct sock_filter* primary_filter = x86_64_filter;
-static const size_t primary_filter_size = x86_64_filter_size;
+static const struct sock_filter* primary_app_filter = x86_64_app_filter;
+static const size_t primary_app_filter_size = x86_64_app_filter_size;
+static const struct sock_filter* primary_system_filter = x86_64_system_filter;
+static const size_t primary_system_filter_size = x86_64_system_filter_size;
 static const struct sock_filter* primary_global_filter = x86_64_global_filter;
 static const size_t primary_global_filter_size = x86_64_global_filter_size;
 #define SECONDARY_ARCH AUDIT_ARCH_I386
-static const struct sock_filter* secondary_filter = x86_filter;
-static const size_t secondary_filter_size = x86_filter_size;
+static const struct sock_filter* secondary_app_filter = x86_app_filter;
+static const size_t secondary_app_filter_size = x86_app_filter_size;
+static const struct sock_filter* secondary_system_filter = x86_system_filter;
+static const size_t secondary_system_filter_size = x86_system_filter_size;
 static const struct sock_filter* secondary_global_filter = x86_global_filter;
 static const size_t secondary_global_filter_size = x86_global_filter_size;
 
@@ -60,13 +68,17 @@
 
 #define DUAL_ARCH
 #define PRIMARY_ARCH AUDIT_ARCH_MIPSEL64
-static const struct sock_filter* primary_filter = mips64_filter;
-static const size_t primary_filter_size = mips64_filter_size;
+static const struct sock_filter* primary_app_filter = mips64_app_filter;
+static const size_t primary_app_filter_size = mips64_app_filter_size;
+static const struct sock_filter* primary_system_filter = mips64_system_filter;
+static const size_t primary_system_filter_size = mips64_system_filter_size;
 static const struct sock_filter* primary_global_filter = mips64_global_filter;
 static const size_t primary_global_filter_size = mips64_global_filter_size;
 #define SECONDARY_ARCH AUDIT_ARCH_MIPSEL
-static const struct sock_filter* secondary_filter = mips_filter;
-static const size_t secondary_filter_size = mips_filter_size;
+static const struct sock_filter* secondary_app_filter = mips_app_filter;
+static const size_t secondary_app_filter_size = mips_app_filter_size;
+static const struct sock_filter* secondary_system_filter = mips_system_filter;
+static const size_t secondary_system_filter_size = mips_system_filter_size;
 static const struct sock_filter* secondary_global_filter = mips_global_filter;
 static const size_t secondary_global_filter_size = mips_global_filter_size;
 
@@ -121,31 +133,45 @@
         static_cast<unsigned short>(f.size()),
         const_cast<struct sock_filter*>(&f[0]),
     };
-
+    // This assumes either the current process has CAP_SYS_ADMIN, or PR_SET_NO_NEW_PRIVS bit is set.
     if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
         PLOG(FATAL) << "Could not set seccomp filter of size " << f.size();
         return false;
     }
-
-    LOG(INFO) << "Global filter of size " << f.size() << " installed";
     return true;
 }
 
-bool _set_seccomp_filter(bool global) {
+enum FilterType {
+  APP,
+  SYSTEM,
+  GLOBAL
+};
+
+bool _set_seccomp_filter(FilterType type) {
     const sock_filter *p, *s;
     size_t p_size, s_size;
     filter f;
 
-    if (global) {
+    switch (type) {
+      case APP:
+        p = primary_app_filter;
+        p_size = primary_app_filter_size;
+        s = secondary_app_filter;
+        s_size = secondary_app_filter_size;
+        break;
+      case SYSTEM:
+        p = primary_system_filter;
+        p_size = primary_system_filter_size;
+        s = secondary_system_filter;
+        s_size = secondary_system_filter_size;
+        break;
+      case GLOBAL:
         p = primary_global_filter;
         p_size = primary_global_filter_size;
         s = secondary_global_filter;
         s_size = secondary_global_filter_size;
-    } else {
-        p = primary_filter;
-        p_size = primary_filter_size;
-        s = secondary_filter;
-        s_size = secondary_filter_size;
+        break;
+
     }
 
 #ifdef DUAL_ARCH
@@ -180,20 +206,14 @@
     return install_filter(f);
 }
 
-bool set_seccomp_filter() {
-    return _set_seccomp_filter(false);
+bool set_app_seccomp_filter() {
+    return _set_seccomp_filter(FilterType::APP);
+}
+
+bool set_system_seccomp_filter() {
+    return _set_seccomp_filter(FilterType::SYSTEM);
 }
 
 bool set_global_seccomp_filter() {
-    return _set_seccomp_filter(true);
-}
-
-void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size) {
-#if defined __aarch64__ || defined __x86_64__ || defined __mips64__
-    filter = primary_filter;
-    filter_size = primary_filter_size;
-#else
-    filter = secondary_filter;
-    filter_size = secondary_filter_size;
-#endif
+    return _set_seccomp_filter(FilterType::GLOBAL);
 }
diff --git a/libc/seccomp/x86_64_app_policy.cpp b/libc/seccomp/x86_64_app_policy.cpp
new file mode 100644
index 0000000..b90124b
--- /dev/null
+++ b/libc/seccomp/x86_64_app_policy.cpp
@@ -0,0 +1,115 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter x86_64_app_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 104),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 155, 51, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 25, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 38, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 3, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 2, 97, 96), //read|write
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4, 96, 95), //close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 6, 94, 93), //fstat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 93, 92), //lseek|mmap|mprotect|munmap|brk|rt_sigaction|rt_sigprocmask|rt_sigreturn|ioctl|pread64|pwrite64|readv|writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 35, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 32, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 29, 90, 89), //sched_yield|mremap|msync|mincore|madvise
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 89, 88), //dup
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 37, 88, 87), //nanosleep|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 72, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 43, 84, 83), //setitimer|getpid|sendfile|socket|connect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 83, 82), //sendto|recvfrom|sendmsg|recvmsg|shutdown|bind|listen|getsockname|getpeername|socketpair|setsockopt|getsockopt|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 64, 82, 81), //vfork|execve|exit|wait4|kill|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 91, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 78, 79, 78), //fcntl|flock|fsync|fdatasync|truncate|ftruncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 82, 78, 77), //getcwd|chdir|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 92, 77, 76), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 120, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 112, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 72, 71), //fchown
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 71, 70), //umask|gettimeofday|getrlimit|getrusage|sysinfo|times|ptrace|getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 107, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 105, 69, 68), //getgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 111, 68, 67), //geteuid|getegid|setpgid|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 113, 65, 64), //setsid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 64, 63), //setregid|getgroups
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 119, 63, 62), //getresuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 135, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 127, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 122, 59, 58), //getresgid|getpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 58, 57), //getsid|capget
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 132, 57, 56), //rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|sigaltstack
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 54, 53), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 139, 53, 52), //statfs|fstatfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 153, 52, 51), //getpriority|setpriority|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|mlock|munlock|mlockall|munlockall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 251, 25, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 206, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 179, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 160, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 157, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 156, 46, 45), //pivot_root
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 159, 45, 44), //prctl|arch_prctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 162, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 161, 43, 42), //setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 163, 42, 41), //sync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 202, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 186, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 180, 39, 38), //quotactl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 201, 38, 37), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 205, 37, 36), //futex|sched_setaffinity|sched_getaffinity
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 228, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 221, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 217, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 211, 33, 32), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 32, 31), //getdents64|set_tid_address|restart_syscall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 227, 31, 30), //fadvise64|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 247, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 233, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 232, 28, 27), //clock_gettime|clock_getres|clock_nanosleep|exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 235, 27, 26), //epoll_ctl|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 248, 26, 25), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 275, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 257, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 21, 20), //ioprio_set|ioprio_get
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 256, 20, 19), //inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 262, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 261, 18, 17), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 17, 16), //newfstatat|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 283, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 280, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 279, 14, 13), //splice|tee|sync_file_range|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 13, 12), //utimensat|epoll_pwait
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 12, 11), //timerfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 314, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 306, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 302, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 8, 7), //fallocate|timerfd_settime|timerfd_gettime|accept4|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 303, 7, 6), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 6, 5), //syncfs|sendmmsg|setns|getcpu|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 325, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 320, 3, 2), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 329, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t x86_64_app_filter_size = sizeof(x86_64_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_64_global_policy.cpp b/libc/seccomp/x86_64_global_policy.cpp
index 801d6c2..8142ce4 100644
--- a/libc/seccomp/x86_64_global_policy.cpp
+++ b/libc/seccomp/x86_64_global_policy.cpp
@@ -84,14 +84,14 @@
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 12, 11), //utimensat|epoll_pwait
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 11, 10), //timerfd_create
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 10, 9), //fallocate|timerfd_settime|timerfd_gettime|accept4|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 305, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 303, 6, 5), //prlimit64
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 5, 4), //clock_adjtime|syncfs|sendmmsg|setns|getcpu|process_vm_readv|process_vm_writev
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 320, 4, 3), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 325, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 2, 1), //bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 329, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
diff --git a/libc/seccomp/x86_64_policy.cpp b/libc/seccomp/x86_64_system_policy.cpp
similarity index 95%
rename from libc/seccomp/x86_64_policy.cpp
rename to libc/seccomp/x86_64_system_policy.cpp
index 025e24f..67859eb 100644
--- a/libc/seccomp/x86_64_policy.cpp
+++ b/libc/seccomp/x86_64_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter x86_64_filter[] = {
+const sock_filter x86_64_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 88),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 175, 43, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 21, 0),
@@ -84,16 +84,16 @@
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 282, 12, 11), //utimensat|epoll_pwait
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 11, 10), //timerfd_create
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 10, 9), //fallocate|timerfd_settime|timerfd_gettime|accept4|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open|recvmmsg
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 5, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 5, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 314, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 305, 1, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 303, 6, 5), //prlimit64
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 312, 5, 4), //clock_adjtime|syncfs|sendmmsg|setns|getcpu|process_vm_readv|process_vm_writev
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 320, 4, 3), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 325, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 323, 2, 1), //bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 329, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t x86_64_filter_size = sizeof(x86_64_filter) / sizeof(struct sock_filter);
+const size_t x86_64_system_filter_size = sizeof(x86_64_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_app_policy.cpp b/libc/seccomp/x86_app_policy.cpp
new file mode 100644
index 0000000..5131efa
--- /dev/null
+++ b/libc/seccomp/x86_app_policy.cpp
@@ -0,0 +1,135 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter x86_app_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 124),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 61, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 117, 116), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 116, 115), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 114, 113), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 21, 113, 112), //lseek|getpid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 110, 109), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 109, 108), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 107, 106), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 106, 105), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 102, 101), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 101, 100), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 99, 98), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 98, 97), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 61, 95, 94), //umask
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 94, 93), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 75, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 92, 91), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 91, 90), //setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 86, 85), //getrusage|gettimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 85, 84), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 83, 82), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 82, 81), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 104, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 79, 78), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 103, 78, 77), //socketcall
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 76, 75), //setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 75, 74), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 122, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 71, 70), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 121, 70, 69), //fsync|sigreturn|clone
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 125, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 68, 67), //uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 67, 66), //mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 140, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 64, 63), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 63, 62), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 62, 61), //_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 265, 31, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 207, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 186, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 56, 55), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 55, 54), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 53, 52), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 185, 52, 51), //getcwd|capget
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 49, 48), //sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 48, 47), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 204, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 203, 46, 45), //getuid32|getgid32|geteuid32|getegid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 206, 45, 44), //setregid32|getgroups32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 211, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 209, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 208, 41, 40), //fchown32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 210, 40, 39), //getresuid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 38, 37), //getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 37, 36), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 33, 32), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 31, 30), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 264, 30, 29), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 25, 24), //clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 24, 23), //fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 22, 21), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 21, 20), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 18, 17), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 17, 16), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 15, 14), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 14, 13), //getcpu|epoll_pwait|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 351, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 344, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 10, 9), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 9, 8), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 7, 6), //syncfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 6, 5), //setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 376, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 358, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 357, 3, 2), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 359, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t x86_app_filter_size = sizeof(x86_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_global_policy.cpp b/libc/seccomp/x86_global_policy.cpp
index 9305729..3fd06ee 100644
--- a/libc/seccomp/x86_global_policy.cpp
+++ b/libc/seccomp/x86_global_policy.cpp
@@ -5,125 +5,123 @@
 
 #include "seccomp_bpfs.h"
 const sock_filter x86_global_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 120),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 118),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 59, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 113, 112), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 112, 111), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 111, 110), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 110, 109), //creat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 110, 109), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 109, 108), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 108, 107), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 107, 106), //lseek|getpid|mount
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 106, 105), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 105, 104), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 104, 103), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 103, 102), //ptrace
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 103, 102), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 102, 101), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 101, 100), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 100, 99), //sync|kill|rename|mkdir
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 98, 97), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 97, 96), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 96, 95), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 95, 94), //brk
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 95, 94), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 94, 93), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 93, 92), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 92, 91), //ioctl|fcntl
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 91, 90), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 90, 89), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 89, 88), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 89, 88), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 88, 87), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 87, 86), //dup2|getppid
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 87, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 84, 83), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 83, 82), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 82, 81), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 81, 80), //sethostname|setrlimit
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 81, 80), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 80, 79), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 79, 78), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 78, 77), //readlink
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 77, 76), //swapon|reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 76, 75), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 75, 74), //swapon|reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 74, 73), //mmap|munmap|truncate
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 74, 73), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 73, 72), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 72, 71), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 71, 70), //getpriority|setpriority
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 69, 68), //socketcall|syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 68, 67), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 67, 66), //socketcall|syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 66, 65), //wait4
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 66, 65), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 65, 64), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 64, 63), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 63, 62), //fsync|sigreturn|clone|setdomainname|uname
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 62, 61), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 61, 60), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 60, 59), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 60, 59), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 59, 58), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 58, 57), //quotactl|getpgid|fchdir
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 29, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 54, 53), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 53, 52), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 52, 51), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 51, 50), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 51, 50), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 50, 49), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 49, 48), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 48, 47), //poll
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 47, 46), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 46, 45), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 45, 44), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 44, 43), //getcwd|capget|capset|sigaltstack|sendfile
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 44, 43), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 43, 42), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 42, 41), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 41, 40), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 39, 38), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 38, 37), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 37, 36), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 36, 35), //mincore|madvise|getdents64|fcntl64
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 36, 35), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 35, 34), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 34, 33), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 33, 32), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 32, 31), //exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 31, 30), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 30, 29), //fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 30, 29), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 29, 28), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 28, 27), //fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 13, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 7, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 288, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 286, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 25, 24), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 287, 24, 23), //add_key
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 23, 22), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 287, 22, 21), //add_key
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 22, 21), //keyctl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 21, 20), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 289, 20, 19), //keyctl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 19, 18), //inotify_init|inotify_add_watch|inotify_rm_watch
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 18, 17), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 17, 16), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 15, 14), //splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 14, 13), //getcpu|epoll_pwait|utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 10, 9), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 9, 8), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 7, 6), //clock_adjtime|syncfs
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 6, 5), //setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 16, 15), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 15, 14), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 14, 13), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 10, 9), //getcpu|epoll_pwait|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 9, 8), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 7, 6), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 6, 5), //clock_adjtime|syncfs
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 376, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 358, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 357, 3, 2), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 359, 2, 1), //execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 350, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 3, 2), //setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 359, 2, 1), //finit_module|sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
diff --git a/libc/seccomp/x86_policy.cpp b/libc/seccomp/x86_policy.cpp
deleted file mode 100644
index 494a42a..0000000
--- a/libc/seccomp/x86_policy.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-// Autogenerated file - edit at your peril!!
-
-#include <linux/filter.h>
-#include <errno.h>
-
-#include "seccomp_bpfs.h"
-const sock_filter x86_filter[] = {
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 116),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 57, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 109, 108), //restart_syscall|exit|fork|read|write|open|close
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 108, 107), //creat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 106, 105), //unlink|execve|chdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 105, 104), //lseek|getpid|mount
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 102, 101), //getuid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 101, 100), //ptrace
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 99, 98), //access
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 98, 97), //sync|kill|rename|mkdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 94, 93), //dup|pipe|times
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 93, 92), //brk
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 91, 90), //acct|umount2
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 90, 89), //ioctl|fcntl
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 87, 86), //setpgid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 86, 85), //umask|chroot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 85, 84), //dup2|getppid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 88, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 80, 79), //setsid|sigaction
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 79, 78), //sethostname|setrlimit
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 77, 76), //getrusage|gettimeofday|settimeofday
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 76, 75), //readlink
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 73, 72), //reboot
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 72, 71), //mmap|munmap|truncate
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 71, 70), //fchmod
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 67, 66), //getpriority|setpriority
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 66, 65), //socketcall|syslog|setitimer|getitimer
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 64, 63), //wait4
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 63, 62), //sysinfo
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 60, 59), //fsync|sigreturn|clone|setdomainname|uname
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 59, 58), //adjtimex|mprotect
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 58, 57), //init_module|delete_module
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 29, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 15, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 52, 51), //quotactl|getpgid|fchdir
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 51, 50), //personality
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 49, 48), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 48, 47), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 45, 44), //poll
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 44, 43), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 42, 41), //getcwd|capget|capset|sigaltstack|sendfile
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 41, 40), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 37, 36), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 36, 35), //setuid32|setgid32
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 34, 33), //mincore|madvise|getdents64|fcntl64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 33, 32), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 30, 29), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 29, 28), //exit_group
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 28, 27), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 13, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 23, 22), //fadvise64_64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 22, 21), //waitid
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 20, 19), //inotify_init|inotify_add_watch|inotify_rm_watch
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 19, 18), //openat|mkdirat|mknodat|fchownat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 16, 15), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 15, 14), //splice|sync_file_range|tee|vmsplice
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 14, 13), //getcpu|epoll_pwait|utimensat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 351, 7, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 10, 9), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 9, 8), //prlimit64
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 7, 6), //clock_adjtime|syncfs
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 6, 5), //setns|process_vm_readv|process_vm_writev
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 376, 3, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 358, 1, 0),
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 357, 3, 2), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 359, 2, 1), //execveat
-BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
-BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
-};
-
-const size_t x86_filter_size = sizeof(x86_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_system_policy.cpp b/libc/seccomp/x86_system_policy.cpp
new file mode 100644
index 0000000..3a34c69
--- /dev/null
+++ b/libc/seccomp/x86_system_policy.cpp
@@ -0,0 +1,125 @@
+// Autogenerated file - edit at your peril!!
+
+#include <linux/filter.h>
+#include <errno.h>
+
+#include "seccomp_bpfs.h"
+const sock_filter x86_system_filter[] = {
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 114),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 57, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 41, 15, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 24, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 10, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 8, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 7, 107, 106), //restart_syscall|exit|fork|read|write|open|close
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 9, 106, 105), //creat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 19, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 13, 104, 103), //unlink|execve|chdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 22, 103, 102), //lseek|getpid|mount
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 33, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 26, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 25, 100, 99), //getuid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 27, 99, 98), //ptrace
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 36, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 34, 97, 96), //access
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 40, 96, 95), //sync|kill|rename|mkdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 57, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 51, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 45, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 44, 92, 91), //dup|pipe|times
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 46, 91, 90), //brk
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 54, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 53, 89, 88), //acct|umount2
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 56, 88, 87), //ioctl|fcntl
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 63, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 60, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 58, 85, 84), //setpgid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 62, 84, 83), //umask|chroot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 65, 83, 82), //dup2|getppid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 96, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 88, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 77, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 68, 78, 77), //setsid|sigaction
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 76, 77, 76), //sethostname|setrlimit
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 85, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 80, 75, 74), //getrusage|gettimeofday|settimeofday
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 86, 74, 73), //readlink
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 94, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 90, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 89, 71, 70), //reboot
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 93, 70, 69), //mmap|munmap|truncate
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 95, 69, 68), //fchmod
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 118, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 114, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 102, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 98, 65, 64), //getpriority|setpriority
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 106, 64, 63), //socketcall|syslog|setitimer|getitimer
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 116, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 115, 62, 61), //wait4
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 117, 61, 60), //sysinfo
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 128, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 124, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 123, 58, 57), //fsync|sigreturn|clone|setdomainname|uname
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 126, 57, 56), //adjtimex|mprotect
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 130, 56, 55), //init_module|delete_module
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 254, 27, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 190, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 168, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 138, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 136, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 134, 50, 49), //quotactl|getpgid|fchdir
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 137, 49, 48), //personality
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 149, 47, 46), //setfsuid|setfsgid|_llseek|getdents|_newselect|flock|msync|readv|writev|getsid|fdatasync
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 164, 46, 45), //mlock|munlock|mlockall|munlockall|sched_setparam|sched_getparam|sched_setscheduler|sched_getscheduler|sched_yield|sched_get_priority_max|sched_get_priority_min|sched_rr_get_interval|nanosleep|mremap
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 183, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 172, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 169, 43, 42), //poll
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 182, 42, 41), //prctl|rt_sigreturn|rt_sigaction|rt_sigprocmask|rt_sigpending|rt_sigtimedwait|rt_sigqueueinfo|rt_sigsuspend|pread64|pwrite64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 188, 41, 40), //getcwd|capget|capset|sigaltstack|sendfile
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 224, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 213, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 199, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 198, 37, 36), //vfork|ugetrlimit|mmap2|truncate64|ftruncate64|stat64|lstat64|fstat64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 212, 36, 35), //getuid32|getgid32|geteuid32|getegid32|setreuid32|setregid32|getgroups32|setgroups32|fchown32|setresuid32|getresuid32|setresgid32|getresgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 218, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 215, 34, 33), //setuid32|setgid32
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 222, 33, 32), //mincore|madvise|getdents64|fcntl64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 252, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 245, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 244, 30, 29), //gettid|readahead|setxattr|lsetxattr|fsetxattr|getxattr|lgetxattr|fgetxattr|listxattr|llistxattr|flistxattr|removexattr|lremovexattr|fremovexattr|tkill|sendfile64|futex|sched_setaffinity|sched_getaffinity|set_thread_area
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 250, 29, 28), //io_setup|io_destroy|io_getevents|io_submit|io_cancel
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 253, 28, 27), //exit_group
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 318, 13, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 295, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 284, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 272, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 271, 23, 22), //epoll_create|epoll_ctl|epoll_wait|remap_file_pages|set_tid_address|timer_create|timer_settime|timer_gettime|timer_getoverrun|timer_delete|clock_settime|clock_gettime|clock_getres|clock_nanosleep|statfs64|fstatfs64|tgkill
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 273, 22, 21), //fadvise64_64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 291, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 285, 20, 19), //waitid
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 294, 19, 18), //inotify_init|inotify_add_watch|inotify_rm_watch
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 313, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 300, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 299, 16, 15), //openat|mkdirat|mknodat|fchownat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 311, 15, 14), //fstatat64|unlinkat|renameat|linkat|symlinkat|readlinkat|fchmodat|faccessat|pselect6|ppoll|unshare
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 317, 14, 13), //splice|sync_file_range|tee|vmsplice
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 346, 7, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 340, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 322, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 321, 10, 9), //getcpu|epoll_pwait|utimensat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 337, 9, 8), //timerfd_create|eventfd|fallocate|timerfd_settime|timerfd_gettime|signalfd4|eventfd2|epoll_create1|dup3|pipe2|inotify_init1|preadv|pwritev|rt_tgsigqueueinfo|perf_event_open
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 343, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 341, 7, 6), //prlimit64
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 345, 6, 5), //clock_adjtime|syncfs
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 376, 3, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 351, 1, 0),
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 349, 3, 2), //setns|process_vm_readv|process_vm_writev
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 359, 2, 1), //sched_setattr|sched_getattr|renameat2|seccomp|getrandom|memfd_create|bpf|execveat
+BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 380, 1, 0), //mlock2|copy_file_range|preadv2|pwritev2
+BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+};
+
+const size_t x86_system_filter_size = sizeof(x86_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 0ff0785..a31d7b9 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -159,30 +159,17 @@
 #define _UB(fp) _EXT(fp)->_ub
 #define _FLOCK(fp)  _EXT(fp)->_lock
 
-#define _FILEEXT_INIT(fp) \
-do { \
-	_UB(fp)._base = NULL; \
-	_UB(fp)._size = 0; \
-	WCIO_INIT(fp); \
-	pthread_mutexattr_t attr; \
-	pthread_mutexattr_init(&attr); \
-	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); \
-	pthread_mutex_init(&_FLOCK(fp), &attr); \
-	pthread_mutexattr_destroy(&attr); \
-	_EXT(fp)->_caller_handles_locking = false; \
-} while (0)
+#define _FILEEXT_SETUP(fp, fext) \
+  do { \
+    (fp)->_ext._base = __BIONIC_CAST(reinterpret_cast, unsigned char*, fext); \
+    memset(_EXT(fp), 0, sizeof(struct __sfileext)); \
+    _EXT(fp)->_caller_handles_locking = true; \
+  } while (0)
 
-#define _FILEEXT_SETUP(f, fext) \
-do { \
-	(f)->_ext._base = __BIONIC_CAST(reinterpret_cast, unsigned char*, fext); \
-	_FILEEXT_INIT(f); \
-} while (0)
-
-/*
- * Android <= KitKat had getc/putc macros in <stdio.h> that referred
- * to __srget/__swbuf, so those symbols need to be public for LP32
- * but can be hidden for LP64.
- */
+// Android <= 19 had getc/putc macros in <stdio.h> that referred
+// to __srget/__swbuf, so those symbols need to be public for LP32
+// but can be hidden for LP64. Moreover, the NDK continued to ship
+// those macros until r15 made unified headers the default.
 __LIBC32_LEGACY_PUBLIC__ int __srget(FILE*);
 __LIBC32_LEGACY_PUBLIC__ int __swbuf(int, FILE*);
 __LIBC32_LEGACY_PUBLIC__ int __srefill(FILE*);
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index d627556..d3ac043 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -170,7 +170,10 @@
 
 	fp->_lb._base = nullptr;	/* no line buffer */
 	fp->_lb._size = 0;
-	_FILEEXT_INIT(fp);
+
+	memset(_EXT(fp), 0, sizeof(struct __sfileext));
+	_FLOCK(fp) = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+	_EXT(fp)->_caller_handles_locking = false;
 
 	// Caller sets cookie, _read/_write etc.
 	// We explicitly clear _seek and _seek64 to prevent subtle bugs.
diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.cpp
similarity index 71%
rename from libc/stdio/vfscanf.c
rename to libc/stdio/vfscanf.cpp
index f0ed4ae..49d6bf6 100644
--- a/libc/stdio/vfscanf.c
+++ b/libc/stdio/vfscanf.cpp
@@ -37,74 +37,68 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/param.h>
 #include <wctype.h>
 #include "local.h"
 
 #include <private/bionic_ctype.h>
+#include <private/bionic_fortify.h>
+#include <private/bionic_mbstate.h>
 
 #define BUF 513 /* Maximum length of numeric string. */
 
-/*
- * Flags used during conversion.
- */
-#define LONG 0x00001       /* l: long or double */
-#define LONGDBL 0x00002    /* L: long double */
-#define SHORT 0x00004      /* h: short */
-#define SHORTSHORT 0x00008 /* hh: 8 bit integer */
-#define LLONG 0x00010      /* ll: long long (+ deprecated q: quad) */
-#define POINTER 0x00020    /* p: void * (as hex) */
-#define SIZEINT 0x00040    /* z: (signed) size_t */
-#define MAXINT 0x00080     /* j: intmax_t */
-#define PTRINT 0x00100     /* t: ptrdiff_t */
-#define NOSKIP 0x00200     /* [ or c: do not skip blanks */
-#define SUPPRESS 0x00400   /* *: suppress assignment */
-#define UNSIGNED 0x00800   /* %[oupxX] conversions */
+// Flags used during conversion.
+// Size/type:
+#define LONG       0x00001 // l: long or double
+#define LONGDBL    0x00002 // L: long double
+#define SHORT      0x00004 // h: short
+#define SHORTSHORT 0x00008 // hh: 8 bit integer
+#define LLONG      0x00010 // ll: long long (+ deprecated q: quad)
+#define POINTER    0x00020 // p: void* (as hex)
+#define SIZEINT    0x00040 // z: (signed) size_t
+#define MAXINT     0x00080 // j: intmax_t
+#define PTRINT     0x00100 // t: ptrdiff_t
+#define NOSKIP     0x00200 // [ or c: do not skip blanks
+// Modifiers:
+#define SUPPRESS   0x00400 // *: suppress assignment
+#define UNSIGNED   0x00800 // %[oupxX] conversions
+#define ALLOCATE   0x01000 // m: allocate a char*
+// Internal use during integer parsing:
+#define SIGNOK     0x02000 // +/- is (still) legal
+#define HAVESIGN   0x04000 // Sign detected
+#define NDIGITS    0x08000 // No digits detected
+#define PFXOK      0x10000 // "0x" prefix is (still) legal
+#define NZDIGITS   0x20000 // No zero digits detected
 
-/*
- * The following are used in numeric conversions only:
- * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point;
- * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral.
- */
-#define SIGNOK 0x01000   /* +/- is (still) legal */
-#define HAVESIGN 0x02000 /* sign detected */
-#define NDIGITS 0x04000  /* no digits detected */
+// Conversion types.
+#define CT_CHAR 0   // %c conversion
+#define CT_CCL 1    // %[...] conversion
+#define CT_STRING 2 // %s conversion
+#define CT_INT 3    // Integer: strtoimax/strtoumax
+#define CT_FLOAT 4  // Float: strtod
 
-#define DPTOK 0x08000 /* (float) decimal point is still legal */
-#define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */
-
-#define PFXOK 0x08000    /* 0x prefix is (still) legal */
-#define NZDIGITS 0x10000 /* no zero digits detected */
-
-/*
- * Conversion types.
- */
-#define CT_CHAR 0   /* %c conversion */
-#define CT_CCL 1    /* %[...] conversion */
-#define CT_STRING 2 /* %s conversion */
-#define CT_INT 3    /* integer, i.e., strtoimax or strtoumax */
-#define CT_FLOAT 4  /* floating, i.e., strtod */
-
-static u_char* __sccl(char*, u_char*);
+static const unsigned char* __sccl(char*, const unsigned char*);
 
 /*
  * Internal, unlocked version of vfscanf
  */
-int __svfscanf(FILE* fp, const char* fmt0, __va_list ap) {
-  u_char* fmt = (u_char*)fmt0;
+int __svfscanf(FILE* fp, const char* fmt0, va_list ap) {
+  const unsigned char* fmt = reinterpret_cast<const unsigned char*>(fmt0);
   int c;            /* character from format, or conversion */
   size_t width;     /* field width, or 0 */
-  char* p;          /* points into all kinds of strings */
-  int n;            /* handy integer */
+  char* p;
+  wchar_t* wcp;
+  size_t n;
   int flags;        /* flags as defined above */
-  char* p0;         /* saves original value of p when necessary */
   int nassigned;    /* number of fields assigned */
   int nread;        /* number of characters consumed from fp */
   int base;         /* base argument to strtoimax/strtouimax */
   char ccltab[256]; /* character class table for %[...] */
   char buf[BUF];    /* buffer for numeric conversions */
-  wchar_t* wcp;     /* handy wide character pointer */
   size_t nconv;     /* length of multibyte sequence converted */
   mbstate_t mbs;
+  void* allocation = NULL; // Allocated but unassigned result for %mc/%ms/%m[.
+  size_t capacity = 0; // Number of char/wchar_t units allocated in `allocation`.
 
   /* `basefix' is used to avoid `if' tests in the integer scanner */
   static short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
@@ -113,10 +107,9 @@
 
   nassigned = 0;
   nread = 0;
-  base = 0; /* XXX just to keep gcc happy */
   for (;;) {
     c = *fmt++;
-    if (c == 0) return (nassigned);
+    if (c == 0) return nassigned;
     if (IsSpace(c)) {
       while ((fp->_r > 0 || __srefill(fp) == 0) && IsSpace(*fp->_p)) nread++, fp->_r--, fp->_p++;
       continue;
@@ -164,6 +157,9 @@
           flags |= LONG;
         }
         goto again;
+      case 'm':
+        flags |= ALLOCATE;
+        goto again;
       case 'q':
         flags |= LLONG; /* deprecated */
         goto again;
@@ -239,6 +235,8 @@
         break;
 
       case 's':
+        memset(ccltab, 1, 256);
+        ccltab['\t'] = ccltab['\n'] = ccltab['\v'] = ccltab['\f'] = ccltab['\r'] = ccltab[' '] = 0;
         c = CT_STRING;
         break;
 
@@ -262,29 +260,30 @@
 
       case 'n':
         if (flags & SUPPRESS) continue;
-        if (flags & SHORTSHORT)
+        if (flags & SHORTSHORT) {
           *va_arg(ap, signed char*) = nread;
-        else if (flags & SHORT)
+        } else if (flags & SHORT) {
           *va_arg(ap, short*) = nread;
-        else if (flags & LONG)
+        } else if (flags & LONG) {
           *va_arg(ap, long*) = nread;
-        else if (flags & SIZEINT)
+        } else if (flags & SIZEINT) {
           *va_arg(ap, ssize_t*) = nread;
-        else if (flags & PTRINT)
+        } else if (flags & PTRINT) {
           *va_arg(ap, ptrdiff_t*) = nread;
-        else if (flags & LLONG)
+        } else if (flags & LLONG) {
           *va_arg(ap, long long*) = nread;
-        else if (flags & MAXINT)
+        } else if (flags & MAXINT) {
           *va_arg(ap, intmax_t*) = nread;
-        else
+        } else {
           *va_arg(ap, int*) = nread;
+        }
         continue;
 
       /*
        * Disgusting backwards compatibility hacks.	XXX
        */
       case '\0': /* compat */
-        return (EOF);
+        return EOF;
 
       default: /* compat */
         if (IsUpper(c)) flags |= LONG;
@@ -293,6 +292,13 @@
         break;
     }
 
+    if ((flags & ALLOCATE) != 0 && c > CT_STRING) {
+      __fortify_fatal("scanf 'm' only works with %%c/%%s/%%[");
+    }
+    if ((flags & (ALLOCATE|SUPPRESS)) == (ALLOCATE|SUPPRESS)) {
+      __fortify_fatal("scanf 'm' makes no sense with '*'");
+    }
+
     /*
      * We have a conversion that requires input.
      */
@@ -326,42 +332,53 @@
         /* scan arbitrary characters (sets NOSKIP) */
         if (width == 0) width = 1;
         if (flags & LONG) {
-          wcp = ((flags & SUPPRESS) == 0) ? va_arg(ap, wchar_t*) : NULL;
-          n = 0;
+          if (flags & ALLOCATE) {
+            allocation = wcp = reinterpret_cast<wchar_t*>(malloc(width * sizeof(wchar_t)));
+            if (allocation == NULL) goto allocation_failure;
+          } else if (flags & SUPPRESS) {
+            wcp = NULL;
+          } else {
+            wcp = va_arg(ap, wchar_t*);
+          }
+          size_t bytes = 0;
           while (width != 0) {
-            if (n == (int)MB_CUR_MAX) {
+            if (bytes == MB_CUR_MAX) {
               fp->_flags |= __SERR;
               goto input_failure;
             }
-            buf[n++] = *fp->_p;
+            buf[bytes++] = *fp->_p;
             fp->_p++;
             fp->_r--;
             memset(&mbs, 0, sizeof(mbs));
-            nconv = mbrtowc(wcp, buf, n, &mbs);
-            if (nconv == (size_t)-1) {
+            nconv = mbrtowc(wcp, buf, bytes, &mbs);
+            if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
               fp->_flags |= __SERR;
               goto input_failure;
             }
             if (nconv == 0 && !(flags & SUPPRESS)) *wcp = L'\0';
-            if (nconv != (size_t)-2) {
-              nread += n;
+            if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+              nread += bytes;
               width--;
               if (!(flags & SUPPRESS)) wcp++;
-              n = 0;
+              bytes = 0;
             }
             if (fp->_r <= 0 && __srefill(fp)) {
-              if (n != 0) {
+              if (bytes != 0) {
                 fp->_flags |= __SERR;
                 goto input_failure;
               }
               break;
             }
           }
+          if (allocation != NULL) {
+            *va_arg(ap, wchar_t**) = reinterpret_cast<wchar_t*>(allocation);
+            allocation = NULL;
+          }
           if (!(flags & SUPPRESS)) nassigned++;
         } else if (flags & SUPPRESS) {
           size_t sum = 0;
           for (;;) {
-            if ((n = fp->_r) < (int)width) {
+            if ((n = fp->_r) < width) {
               sum += n;
               width -= n;
               fp->_p += n;
@@ -378,9 +395,18 @@
           }
           nread += sum;
         } else {
-          size_t r = fread((void*)va_arg(ap, char*), 1, width, fp);
-
+          if (flags & ALLOCATE) {
+            allocation = p = reinterpret_cast<char*>(malloc(width));
+            if (allocation == NULL) goto allocation_failure;
+          } else {
+            p = va_arg(ap, char*);
+          }
+          size_t r = fread(p, 1, width, fp);
           if (r == 0) goto input_failure;
+          if (allocation != NULL) {
+            *va_arg(ap, char**) = reinterpret_cast<char*>(allocation);
+            allocation = NULL;
+          }
           nread += r;
           nassigned++;
         }
@@ -390,58 +416,75 @@
       case CT_STRING:
         // CT_CCL: scan a (nonempty) character class (sets NOSKIP).
         // CT_STRING: like CCL, but zero-length string OK, & no NOSKIP.
-        if (width == 0) width = (size_t)~0; // 'infinity'.
+        if (width == 0) width = SIZE_MAX;
         if (flags & LONG) {
-          wchar_t twc;
-          int nchars = 0;
-
-          wcp = (flags & SUPPRESS) == 0 ? va_arg(ap, wchar_t*) : &twc;
+          // TODO: since no-one cares, replace this with a simple fgetwc loop?
           n = 0;
+          if (flags & ALLOCATE) {
+            capacity = MIN(width, 32);
+            allocation = wcp = reinterpret_cast<wchar_t*>(malloc(sizeof(wchar_t) * capacity));
+            if (allocation == NULL) goto allocation_failure;
+          } else if (flags & SUPPRESS) {
+            wcp = NULL;
+          } else {
+            wcp = va_arg(ap, wchar_t*);
+          }
+          size_t bytes = 0;
           while ((c == CT_CCL || !IsSpace(*fp->_p)) && width != 0) {
-            if (n == (int)MB_CUR_MAX) {
+            if (bytes == MB_CUR_MAX) {
               fp->_flags |= __SERR;
               goto input_failure;
             }
-            buf[n++] = *fp->_p;
+            buf[bytes++] = *fp->_p;
             fp->_p++;
             fp->_r--;
+            wchar_t wc = L'\0';
             memset(&mbs, 0, sizeof(mbs));
-            nconv = mbrtowc(wcp, buf, n, &mbs);
-            if (nconv == (size_t)-1) {
+            nconv = mbrtowc(&wc, buf, bytes, &mbs);
+            if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
               fp->_flags |= __SERR;
               goto input_failure;
             }
-            if (nconv == 0) *wcp = L'\0';
-            if (nconv != (size_t)-2) {
-              if ((c == CT_CCL && wctob(*wcp) != EOF && !ccltab[wctob(*wcp)]) || (c == CT_STRING && iswspace(*wcp))) {
-                while (n != 0) {
-                  n--;
-                  ungetc(buf[n], fp);
+            if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+              if ((c == CT_CCL && wctob(wc) != EOF && !ccltab[wctob(wc)]) || (c == CT_STRING && iswspace(wc))) {
+                while (bytes != 0) {
+                  bytes--;
+                  ungetc(buf[bytes], fp);
                 }
                 break;
               }
-              nread += n;
+              if (wcp) wcp[n] = wc;
+              n++;
+              if (allocation != NULL && n == capacity) {
+                capacity *= 2;
+                wchar_t* new_allocation =
+                    reinterpret_cast<wchar_t*>(realloc(allocation, sizeof(wchar_t) * capacity));
+                if (new_allocation == NULL) goto allocation_failure;
+                allocation = wcp = new_allocation;
+              }
+              nread += bytes;
               width--;
-              if (!(flags & SUPPRESS)) wcp++;
-              nchars++;
-              n = 0;
+              bytes = 0;
             }
             if (fp->_r <= 0 && __srefill(fp)) {
-              if (n != 0) {
+              if (bytes != 0) {
                 fp->_flags |= __SERR;
                 goto input_failure;
               }
               break;
             }
           }
-          if (c == CT_CCL && n != 0) {
+          if (c == CT_CCL && bytes != 0) {
             fp->_flags |= __SERR;
             goto input_failure;
           }
-          n = nchars;
+          if (allocation != NULL) {
+            *va_arg(ap, wchar_t**) = reinterpret_cast<wchar_t*>(allocation);
+            allocation = NULL;
+          }
         } else if (flags & SUPPRESS) {
           n = 0;
-          while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !IsSpace(*fp->_p))) {
+          while (ccltab[*fp->_p]) {
             n++, fp->_r--, fp->_p++;
             if (--width == 0) break;
             if (fp->_r <= 0 && __srefill(fp)) {
@@ -449,29 +492,46 @@
               break;
             }
           }
+          nread += n;
         } else {
-          p0 = p = va_arg(ap, char*);
-          while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !IsSpace(*fp->_p))) {
+          if (flags & ALLOCATE) {
+            capacity = MIN(width, 32);
+            allocation = p = reinterpret_cast<char*>(malloc(capacity));
+            if (allocation == NULL) goto allocation_failure;
+          } else {
+            p = va_arg(ap, char*);
+          }
+          n = 0;
+          while (ccltab[*fp->_p]) {
             fp->_r--;
-            *p++ = *fp->_p++;
+            p[n++] = *fp->_p++;
+            if (allocation != NULL && n == capacity) {
+              capacity *= 2;
+              char* new_allocation = reinterpret_cast<char*>(realloc(allocation, capacity));
+              if (new_allocation == NULL) goto allocation_failure;
+              allocation = p = new_allocation;
+            }
             if (--width == 0) break;
             if (fp->_r <= 0 && __srefill(fp)) {
-              if (c == CT_CCL && p == p0) goto input_failure;
+              if (c == CT_CCL && n == 0) goto input_failure;
               break;
             }
           }
-          n = p - p0;
+          nread += n;
+          if (allocation != NULL) {
+            *va_arg(ap, char**) = reinterpret_cast<char*>(allocation);
+            allocation = NULL;
+          }
         }
         if (c == CT_CCL && n == 0) goto match_failure;
         if (!(flags & SUPPRESS)) {
           if (flags & LONG) {
-            *wcp = L'\0';
+            wcp[n] = L'\0';
           } else {
-            *p = '\0';
+            p[n] = '\0';
           }
           ++nassigned;
         }
-        nread += n;
         break;
 
       case CT_INT:
@@ -610,28 +670,30 @@
           uintmax_t res;
 
           *p = '\0';
-          if (flags & UNSIGNED)
+          if (flags & UNSIGNED) {
             res = strtoumax(buf, NULL, base);
-          else
+          } else {
             res = strtoimax(buf, NULL, base);
-          if (flags & POINTER)
+          }
+          if (flags & POINTER) {
             *va_arg(ap, void**) = (void*)(uintptr_t)res;
-          else if (flags & MAXINT)
+          } else if (flags & MAXINT) {
             *va_arg(ap, intmax_t*) = res;
-          else if (flags & LLONG)
+          } else if (flags & LLONG) {
             *va_arg(ap, long long*) = res;
-          else if (flags & SIZEINT)
+          } else if (flags & SIZEINT) {
             *va_arg(ap, ssize_t*) = res;
-          else if (flags & PTRINT)
+          } else if (flags & PTRINT) {
             *va_arg(ap, ptrdiff_t*) = res;
-          else if (flags & LONG)
+          } else if (flags & LONG) {
             *va_arg(ap, long*) = res;
-          else if (flags & SHORT)
+          } else if (flags & SHORT) {
             *va_arg(ap, short*) = res;
-          else if (flags & SHORTSHORT)
+          } else if (flags & SHORTSHORT) {
             *va_arg(ap, signed char*) = res;
-          else
+          } else {
             *va_arg(ap, int*) = res;
+          }
           nassigned++;
         }
         nread += p - buf;
@@ -659,10 +721,12 @@
         break;
     }
   }
+allocation_failure:
 input_failure:
+  free(allocation);
   if (nassigned == 0) nassigned = -1;
 match_failure:
-  return (nassigned);
+  return nassigned;
 }
 
 /*
@@ -671,7 +735,7 @@
  * closing `]'.  The table has a 1 wherever characters should be
  * considered part of the scanset.
  */
-static u_char* __sccl(char* tab, u_char* fmt) {
+static const unsigned char* __sccl(char* tab, const unsigned char* fmt) {
   int c, n, v;
 
   /* first `clear' the whole table */
@@ -679,10 +743,10 @@
   if (c == '^') {
     v = 1;      /* default => accept */
     c = *fmt++; /* get new first char */
-  } else
+  } else {
     v = 0; /* default => reject */
-  /* should probably use memset here */
-  for (n = 0; n < 256; n++) tab[n] = v;
+  }
+  memset(tab, v, 256);
   if (c == 0) return (fmt - 1); /* format ended before closing ] */
 
   /*
@@ -744,7 +808,7 @@
         break;
 
       case ']': /* end of scanset */
-        return (fmt);
+        return fmt;
 
       default: /* just another character */
         c = n;
diff --git a/libc/stdio/wcio.h b/libc/stdio/wcio.h
index 2c1fa3c..3c4f7a4 100644
--- a/libc/stdio/wcio.h
+++ b/libc/stdio/wcio.h
@@ -79,9 +79,6 @@
 	} \
 } while (0)
 
-#define WCIO_INIT(fp) \
-	memset(&(_EXT(fp)->_wcio), 0, sizeof(struct wchar_io_data))
-
 __END_DECLS
 
 #endif /*_WCIO_H_*/
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
index b8afa29..92baedd 100644
--- a/libc/system_properties/contexts_split.cpp
+++ b/libc/system_properties/contexts_split.cpp
@@ -274,12 +274,22 @@
     // Don't check for failure here, so we always have a sane list of properties.
     // E.g. In case of recovery, the vendor partition will not have mounted and we
     // still need the system / platform properties to function.
-    InitializePropertiesFromFile("/vendor/etc/selinux/nonplat_property_contexts");
+    if (access("/vendor/etc/selinux/vendor_property_contexts", R_OK) != -1) {
+      InitializePropertiesFromFile("/vendor/etc/selinux/vendor_property_contexts");
+    } else {
+      // Fallback to nonplat_* if vendor_* doesn't exist.
+      InitializePropertiesFromFile("/vendor/etc/selinux/nonplat_property_contexts");
+    }
   } else {
     if (!InitializePropertiesFromFile("/plat_property_contexts")) {
       return false;
     }
-    InitializePropertiesFromFile("/nonplat_property_contexts");
+    if (access("/vendor_property_contexts", R_OK) != -1) {
+      InitializePropertiesFromFile("/vendor_property_contexts");
+    } else {
+      // Fallback to nonplat_* if vendor_* doesn't exist.
+      InitializePropertiesFromFile("/nonplat_property_contexts");
+    }
   }
 
   return true;
diff --git a/libc/system_properties/include/system_properties/system_properties.h b/libc/system_properties/include/system_properties/system_properties.h
index c74f875..83ac00c 100644
--- a/libc/system_properties/include/system_properties/system_properties.h
+++ b/libc/system_properties/include/system_properties/system_properties.h
@@ -48,7 +48,7 @@
   SystemProperties() {
   }
   // Special constructor for testing that also zero initializes the important members.
-  SystemProperties(bool initialized) : initialized_(initialized) {
+  explicit SystemProperties(bool initialized) : initialized_(initialized) {
   }
 
   DISALLOW_COPY_AND_ASSIGN(SystemProperties);
diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index f3a232e..63d9f20 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -26,47 +26,18 @@
     self.names.append(name)
 
 
-def get_names(syscall_files, architecture, global_policy):
-  syscall_lists = []
-  for syscall_file in syscall_files:
-    parser = SysCallsTxtParser()
-    parser.parse_open_file(syscall_file)
-    syscall_lists.append(parser.syscalls)
+def load_syscall_names_from_file(file_path, architecture):
+  parser = SysCallsTxtParser()
+  parser.parse_open_file(open(file_path))
+  return set([x["name"] for x in parser.syscalls if x.get(architecture)])
 
-  bionic, whitelist, blacklist = syscall_lists[0], syscall_lists[1], syscall_lists[2]
-  if global_policy:
-    global_whitelist = syscall_lists[-1]
-  else:
-    global_whitelist = []
 
-  for x in blacklist:
-    if not x in bionic:
-      raise RuntimeError("Blacklist item not in bionic - aborting " + str(x))
+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_name - base_names))
 
-    if x in whitelist:
-      raise RuntimeError("Blacklist item in whitelist - aborting " + str(x))
-
-  bionic_minus_blacklist = [x for x in bionic if x not in blacklist]
-  syscalls = bionic_minus_blacklist + whitelist + global_whitelist
-
-  # Select only elements matching required architecture
-  syscalls = [x for x in syscalls if architecture in x and x[architecture]]
-
-  # We only want the name
-  names = [x["name"] for x in syscalls]
-
-  # Check for duplicates
-  dups = [name for name, count in collections.Counter(names).items() if count > 1]
-
-  # x86 has duplicate socketcall entries, so hard code for this
-  if architecture == "x86":
-    dups.remove("socketcall")
-
-  if len(dups) > 0:
-    raise RuntimeError("Duplicate entries found - aborting " + str(dups))
-
-  # Remove remaining duplicates
-  return list(set(names))
+  return (base_names - blacklist_names) | whitelist_names
 
 
 def convert_names_to_NRs(names, header_dir, extra_switches):
@@ -175,8 +146,11 @@
   return bpf
 
 
-def convert_bpf_to_output(bpf, architecture, global_policy):
-  suffix = "global_" if global_policy else ""
+def convert_bpf_to_output(bpf, architecture, name_modifier):
+  if name_modifier:
+    name_modifier = name_modifier + "_"
+  else:
+    name_modifier = ""
   header = textwrap.dedent("""\
     // Autogenerated file - edit at your peril!!
 
@@ -185,29 +159,53 @@
 
     #include "seccomp_bpfs.h"
     const sock_filter {architecture}_{suffix}filter[] = {{
-    """).format(architecture=architecture,suffix=suffix)
+    """).format(architecture=architecture,suffix=name_modifier)
 
   footer = textwrap.dedent("""\
 
     }};
 
     const size_t {architecture}_{suffix}filter_size = sizeof({architecture}_{suffix}filter) / sizeof(struct sock_filter);
-    """).format(architecture=architecture,suffix=suffix)
+    """).format(architecture=architecture,suffix=name_modifier)
   return header + "\n".join(bpf) + footer
 
 
-def construct_bpf(syscall_files, architecture, header_dir, extra_switches,
-                  global_policy):
-  names = get_names(syscall_files, architecture, global_policy)
+def construct_bpf(names, architecture, header_dir, extra_switches,
+                  name_modifier):
   syscalls = convert_names_to_NRs(names, header_dir, extra_switches)
   ranges = convert_NRs_to_ranges(syscalls)
   bpf = convert_ranges_to_bpf(ranges)
-  return convert_bpf_to_output(bpf, architecture, global_policy)
+  return convert_bpf_to_output(bpf, architecture, name_modifier)
 
 
-ANDROID_SYSCALL_FILES = ["SYSCALLS.TXT",
-                         "SECCOMP_WHITELIST.TXT",
-                         "SECCOMP_BLACKLIST.TXT"]
+# final syscalls = base - blacklists + whitelists
+ANDROID_SYSTEM_SYSCALL_FILES = {
+    "base": "SYSCALLS.TXT",
+    "whitelists": [
+        "SECCOMP_WHITELIST_COMMON.TXT",
+        "SECCOMP_WHITELIST_SYSTEM.TXT"],
+    "blacklists": ["SECCOMP_BLACKLIST_COMMON.TXT"]
+}
+
+ANDROID_APP_SYSCALL_FILES = {
+    "base": "SYSCALLS.TXT",
+    "whitelists": [
+        "SECCOMP_WHITELIST_COMMON.TXT",
+        "SECCOMP_WHITELIST_APP.TXT"],
+    "blacklists": [
+        "SECCOMP_BLACKLIST_COMMON.TXT",
+        "SECCOMP_BLACKLIST_APP.TXT"]
+}
+
+ANDROID_GLOBAL_SYSCALL_FILES = {
+    "base": "SYSCALLS.TXT",
+    "whitelists": [
+        "SECCOMP_WHITELIST_COMMON.TXT",
+        "SECCOMP_WHITELIST_SYSTEM.TXT",
+        "SECCOMP_WHITELIST_APP.TXT",
+        "SECCOMP_WHITELIST_GLOBAL.TXT"],
+    "blacklists": ["SECCOMP_BLACKLIST_COMMON.TXT"]
+}
 
 
 POLICY_CONFIGS = [("arm", "kernel/uapi/asm-arm", []),
@@ -223,18 +221,23 @@
   os.chdir(os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc"))
 
 
-def gen_policy(global_policy):
-  if global_policy:
-    ANDROID_SYSCALL_FILES.append("SECCOMP_WHITELIST_GLOBAL.TXT")
-
+def gen_policy(syscall_files, name_modifier):
   for arch, header_path, switches in POLICY_CONFIGS:
-    files = [open(filename) for filename in ANDROID_SYSCALL_FILES]
-    output = construct_bpf(files, arch, header_path, switches, global_policy)
+    base_names = load_syscall_names_from_file(syscall_files["base"], arch)
+    whitelist_names = set()
+    for f in syscall_files["whitelists"]:
+      whitelist_names |= load_syscall_names_from_file(f, arch)
+    blacklist_names = set()
+    for f in syscall_files["blacklists"]:
+      blacklist_names |= load_syscall_names_from_file(f, arch)
+
+    names = merge_names(base_names, whitelist_names, blacklist_names)
+    output = construct_bpf(names, arch, header_path, switches, name_modifier)
 
     # And output policy
     existing = ""
-    global_string = "_global" if global_policy else ""
-    output_path = "seccomp/{}{}_policy.cpp".format(arch, global_string)
+    filename_modifier = "_" + name_modifier if name_modifier else ""
+    output_path = "seccomp/{}{}_policy.cpp".format(arch, filename_modifier)
     if os.path.isfile(output_path):
       existing = open(output_path).read()
     if output == existing:
@@ -247,8 +250,10 @@
 
 def main():
   set_dir()
-  gen_policy(False)
-  gen_policy(True)
+  gen_policy(ANDROID_SYSTEM_SYSCALL_FILES, 'system')
+  gen_policy(ANDROID_APP_SYSCALL_FILES, 'app')
+  gen_policy(ANDROID_GLOBAL_SYSCALL_FILES, 'global')
+
 
 if __name__ == "__main__":
   main()
diff --git a/libc/upstream-openbsd/lib/libc/gen/time.c b/libc/upstream-openbsd/lib/libc/gen/time.c
deleted file mode 100644
index 6fcf1cd..0000000
--- a/libc/upstream-openbsd/lib/libc/gen/time.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*	$OpenBSD: time.c,v 1.7 2015/10/29 03:58:55 mmcc Exp $ */
-/*
- * Copyright (c) 1983, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/time.h>
-#include <time.h>
-
-time_t
-time(time_t *t)
-{
-	struct timeval tt;
-
-	if (gettimeofday(&tt, NULL) < 0)
-		return (-1);
-	if (t)
-		*t = (time_t)tt.tv_sec;
-	return (tt.tv_sec);
-}
-DEF_STRONG(time);
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 44daaec..082cdea 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -4,7 +4,10 @@
 cc_library_static {
     name: "libdl_static",
 
-    srcs: ["libdl.cpp", "libdl_cfi.cpp"],
+    srcs: [
+        "libdl.cpp",
+        "libdl_cfi.cpp",
+    ],
 
     cflags: [
         "-Wall",
@@ -25,6 +28,7 @@
 
 cc_library {
     name: "libdl",
+    static_ndk_lib: true,
 
     defaults: ["linux_bionic_supported"],
 
@@ -70,7 +74,7 @@
         whole_static_libs: ["libdl_static"],
     },
     static: {
-        srcs: [ "libdl_static.c" ],
+        srcs: ["libdl_static.c"],
     },
     cflags: [
         "-Wall",
@@ -90,53 +94,7 @@
 
     // This is placeholder library the actual implementation is (currently)
     // provided by the linker.
-    shared_libs: [ "ld-android" ],
-
-    sanitize: {
-        never: true,
-    },
-}
-
-cc_library {
-    // NOTE: --exclude-libs=libgcc.a makes sure that any symbols libdl.so pulls from
-    // libgcc.a are made static to ld-android.so.  This in turn ensures that libraries that
-    // a) pull symbols from libgcc.a and b) depend on ld-android.so will not rely on ld-android.so
-    // to provide those symbols, but will instead pull them from libgcc.a.  Specifically,
-    // we use this property to make sure libc.so has its own copy of the code from
-    // libgcc.a it uses.
-    //
-    // DO NOT REMOVE --exclude-libs!
-
-    ldflags: ["-Wl,--exclude-libs=libgcc.a"],
-
-    // for x86, exclude libgcc_eh.a for the same reasons as above
-    arch: {
-        x86: {
-            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
-        },
-        x86_64: {
-            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
-        },
-    },
-    srcs: ["ld_android.c"],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Wunused",
-        "-Werror",
-    ],
-    stl: "none",
-
-    name: "ld-android",
-    defaults: ["linux_bionic_supported"],
-
-    // NOTE: libdl needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a needs a
-    // few symbols from libc. Using --no-undefined here results in having to link
-    // against libc creating a circular dependency which is removed and we end up
-    // with missing symbols. Since this library is just a bunch of stubs, we set
-    // LOCAL_ALLOW_UNDEFINED_SYMBOLS to remove --no-undefined from the linker flags.
-    allow_undefined_symbols: true,
-    system_shared_libs: [],
+    shared_libs: ["ld-android"],
 
     sanitize: {
         never: true,
diff --git a/libdl/ld_android.c b/libdl/ld_android.c
deleted file mode 100644
index 8b13789..0000000
--- a/libdl/ld_android.c
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/libm/Android.bp b/libm/Android.bp
index 6d6fafa..76a4699 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -6,6 +6,7 @@
 cc_library {
     name: "libm",
     defaults: ["linux_bionic_supported"],
+    static_ndk_lib: true,
 
     srcs: [
         "upstream-freebsd/lib/msun/bsdsrc/b_exp.c",
diff --git a/linker/Android.bp b/linker/Android.bp
index f802f45..50587f2 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -6,7 +6,10 @@
         "linker_allocator.cpp",
         "linker_memory.cpp",
     ],
-    cflags: ["-Wall", "-Werror"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
 
     // We need to access Bionic private headers in the linker.
     include_dirs: ["bionic/libc"],
@@ -26,9 +29,15 @@
     host_supported: true,
     device_supported: false,
     target: {
-        linux_bionic: { enabled: true },
-        linux_glibc: { enabled: false },
-        darwin: { enabled: false },
+        linux_bionic: {
+            enabled: true,
+        },
+        linux_glibc: {
+            enabled: false,
+        },
+        darwin: {
+            enabled: false,
+        },
     },
 
     cflags: [
@@ -130,6 +139,7 @@
         "-shared",
         "-Wl,-Bsymbolic",
         "-Wl,--exclude-libs,ALL",
+        "-Wl,-soname,ld-android.so",
     ],
 
     cflags: [
@@ -186,7 +196,7 @@
 
         // Important: The liblinker_malloc should be the last library in the list
         // to overwrite any other malloc implementations by other static libraries.
-        "liblinker_malloc"
+        "liblinker_malloc",
     ],
     static_executable: true,
 
@@ -220,3 +230,64 @@
     // looking up symbols in the linker by mistake.
     prefix_symbols: "__dl_",
 }
+
+cc_library {
+    // NOTE: --exclude-libs=libgcc.a makes sure that any symbols ld-android.so pulls from
+    // libgcc.a are made static to ld-android.so.  This in turn ensures that libraries that
+    // a) pull symbols from libgcc.a and b) depend on ld-android.so will not rely on ld-android.so
+    // to provide those symbols, but will instead pull them from libgcc.a.  Specifically,
+    // we use this property to make sure libc.so has its own copy of the code from
+    // libgcc.a it uses.
+    //
+    // DO NOT REMOVE --exclude-libs!
+
+    ldflags: ["-Wl,--exclude-libs=libgcc.a"],
+
+    // for x86, exclude libgcc_eh.a for the same reasons as above
+    arch: {
+        arm: {
+            version_script: "linker.arm.map",
+        },
+        arm64: {
+            version_script: "linker.generic.map",
+        },
+        x86: {
+            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+            version_script: "linker.generic.map",
+        },
+        x86_64: {
+            ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
+            version_script: "linker.generic.map",
+        },
+        mips: {
+            version_script: "linker.generic.map",
+        },
+        mips64: {
+            version_script: "linker.generic.map",
+        },
+    },
+
+    srcs: ["ld_android.cpp"],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wunused",
+        "-Werror",
+    ],
+    stl: "none",
+
+    name: "ld-android",
+    defaults: ["linux_bionic_supported"],
+
+    // NOTE: ld-android.so needs __aeabi_unwind_cpp_pr0 from libgcc.a but libgcc.a
+    // needs a few symbols from libc. Using --no-undefined here results in having to
+    // link against libc creating a circular dependency which is removed and we end
+    // up with missing symbols. Since this library is just a bunch of stubs, we set
+    // allow_undefined_symbols to remove --no-undefined from the linker flags.
+    allow_undefined_symbols: true,
+    system_shared_libs: [],
+
+    sanitize: {
+        never: true,
+    },
+}
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 7f9bf7e..4b84537 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -65,6 +65,8 @@
 bool __loader_android_link_namespaces(android_namespace_t* namespace_from,
                                       android_namespace_t* namespace_to,
                                       const char* shared_libs_sonames) __LINKER_PUBLIC__;
+bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
+                                               android_namespace_t* namespace_to) __LINKER_PUBLIC__;
 void __loader_android_set_application_target_sdk_version(uint32_t target) __LINKER_PUBLIC__;
 void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) __LINKER_PUBLIC__;
 void __loader_cfi_fail(uint64_t CallSiteTypeId,
@@ -82,6 +84,8 @@
                       const char* symbol,
                       const char* version,
                       const void* caller_addr) __LINKER_PUBLIC__;
+void __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
+void __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
 #if defined(__arm__)
 _Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
 #endif
@@ -264,6 +268,19 @@
   return success;
 }
 
+bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
+                                               android_namespace_t* namespace_to) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+
+  bool success = link_namespaces_all_libs(namespace_from, namespace_to);
+
+  if (!success) {
+    __bionic_format_dlerror("android_link_namespaces_all_libs failed", linker_get_error_buffer());
+  }
+
+  return success;
+}
+
 android_namespace_t* __loader_android_get_exported_namespace(const char* name) {
   return get_exported_namespace(name);
 }
@@ -272,6 +289,16 @@
   CFIShadowWriter::CfiFail(CallSiteTypeId, Ptr, DiagData, CallerPc);
 }
 
+void __loader_add_thread_local_dtor(void* dso_handle) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  increment_dso_handle_reference_counter(dso_handle);
+}
+
+void __loader_remove_thread_local_dtor(void* dso_handle) {
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+  decrement_dso_handle_reference_counter(dso_handle);
+}
+
 static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
 static soinfo* __libdl_info = nullptr;
 
@@ -298,7 +325,7 @@
     __libdl_info->ref_count_ = 1;
     __libdl_info->strtab_size_ = linker_si.strtab_size_;
     __libdl_info->local_group_root_ = __libdl_info;
-    __libdl_info->soname_ = "ld-android.so";
+    __libdl_info->soname_ = linker_si.soname_;
     __libdl_info->target_sdk_version_ = __ANDROID_API__;
     __libdl_info->generate_handle();
     __libdl_info->link_map_head.l_addr = linker_map.l_addr;
diff --git a/linker/ld_android.cpp b/linker/ld_android.cpp
new file mode 100644
index 0000000..e2499b3
--- /dev/null
+++ b/linker/ld_android.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 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 <stdlib.h>
+#include <sys/cdefs.h>
+
+extern "C" void __internal_linker_error() {
+  abort();
+}
+
+__strong_alias(__loader_android_create_namespace, __internal_linker_error);
+__strong_alias(__loader_android_dlopen_ext, __internal_linker_error);
+__strong_alias(__loader_android_dlwarning, __internal_linker_error);
+__strong_alias(__loader_android_get_application_target_sdk_version, __internal_linker_error);
+__strong_alias(__loader_android_get_LD_LIBRARY_PATH, __internal_linker_error);
+__strong_alias(__loader_android_get_exported_namespace, __internal_linker_error);
+__strong_alias(__loader_android_init_anonymous_namespace, __internal_linker_error);
+__strong_alias(__loader_android_link_namespaces, __internal_linker_error);
+__strong_alias(__loader_android_link_namespaces_all_libs, __internal_linker_error);
+__strong_alias(__loader_android_set_application_target_sdk_version, __internal_linker_error);
+__strong_alias(__loader_android_update_LD_LIBRARY_PATH, __internal_linker_error);
+__strong_alias(__loader_cfi_fail, __internal_linker_error);
+__strong_alias(__loader_dl_iterate_phdr, __internal_linker_error);
+__strong_alias(__loader_dladdr, __internal_linker_error);
+__strong_alias(__loader_dlclose, __internal_linker_error);
+__strong_alias(__loader_dlerror, __internal_linker_error);
+__strong_alias(__loader_dlopen, __internal_linker_error);
+__strong_alias(__loader_dlsym, __internal_linker_error);
+__strong_alias(__loader_dlvsym, __internal_linker_error);
+__strong_alias(__loader_add_thread_local_dtor, __internal_linker_error);
+__strong_alias(__loader_remove_thread_local_dtor, __internal_linker_error);
+#if defined(__arm__)
+__strong_alias(__loader_dl_unwind_find_exidx, __internal_linker_error);
+#endif
+__strong_alias(rtld_db_dlactivity, __internal_linker_error);
+
diff --git a/linker/linker.arm.map b/linker/linker.arm.map
index 67b0632..a58e7c8 100644
--- a/linker/linker.arm.map
+++ b/linker/linker.arm.map
@@ -17,8 +17,11 @@
     __loader_android_dlwarning;
     __loader_cfi_fail;
     __loader_android_link_namespaces;
+    __loader_android_link_namespaces_all_libs;
     __loader_android_get_exported_namespace;
     __loader_dl_unwind_find_exidx;
+    __loader_add_thread_local_dtor;
+    __loader_remove_thread_local_dtor;
     rtld_db_dlactivity;
   local:
     *;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 4ad44fa..3f898ba 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -75,6 +75,8 @@
 #undef ELF_ST_TYPE
 #define ELF_ST_TYPE(x) (static_cast<uint32_t>(x) & 0xf)
 
+static std::unordered_map<void*, size_t> g_dso_handle_counters;
+
 static android_namespace_t* g_anonymous_namespace = &g_default_namespace;
 static std::unordered_map<std::string, android_namespace_t*> g_exported_namespaces;
 
@@ -1428,7 +1430,7 @@
   }
 
   // returning true with empty soinfo means that the library is okay to be
-  // loaded in the namespace buy has not yet been loaded there before.
+  // loaded in the namespace but has not yet been loaded there before.
   task->set_soinfo(nullptr);
   return true;
 }
@@ -1780,26 +1782,10 @@
   return si;
 }
 
-static void soinfo_unload(soinfo* unload_si) {
-  // Note that the library can be loaded but not linked;
-  // in which case there is no root but we still need
-  // to walk the tree and unload soinfos involved.
-  //
-  // This happens on unsuccessful dlopen, when one of
-  // the DT_NEEDED libraries could not be linked/found.
-  bool is_linked = unload_si->is_linked();
-  soinfo* root = is_linked ? unload_si->get_local_group_root() : unload_si;
-
-  LD_LOG(kLogDlopen,
-         "... dlclose(realpath=\"%s\"@%p) ... load group root is \"%s\"@%p",
-         unload_si->get_realpath(),
-         unload_si,
-         root->get_realpath(),
-         root);
-
+static void soinfo_unload_impl(soinfo* root) {
   ScopedTrace trace((std::string("unload ") + root->get_realpath()).c_str());
+  bool is_linked = root->is_linked();
 
-  size_t ref_count = is_linked ? root->decrement_ref_count() : 0;
   if (!root->can_unload()) {
     LD_LOG(kLogDlopen,
            "... dlclose(root=\"%s\"@%p) ... not unloading - the load group is flagged with NODELETE",
@@ -1808,14 +1794,6 @@
     return;
   }
 
-  if (ref_count > 0) {
-    LD_LOG(kLogDlopen,
-           "... dlclose(root=\"%s\"@%p) ... not unloading - decrementing ref_count to %zd",
-           root->get_realpath(),
-           root,
-           ref_count);
-    return;
-  }
 
   soinfo_list_t unload_list;
   unload_list.push_back(root);
@@ -1916,6 +1894,86 @@
   }
 }
 
+static void soinfo_unload(soinfo* unload_si) {
+  // Note that the library can be loaded but not linked;
+  // in which case there is no root but we still need
+  // to walk the tree and unload soinfos involved.
+  //
+  // This happens on unsuccessful dlopen, when one of
+  // the DT_NEEDED libraries could not be linked/found.
+  bool is_linked = unload_si->is_linked();
+  soinfo* root = is_linked ? unload_si->get_local_group_root() : unload_si;
+
+  LD_LOG(kLogDlopen,
+         "... dlclose(realpath=\"%s\"@%p) ... load group root is \"%s\"@%p",
+         unload_si->get_realpath(),
+         unload_si,
+         root->get_realpath(),
+         root);
+
+
+  size_t ref_count = is_linked ? root->decrement_ref_count() : 0;
+  if (ref_count > 0) {
+    LD_LOG(kLogDlopen,
+           "... dlclose(root=\"%s\"@%p) ... not unloading - decrementing ref_count to %zd",
+           root->get_realpath(),
+           root,
+           ref_count);
+    return;
+  }
+
+  soinfo_unload_impl(root);
+}
+
+void increment_dso_handle_reference_counter(void* dso_handle) {
+  if (dso_handle == nullptr) {
+    return;
+  }
+
+  auto it = g_dso_handle_counters.find(dso_handle);
+  if (it != g_dso_handle_counters.end()) {
+    CHECK(++it->second != 0);
+  } else {
+    soinfo* si = find_containing_library(dso_handle);
+    if (si != nullptr) {
+      ProtectedDataGuard guard;
+      si->set_tls_nodelete();
+    } else {
+      async_safe_fatal(
+          "increment_dso_handle_reference_counter: Couldn't find soinfo by dso_handle=%p",
+          dso_handle);
+    }
+    g_dso_handle_counters[dso_handle] = 1U;
+  }
+}
+
+void decrement_dso_handle_reference_counter(void* dso_handle) {
+  if (dso_handle == nullptr) {
+    return;
+  }
+
+  auto it = g_dso_handle_counters.find(dso_handle);
+  CHECK(it != g_dso_handle_counters.end());
+  CHECK(it->second != 0);
+
+  if (--it->second == 0) {
+    soinfo* si = find_containing_library(dso_handle);
+    if (si != nullptr) {
+      ProtectedDataGuard guard;
+      si->unset_tls_nodelete();
+      if (si->get_ref_count() == 0) {
+        // Perform deferred unload - note that soinfo_unload_impl does not decrement ref_count
+        soinfo_unload_impl(si);
+      }
+    } else {
+      async_safe_fatal(
+          "decrement_dso_handle_reference_counter: Couldn't find soinfo by dso_handle=%p",
+          dso_handle);
+    }
+    g_dso_handle_counters.erase(it);
+  }
+}
+
 static std::string symbol_display_name(const char* sym_name, const char* sym_ver) {
   if (sym_ver == nullptr) {
     return sym_name;
@@ -2305,7 +2363,8 @@
     add_soinfos_to_namespace(parent_namespace->soinfo_list(), ns);
     // and copy parent namespace links
     for (auto& link : parent_namespace->linked_namespaces()) {
-      ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames());
+      ns->add_linked_namespace(link.linked_namespace(), link.shared_lib_sonames(),
+                               link.allow_all_shared_libs());
     }
   } else {
     // If not shared - copy only the shared group
@@ -2341,7 +2400,25 @@
   std::unordered_set<std::string> sonames_set(sonames.begin(), sonames.end());
 
   ProtectedDataGuard guard;
-  namespace_from->add_linked_namespace(namespace_to, sonames_set);
+  namespace_from->add_linked_namespace(namespace_to, sonames_set, false);
+
+  return true;
+}
+
+bool link_namespaces_all_libs(android_namespace_t* namespace_from,
+                              android_namespace_t* namespace_to) {
+  if (namespace_from == nullptr) {
+    DL_ERR("error linking namespaces: namespace_from is null.");
+    return false;
+  }
+
+  if (namespace_to == nullptr) {
+    DL_ERR("error linking namespaces: namespace_to is null.");
+    return false;
+  }
+
+  ProtectedDataGuard guard;
+  namespace_from->add_linked_namespace(namespace_to, std::unordered_set<std::string>(), true);
 
   return true;
 }
@@ -2537,6 +2614,50 @@
   return true;
 }
 
+void soinfo::apply_relr_reloc(ElfW(Addr) offset) {
+  ElfW(Addr) address = offset + load_bias;
+  *reinterpret_cast<ElfW(Addr)*>(address) += load_bias;
+}
+
+// Process relocations in SHT_RELR section (experimental).
+// Details of the encoding are described in this post:
+//   https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
+bool soinfo::relocate_relr() {
+  ElfW(Relr)* begin = relr_;
+  ElfW(Relr)* end = relr_ + relr_count_;
+  constexpr size_t wordsize = sizeof(ElfW(Addr));
+
+  ElfW(Addr) base = 0;
+  for (ElfW(Relr)* current = begin; current < end; ++current) {
+    ElfW(Relr) entry = *current;
+    ElfW(Addr) offset;
+
+    if ((entry&1) == 0) {
+      // Even entry: encodes the offset for next relocation.
+      offset = static_cast<ElfW(Addr)>(entry);
+      apply_relr_reloc(offset);
+      // Set base offset for subsequent bitmap entries.
+      base = offset + wordsize;
+      continue;
+    }
+
+    // Odd entry: encodes bitmap for relocations starting at base.
+    offset = base;
+    while (entry != 0) {
+      entry >>= 1;
+      if ((entry&1) != 0) {
+        apply_relr_reloc(offset);
+      }
+      offset += wordsize;
+    }
+
+    // Advance base offset by 63 words for 64-bit platforms,
+    // or 31 words for 32-bit platforms.
+    base += (8*wordsize - 1) * wordsize;
+  }
+  return true;
+}
+
 #if !defined(__mips__)
 #if defined(USE_RELA)
 static ElfW(Addr) get_addend(ElfW(Rela)* rela, ElfW(Addr) reloc_addr __unused) {
@@ -3093,7 +3214,7 @@
         }
         break;
 
-      // ignored (see DT_RELCOUNT comments for details)
+      // Ignored (see DT_RELCOUNT comments for details).
       case DT_RELACOUNT:
         break;
 
@@ -3154,6 +3275,25 @@
         return false;
 
 #endif
+      case DT_RELR:
+        relr_ = reinterpret_cast<ElfW(Relr)*>(load_bias + d->d_un.d_ptr);
+        break;
+
+      case DT_RELRSZ:
+        relr_count_ = d->d_un.d_val / sizeof(ElfW(Relr));
+        break;
+
+      case DT_RELRENT:
+        if (d->d_un.d_val != sizeof(ElfW(Relr))) {
+          DL_ERR("invalid DT_RELRENT: %zd", static_cast<size_t>(d->d_un.d_val));
+          return false;
+        }
+        break;
+
+      // Ignored (see DT_RELCOUNT comments for details).
+      case DT_RELRCOUNT:
+        break;
+
       case DT_INIT:
         init_func_ = reinterpret_cast<linker_ctor_function_t>(load_bias + d->d_un.d_ptr);
         DEBUG("%s constructors (DT_INIT) found at %p", get_realpath(), init_func_);
@@ -3446,16 +3586,23 @@
     }
   }
 
+  if (relr_ != nullptr) {
+    DEBUG("[ relocating %s relr ]", get_realpath());
+    if (!relocate_relr()) {
+      return false;
+    }
+  }
+
 #if defined(USE_RELA)
   if (rela_ != nullptr) {
-    DEBUG("[ relocating %s ]", get_realpath());
+    DEBUG("[ relocating %s rela ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(rela_, rela_count_), global_group, local_group)) {
       return false;
     }
   }
   if (plt_rela_ != nullptr) {
-    DEBUG("[ relocating %s plt ]", get_realpath());
+    DEBUG("[ relocating %s plt rela ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(plt_rela_, plt_rela_count_), global_group, local_group)) {
       return false;
@@ -3463,14 +3610,14 @@
   }
 #else
   if (rel_ != nullptr) {
-    DEBUG("[ relocating %s ]", get_realpath());
+    DEBUG("[ relocating %s rel ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(rel_, rel_count_), global_group, local_group)) {
       return false;
     }
   }
   if (plt_rel_ != nullptr) {
-    DEBUG("[ relocating %s plt ]", get_realpath());
+    DEBUG("[ relocating %s plt rel ]", get_realpath());
     if (!relocate(version_tracker,
             plain_reloc_iterator(plt_rel_, plt_rel_count_), global_group, local_group)) {
       return false;
@@ -3573,7 +3720,7 @@
   std::string error_msg;
 
   std::string ld_config_vndk = kLdConfigFilePath;
-  size_t insert_pos = ld_config_vndk.find_last_of(".");
+  size_t insert_pos = ld_config_vndk.find_last_of('.');
   if (insert_pos == std::string::npos) {
     insert_pos = ld_config_vndk.length();
   }
@@ -3650,7 +3797,11 @@
       auto it_to = namespaces.find(ns_link.ns_name());
       CHECK(it_to != namespaces.end());
       android_namespace_t* namespace_to = it_to->second;
-      link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
+      if (ns_link.allow_all_shared_libs()) {
+        link_namespaces_all_libs(namespace_from, namespace_to);
+      } else {
+        link_namespaces(namespace_from, namespace_to, ns_link.shared_libs().c_str());
+      }
     }
   }
   // we can no longer rely on the fact that libdl.so is part of default namespace
diff --git a/linker/linker.generic.map b/linker/linker.generic.map
index abd792a..45bb0b5 100644
--- a/linker/linker.generic.map
+++ b/linker/linker.generic.map
@@ -17,7 +17,10 @@
     __loader_android_dlwarning;
     __loader_cfi_fail;
     __loader_android_link_namespaces;
+    __loader_android_link_namespaces_all_libs;
     __loader_android_get_exported_namespace;
+    __loader_add_thread_local_dtor;
+    __loader_remove_thread_local_dtor;
     rtld_db_dlactivity;
   local:
     *;
diff --git a/linker/linker.h b/linker/linker.h
index f5a202f..29d40fa 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -180,6 +180,12 @@
                      android_namespace_t* namespace_to,
                      const char* shared_lib_sonames);
 
+bool link_namespaces_all_libs(android_namespace_t* namespace_from,
+                              android_namespace_t* namespace_to);
+
 android_namespace_t* get_exported_namespace(const char* name);
 
+void increment_dso_handle_reference_counter(void* dso_handle);
+void decrement_dso_handle_reference_counter(void* dso_handle);
+
 #endif
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 60b7ad9..83c2f36 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -489,12 +489,15 @@
         return false;
       }
 
+      bool allow_all_shared_libs = properties.get_bool(property_name_prefix + ".link." +
+                                                       linked_ns_name + ".allow_all_shared_libs");
+
       std::string shared_libs = properties.get_string(property_name_prefix +
                                                       ".link." +
                                                       linked_ns_name +
                                                       ".shared_libs", &lineno);
 
-      if (shared_libs.empty()) {
+      if (!allow_all_shared_libs && shared_libs.empty()) {
         *error_msg = create_error_msg(ld_config_file_path,
                                       lineno,
                                       std::string("list of shared_libs for ") +
@@ -505,7 +508,15 @@
         return false;
       }
 
-      ns_config->add_namespace_link(linked_ns_name, shared_libs);
+      if (allow_all_shared_libs && !shared_libs.empty()) {
+        *error_msg = create_error_msg(ld_config_file_path, lineno,
+                                      std::string("both shared_libs and allow_all_shared_libs "
+                                                  "are set for ") +
+                                      name + "->" + linked_ns_name + " link.");
+        return false;
+      }
+
+      ns_config->add_namespace_link(linked_ns_name, shared_libs, allow_all_shared_libs);
     }
 
     ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
diff --git a/linker/linker_config.h b/linker/linker_config.h
index dde9362..0c50d57 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -43,8 +43,10 @@
 class NamespaceLinkConfig {
  public:
   NamespaceLinkConfig() = default;
-  NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs)
-      : ns_name_(ns_name), shared_libs_(shared_libs)  {}
+  NamespaceLinkConfig(const std::string& ns_name, const std::string& shared_libs,
+                      bool allow_all_shared_libs)
+      : ns_name_(ns_name), shared_libs_(shared_libs),
+        allow_all_shared_libs_(allow_all_shared_libs) {}
 
   const std::string& ns_name() const {
     return ns_name_;
@@ -54,9 +56,14 @@
     return shared_libs_;
   }
 
+  bool allow_all_shared_libs() const {
+    return allow_all_shared_libs_;
+  }
+
  private:
   std::string ns_name_;
   std::string shared_libs_;
+  bool allow_all_shared_libs_;
 };
 
 class NamespaceConfig {
@@ -89,8 +96,9 @@
     return namespace_links_;
   }
 
-  void add_namespace_link(const std::string& ns_name, const std::string& shared_libs) {
-    namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs));
+  void add_namespace_link(const std::string& ns_name, const std::string& shared_libs,
+                          bool allow_all_shared_libs) {
+    namespace_links_.push_back(NamespaceLinkConfig(ns_name, shared_libs, allow_all_shared_libs));
   }
 
   void set_isolated(bool isolated) {
diff --git a/linker/linker_libcxx_support.cpp b/linker/linker_libcxx_support.cpp
index 41ed8bc..3d15b33 100644
--- a/linker/linker_libcxx_support.cpp
+++ b/linker/linker_libcxx_support.cpp
@@ -35,3 +35,7 @@
 extern "C" int __cxa_type_match() {
   async_safe_fatal("__cxa_type_match is not implemented in the linker");
 }
+
+int posix_memalign(void**, size_t, size_t) {
+  async_safe_fatal("posix_memalign is not implemented in the linker");
+}
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 16906d6..a7fe0d5 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -40,8 +40,10 @@
 struct android_namespace_link_t {
  public:
   android_namespace_link_t(android_namespace_t* linked_namespace,
-                           const std::unordered_set<std::string>& shared_lib_sonames)
-      : linked_namespace_(linked_namespace), shared_lib_sonames_(shared_lib_sonames)
+                           const std::unordered_set<std::string>& shared_lib_sonames,
+                           bool allow_all_shared_libs)
+      : linked_namespace_(linked_namespace), shared_lib_sonames_(shared_lib_sonames),
+        allow_all_shared_libs_(allow_all_shared_libs)
   {}
 
   android_namespace_t* linked_namespace() const {
@@ -53,12 +55,17 @@
   }
 
   bool is_accessible(const char* soname) const {
-    return shared_lib_sonames_.find(soname) != shared_lib_sonames_.end();
+    return allow_all_shared_libs_ || shared_lib_sonames_.find(soname) != shared_lib_sonames_.end();
+  }
+
+  bool allow_all_shared_libs() const {
+    return allow_all_shared_libs_;
   }
 
  private:
   android_namespace_t* const linked_namespace_;
   const std::unordered_set<std::string> shared_lib_sonames_;
+  bool allow_all_shared_libs_;
 };
 
 struct android_namespace_t {
@@ -105,8 +112,10 @@
     return linked_namespaces_;
   }
   void add_linked_namespace(android_namespace_t* linked_namespace,
-                            const std::unordered_set<std::string>& shared_lib_sonames) {
-    linked_namespaces_.push_back(android_namespace_link_t(linked_namespace, shared_lib_sonames));
+                            const std::unordered_set<std::string>& shared_lib_sonames,
+                            bool allow_all_shared_libs) {
+    linked_namespaces_.push_back(
+        android_namespace_link_t(linked_namespace, shared_lib_sonames, allow_all_shared_libs));
   }
 
   void add_soinfo(soinfo* si) {
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index dd91752..54bfcf0 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -537,6 +537,14 @@
   rtld_flags_ |= RTLD_NODELETE;
 }
 
+void soinfo::set_tls_nodelete() {
+  flags_ |= FLAG_TLS_NODELETE;
+}
+
+void soinfo::unset_tls_nodelete() {
+  flags_ &= ~FLAG_TLS_NODELETE;
+}
+
 const char* soinfo::get_realpath() const {
 #if defined(__work_around_b_24465209__)
   if (has_min_version(2)) {
@@ -650,7 +658,11 @@
 }
 
 bool soinfo::can_unload() const {
-  return !is_linked() || ((get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0);
+  return !is_linked() ||
+         (
+             (get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0 &&
+             (flags_ & FLAG_TLS_NODELETE) == 0
+         );
 }
 
 bool soinfo::is_linked() const {
@@ -693,6 +705,10 @@
   return --local_group_root_->ref_count_;
 }
 
+size_t soinfo::get_ref_count() const {
+  return local_group_root_->ref_count_;
+}
+
 soinfo* soinfo::get_local_group_root() const {
   return local_group_root_;
 }
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 273c36c..447c7c3 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -52,9 +52,17 @@
                                          // when load group is crossing
                                          // namespace boundary twice and second
                                          // local group depends on the same libraries.
+#define FLAG_TLS_NODELETE     0x00000200 // This flag set when there is at least one
+                                         // outstanding thread_local dtor
+                                         // registered with this soinfo. In such
+                                         // a case the actual unload is
+                                         // postponed until the last thread_local
+                                         // destructor associated with this
+                                         // soinfo is executed and this flag is
+                                         // unset.
 #define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
 
-#define SOINFO_VERSION 3
+#define SOINFO_VERSION 4
 
 typedef void (*linker_dtor_function_t)();
 typedef void (*linker_ctor_function_t)(int, char**, char**);
@@ -253,9 +261,12 @@
   void set_linker_flag();
   void set_main_executable();
   void set_nodelete();
+  void set_tls_nodelete();
+  void unset_tls_nodelete();
 
   size_t increment_ref_count();
   size_t decrement_ref_count();
+  size_t get_ref_count() const;
 
   soinfo* get_local_group_root() const;
 
@@ -298,6 +309,8 @@
   template<typename ElfRelIteratorT>
   bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
                 const soinfo_list_t& global_group, const soinfo_list_t& local_group);
+  bool relocate_relr();
+  void apply_relr_reloc(ElfW(Addr) offset);
 
  private:
   // This part of the structure is only available
@@ -354,6 +367,10 @@
   friend soinfo* get_libdl_info(const char* linker_path,
                                 const soinfo& linker_si,
                                 const link_map& linker_map);
+
+  // version >= 4
+  ElfW(Relr)* relr_;
+  size_t relr_count_;
 };
 
 // This function is used by dlvsym() to calculate hash of sym_ver
diff --git a/linker/tests/linker_config_test.cpp b/linker/tests/linker_config_test.cpp
index 4c0dcdd..e716879 100644
--- a/linker/tests/linker_config_test.cpp
+++ b/linker/tests/linker_config_test.cpp
@@ -81,6 +81,8 @@
   "namespace.vndk.search.paths = /system/${LIB}/vndk\n"
   "namespace.vndk.asan.search.paths = /data\n"
   "namespace.vndk.asan.search.paths += /system/${LIB}/vndk\n"
+  "namespace.vndk.links = default\n"
+  "namespace.vndk.link.default.allow_all_shared_libs = true\n"
   "\n";
 
 static bool write_version(const std::string& path, uint32_t version) {
@@ -154,10 +156,14 @@
 
   const auto& default_ns_links = default_ns_config->links();
   ASSERT_EQ(2U, default_ns_links.size());
+
   ASSERT_EQ("system", default_ns_links[0].ns_name());
   ASSERT_EQ("libc.so:libm.so:libdl.so:libstdc++.so", default_ns_links[0].shared_libs());
+  ASSERT_FALSE(default_ns_links[0].allow_all_shared_libs());
+
   ASSERT_EQ("vndk", default_ns_links[1].ns_name());
   ASSERT_EQ("libcutils.so:libbase.so", default_ns_links[1].shared_libs());
+  ASSERT_FALSE(default_ns_links[1].allow_all_shared_libs());
 
   auto& ns_configs = config->namespace_configs();
   ASSERT_EQ(3U, ns_configs.size());
@@ -187,8 +193,13 @@
   ASSERT_TRUE(ns_vndk != nullptr) << "vndk namespace was not found";
 
   ASSERT_FALSE(ns_vndk->isolated()); // malformed bool property
-  ASSERT_FALSE(ns_vndk->visible()); // undefined bool property 
+  ASSERT_FALSE(ns_vndk->visible()); // undefined bool property
   ASSERT_EQ(kExpectedVndkSearchPath, ns_vndk->search_paths());
+
+  const auto& ns_vndk_links = ns_vndk->links();
+  ASSERT_EQ(1U, ns_vndk_links.size());
+  ASSERT_EQ("default", ns_vndk_links[0].ns_name());
+  ASSERT_TRUE(ns_vndk_links[0].allow_all_shared_libs());
 }
 
 TEST(linker_config, smoke) {
@@ -198,3 +209,40 @@
 TEST(linker_config, asan_smoke) {
   run_linker_config_smoke_test(true);
 }
+
+TEST(linker_config, ns_link_shared_libs_invalid_settings) {
+  // This unit test ensures an error is emitted when a namespace link in ld.config.txt specifies
+  // both shared_libs and allow_all_shared_libs.
+
+  static const char config_str[] =
+    "dir.test = /data/local/tmp\n"
+    "\n"
+    "[test]\n"
+    "additional.namespaces = system\n"
+    "namespace.default.links = system\n"
+    "namespace.default.link.system.shared_libs = libc.so:libm.so\n"
+    "namespace.default.link.system.allow_all_shared_libs = true\n"
+    "\n";
+
+  TemporaryFile tmp_file;
+  close(tmp_file.fd);
+  tmp_file.fd = -1;
+
+  android::base::WriteStringToFile(config_str, tmp_file.path);
+
+  TemporaryDir tmp_dir;
+
+  std::string executable_path = std::string(tmp_dir.path) + "/some-binary";
+
+  const Config* config = nullptr;
+  std::string error_msg;
+  ASSERT_FALSE(Config::read_binary_config(tmp_file.path,
+                                          executable_path.c_str(),
+                                          false,
+                                          &config,
+                                          &error_msg));
+  ASSERT_TRUE(config == nullptr);
+  ASSERT_EQ(std::string(tmp_file.path) + ":6: "
+            "error: both shared_libs and allow_all_shared_libs are set for default->system link.",
+            error_msg);
+}
diff --git a/tests/Android.bp b/tests/Android.bp
index c1e455d..56a4722 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -140,6 +140,7 @@
         "sys_sem_test.cpp",
         "sys_sendfile_test.cpp",
         "sys_shm_test.cpp",
+        "sys_signalfd_test.cpp",
         "sys_socket_test.cpp",
         "sys_stat_test.cpp",
         "sys_statvfs_test.cpp",
@@ -244,10 +245,13 @@
 
 cc_test_library {
     name: "libfortify1-tests-clang",
-    defaults: ["bionic_fortify_tests_defaults", "bionic_tests_defaults"],
+    defaults: [
+        "bionic_fortify_tests_defaults",
+        "bionic_tests_defaults",
+    ],
     cflags: [
         "-D_FORTIFY_SOURCE=1",
-        "-DTEST_NAME=Fortify1_clang"
+        "-DTEST_NAME=Fortify1_clang",
     ],
     shared: {
         enabled: false,
@@ -256,10 +260,13 @@
 
 cc_test_library {
     name: "libfortify2-tests-clang",
-    defaults: ["bionic_fortify_tests_defaults", "bionic_tests_defaults"],
+    defaults: [
+        "bionic_fortify_tests_defaults",
+        "bionic_tests_defaults",
+    ],
     cflags: [
         "-D_FORTIFY_SOURCE=2",
-        "-DTEST_NAME=Fortify2_clang"
+        "-DTEST_NAME=Fortify2_clang",
     ],
     shared: {
         enabled: false,
@@ -311,7 +318,10 @@
 
 cc_test_library {
     name: "libBionicLoaderTests",
-    defaults: ["bionic_tests_defaults", "llvm-defaults"],
+    defaults: [
+        "bionic_tests_defaults",
+        "llvm-defaults",
+    ],
     srcs: [
         "atexit_test.cpp",
         "dl_test.cpp",
@@ -346,7 +356,7 @@
                 "libLLVMCore",
                 "libLLVMSupport",
             ],
-        }
+        },
     },
 }
 
@@ -413,6 +423,7 @@
     target: {
         android: {
             shared_libs: [
+                "ld-android",
                 "libdl",
                 "libdl_preempt_test_1",
                 "libdl_preempt_test_2",
@@ -437,12 +448,15 @@
                 "-Wl,--enable-new-dtags",
             ],
         },
-    }
+    },
 }
 
 cc_test {
     name: "bionic-unit-tests",
-    defaults: ["bionic_unit_tests_defaults", "bionic_tests_defaults"],
+    defaults: [
+        "bionic_unit_tests_defaults",
+        "bionic_tests_defaults",
+    ],
 
     target: {
         android: {
@@ -554,6 +568,10 @@
         "libnstest_root",
         "libnstest_public",
         "libnstest_public_internal",
+        "libnstest_ns_a_public1",
+        "libnstest_ns_a_public1_internal",
+        "libnstest_ns_b_public2",
+        "libnstest_ns_b_public3",
     ],
 }
 
diff --git a/tests/BionicDeathTest.h b/tests/BionicDeathTest.h
index 3e8d7b2..6826ab7 100644
--- a/tests/BionicDeathTest.h
+++ b/tests/BionicDeathTest.h
@@ -21,25 +21,28 @@
 
 #include <gtest/gtest.h>
 
+#if !defined(__BIONIC__)
+#define sigaction64 sigaction
+#endif
+
 class BionicDeathTest : public testing::Test {
  protected:
   virtual void SetUp() {
     // Suppress debuggerd stack traces. Too slow.
     for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
-      struct sigaction action = {};
-      action.sa_handler = SIG_DFL;
-      sigaction(signo, &action, &previous_);
+      struct sigaction64 action = { .sa_handler = SIG_DFL };
+      sigaction64(signo, &action, &previous_);
     }
   }
 
   virtual void TearDown() {
     for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) {
-      sigaction(signo, &previous_, nullptr);
+      sigaction64(signo, &previous_, nullptr);
     }
   }
 
  private:
-  struct sigaction previous_;
+  struct sigaction64 previous_;
 };
 
 #endif // BIONIC_TESTS_BIONIC_DEATH_TEST_H_
diff --git a/tests/ScopedSignalHandler.h b/tests/ScopedSignalHandler.h
index 8998d0d..36bbf10 100644
--- a/tests/ScopedSignalHandler.h
+++ b/tests/ScopedSignalHandler.h
@@ -20,6 +20,27 @@
 #include <signal.h>
 #include <string.h>
 
+#if defined(__GLIBC__)
+#define posix_spawnattr_getsigdefault64 posix_spawnattr_getsigdefault
+#define posix_spawnattr_getsigmask64 posix_spawnattr_getsigmask
+#define posix_spawnattr_setsigdefault64 posix_spawnattr_setsigdefault
+#define posix_spawnattr_setsigmask64 posix_spawnattr_setsigmask
+#define pthread_sigmask64 pthread_sigmask
+#define sigaction64 sigaction
+#define sigaddset64 sigaddset
+#define sigdelset64 sigdelset
+#define sigemptyset64 sigemptyset
+#define sigfillset64 sigfillset
+#define sigismember64 sigismember
+#define sigpending64 sigpending
+#define sigprocmask64 sigprocmask
+#define sigset64_t sigset_t
+#define sigsuspend64 sigsuspend
+#define sigtimedwait64 sigtimedwait
+#define sigwait64 sigwait
+#define sigwaitinfo64 sigwaitinfo
+#endif
+
 class ScopedSignalHandler {
  public:
   ScopedSignalHandler(int signal_number, void (*handler)(int), int sa_flags = 0)
@@ -27,7 +48,7 @@
     memset(&action_, 0, sizeof(action_));
     action_.sa_flags = sa_flags;
     action_.sa_handler = handler;
-    sigaction(signal_number_, &action_, &old_action_);
+    sigaction64(signal_number_, &action_, &old_action_);
   }
 
   ScopedSignalHandler(int signal_number, void (*action)(int, siginfo_t*, void*),
@@ -36,35 +57,35 @@
     memset(&action_, 0, sizeof(action_));
     action_.sa_flags = sa_flags;
     action_.sa_sigaction = action;
-    sigaction(signal_number_, &action_, &old_action_);
+    sigaction64(signal_number_, &action_, &old_action_);
   }
 
   ScopedSignalHandler(int signal_number) : signal_number_(signal_number) {
-    sigaction(signal_number, nullptr, &old_action_);
+    sigaction64(signal_number, nullptr, &old_action_);
   }
 
   ~ScopedSignalHandler() {
-    sigaction(signal_number_, &old_action_, NULL);
+    sigaction64(signal_number_, &old_action_, NULL);
   }
 
  private:
-  struct sigaction action_;
-  struct sigaction old_action_;
+  struct sigaction64 action_;
+  struct sigaction64 old_action_;
   const int signal_number_;
 };
 
-class ScopedSignalMask {
+class SignalMaskRestorer {
  public:
-  ScopedSignalMask() {
-    sigprocmask(SIG_SETMASK, nullptr, &old_mask_);
+  SignalMaskRestorer() {
+    sigprocmask64(SIG_SETMASK, nullptr, &old_mask_);
   }
 
-  ~ScopedSignalMask() {
-    sigprocmask(SIG_SETMASK, &old_mask_, nullptr);
+  ~SignalMaskRestorer() {
+    sigprocmask64(SIG_SETMASK, &old_mask_, nullptr);
   }
 
  private:
-  sigset_t old_mask_;
+  sigset64_t old_mask_;
 };
 
 #endif // _BIONIC_TESTS_SCOPED_SIGNAL_HANDLER_H
diff --git a/tests/TemporaryFile.h b/tests/TemporaryFile.h
index 5c2fe4f..070b71a 100644
--- a/tests/TemporaryFile.h
+++ b/tests/TemporaryFile.h
@@ -22,7 +22,7 @@
 template <typename T = int (*)(char*)>
 class GenericTemporaryFile {
  public:
-  GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn(mk_fn) {
+  explicit GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn(mk_fn) {
     // Since we might be running on the host or the target, and if we're
     // running on the host we might be running under bionic or glibc,
     // let's just try both possible temporary directories and take the
@@ -33,7 +33,7 @@
     }
   }
 
-  GenericTemporaryFile(const char* dirpath, T mk_fn = mkstemp) : mk_fn(mk_fn) {
+  explicit GenericTemporaryFile(const char* dirpath, T mk_fn = mkstemp) : mk_fn(mk_fn) {
     init(dirpath);
   }
 
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index 85b20de..2aaa192 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
-
 #if defined(__BIONIC_LP32_USE_LONG_DOUBLE)
 #define COMPLEX_TEST complex_h_force_long_double
 #else
@@ -43,26 +41,27 @@
 
 #include <math.h> // For M_PI_2/M_PI_2l.
 
-#if 0
-// Note that gtest doesn't support complex numbers, so the output from
-// assertion failures is misleading/useless (at best you'll only see the real
-// part).
-// TODO: find out why gtest doesn't use these; until then they're only useful
-// for manual printf^Woperator<< debugging.
+// Prettify gtest Complex printing.
 #include <iostream>
-std::ostream& operator<<(std::ostream& os, const double _Complex c) {
-  os << "(" << creal(c) << "," << cimag(c) << "i)";
- return os;
+namespace testing {
+namespace internal {
+inline void PrintTo(const double _Complex& c, std::ostream* os) {
+  *os << "(" << creal(c) << "," << cimag(c) << "i)";
 }
-std::ostream& operator<<(std::ostream& os, const float _Complex c) {
-  os << "(" << crealf(c) << "," << cimagf(c) << "i)";
-  return os;
+inline void PrintTo(const float _Complex& c, std::ostream* os) {
+  *os << "(" << crealf(c) << "," << cimagf(c) << "i)";
 }
-std::ostream& operator<<(std::ostream& os, const long double _Complex c) {
-  os << "(" << creall(c) << "," << cimagl(c) << "i)";
-  return os;
+inline void PrintTo(const long double _Complex& c, std::ostream* os) {
+  *os << "(" << creall(c) << "," << cimagl(c) << "i)";
 }
-#endif
+}
+}
+
+// Macro 'I' defined in complex.h conflicts with gtest.h.
+#pragma push_macro("I")
+#undef I
+#include <gtest/gtest.h>
+#pragma pop_macro("I")
 
 TEST(COMPLEX_TEST, cabs) {
   ASSERT_EQ(0.0, cabs(0));
diff --git a/tests/dlext_private.h b/tests/dlext_private.h
index dea92ee..2621a68 100644
--- a/tests/dlext_private.h
+++ b/tests/dlext_private.h
@@ -95,6 +95,9 @@
                                     android_namespace_t* to,
                                     const char* shared_libs_sonames);
 
+extern bool android_link_namespaces_all_libs(android_namespace_t* from,
+                                             android_namespace_t* to);
+
 extern void android_set_application_target_sdk_version(uint32_t target);
 
 __END_DECLS
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 04b83f2..9ed1a56 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -425,7 +425,7 @@
   }
 
   void CreateRelroFile(const char* lib, const char* relro_file) {
-    int relro_fd = open(relro_file, O_RDWR | O_TRUNC);
+    int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
     ASSERT_NOERROR(relro_fd);
 
     pid_t pid = fork();
@@ -447,7 +447,7 @@
     AssertChildExited(pid, 0);
 
     // reopen file for reading so it can be used
-    relro_fd = open(relro_file, O_RDONLY);
+    relro_fd = open(relro_file, O_RDONLY | O_CLOEXEC);
     ASSERT_NOERROR(relro_fd);
     extinfo_.flags |= ANDROID_DLEXT_USE_RELRO;
     extinfo_.relro_fd = relro_fd;
@@ -1737,6 +1737,126 @@
   ASSERT_EQ(expected_dlerror, dlerror());
 }
 
+extern "C" bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from,
+                                                          android_namespace_t* namespace_to);
+
+TEST(dlext, ns_link_namespaces_invalid_arguments) {
+  ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
+
+  android_namespace_t* ns =
+          android_create_namespace("private",
+                                   nullptr,
+                                   (get_testlib_root() + "/private_namespace_libs").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_REGULAR,
+                                   nullptr,
+                                   nullptr);
+  ASSERT_TRUE(ns != nullptr) << dlerror();
+
+  // Test android_link_namespaces()
+  ASSERT_FALSE(android_link_namespaces(nullptr, nullptr, "libc.so"));
+  ASSERT_STREQ("android_link_namespaces failed: error linking namespaces: namespace_from is null.",
+               dlerror());
+
+  ASSERT_FALSE(android_link_namespaces(ns, nullptr, nullptr));
+  ASSERT_STREQ("android_link_namespaces failed: "
+               "error linking namespaces \"private\"->\"(default)\": "
+               "the list of shared libraries is empty.", dlerror());
+
+  ASSERT_FALSE(android_link_namespaces(ns, nullptr, ""));
+  ASSERT_STREQ("android_link_namespaces failed: "
+               "error linking namespaces \"private\"->\"(default)\": "
+               "the list of shared libraries is empty.", dlerror());
+
+  // Test __loader_android_link_namespaces_all_libs()
+  ASSERT_FALSE(__loader_android_link_namespaces_all_libs(nullptr, nullptr));
+  ASSERT_STREQ("android_link_namespaces_all_libs failed: "
+               "error linking namespaces: namespace_from is null.", dlerror());
+
+  ASSERT_FALSE(__loader_android_link_namespaces_all_libs(nullptr, ns));
+  ASSERT_STREQ("android_link_namespaces_all_libs failed: "
+               "error linking namespaces: namespace_from is null.", dlerror());
+
+  ASSERT_FALSE(__loader_android_link_namespaces_all_libs(ns, nullptr));
+  ASSERT_STREQ("android_link_namespaces_all_libs failed: "
+               "error linking namespaces: namespace_to is null.", dlerror());
+}
+
+TEST(dlext, ns_allow_all_shared_libs) {
+  ASSERT_TRUE(android_init_anonymous_namespace(g_core_shared_libs.c_str(), nullptr));
+
+  android_namespace_t* ns_a =
+          android_create_namespace("ns_a",
+                                   nullptr,
+                                   (get_testlib_root() + "/ns_a").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   nullptr,
+                                   nullptr);
+  ASSERT_TRUE(ns_a != nullptr) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_a, nullptr, g_core_shared_libs.c_str())) << dlerror();
+
+  android_namespace_t* ns_b =
+          android_create_namespace("ns_b",
+                                   nullptr,
+                                   (get_testlib_root() + "/ns_b").c_str(),
+                                   ANDROID_NAMESPACE_TYPE_ISOLATED,
+                                   nullptr,
+                                   nullptr);
+  ASSERT_TRUE(ns_b != nullptr) << dlerror();
+  ASSERT_TRUE(android_link_namespaces(ns_b, nullptr, g_core_shared_libs.c_str())) << dlerror();
+
+  ASSERT_TRUE(android_link_namespaces(ns_b, ns_a, "libnstest_ns_a_public1.so")) << dlerror();
+  ASSERT_TRUE(__loader_android_link_namespaces_all_libs(ns_a, ns_b)) << dlerror();
+
+  // Load libs with android_dlopen_ext() from namespace b
+  android_dlextinfo extinfo;
+  extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
+  extinfo.library_namespace = ns_b;
+
+  void* ns_b_handle1 = android_dlopen_ext("libnstest_ns_a_public1.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_b_handle1 != nullptr) << dlerror();
+
+  void* ns_b_handle1_internal =
+      android_dlopen_ext("libnstest_ns_a_public1_internal.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_b_handle1_internal == nullptr);
+
+  void* ns_b_handle2 = android_dlopen_ext("libnstest_ns_b_public2.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_b_handle2 != nullptr) << dlerror();
+
+  void* ns_b_handle3 = android_dlopen_ext("libnstest_ns_b_public3.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_b_handle3 != nullptr) << dlerror();
+
+  // Load libs with android_dlopen_ext() from namespace a
+  extinfo.library_namespace = ns_a;
+
+  void* ns_a_handle1 = android_dlopen_ext("libnstest_ns_a_public1.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_a_handle1 != nullptr) << dlerror();
+
+  void* ns_a_handle1_internal =
+      android_dlopen_ext("libnstest_ns_a_public1_internal.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_a_handle1_internal != nullptr) << dlerror();
+
+  void* ns_a_handle2 = android_dlopen_ext("libnstest_ns_b_public2.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_a_handle2 != nullptr) << dlerror();
+
+  void* ns_a_handle3 = android_dlopen_ext("libnstest_ns_b_public3.so", RTLD_NOW, &extinfo);
+  ASSERT_TRUE(ns_a_handle3 != nullptr) << dlerror();
+
+  // Compare the dlopen handle
+  ASSERT_EQ(ns_b_handle1, ns_a_handle1);
+  ASSERT_EQ(ns_b_handle2, ns_a_handle2);
+  ASSERT_EQ(ns_b_handle3, ns_a_handle3);
+
+  // Close libs
+  dlclose(ns_b_handle1);
+  dlclose(ns_b_handle2);
+  dlclose(ns_b_handle3);
+
+  dlclose(ns_a_handle1);
+  dlclose(ns_a_handle1_internal);
+  dlclose(ns_a_handle2);
+  dlclose(ns_a_handle3);
+}
+
 TEST(dlext, ns_anonymous) {
   static const char* root_lib = "libnstest_root.so";
   std::string shared_libs = g_core_shared_libs + ":" + g_public_lib;
diff --git a/tests/dlfcn_symlink_support.cpp b/tests/dlfcn_symlink_support.cpp
index be1839e..a5d3c3e 100644
--- a/tests/dlfcn_symlink_support.cpp
+++ b/tests/dlfcn_symlink_support.cpp
@@ -44,7 +44,7 @@
     return 0;
   }
 
-  if (android::base::EndsWith(info->dlpi_name, suffix.c_str())) {
+  if (android::base::EndsWith(info->dlpi_name, suffix)) {
     std::string* path = reinterpret_cast<std::string*>(data);
     *path = info->dlpi_name;
     return 1; // found
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 6bd6e0c..000d1f7 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -1317,6 +1317,84 @@
   dlclose(handle);
 }
 
+TEST(dlfcn, dlclose_after_thread_local_dtor) {
+  bool is_dtor_triggered = false;
+
+  auto f = [](void* handle, bool* is_dtor_triggered) {
+    typedef void (*fn_t)(bool*);
+    fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "init_thread_local_variable"));
+    ASSERT_TRUE(fn != nullptr) << dlerror();
+
+    fn(is_dtor_triggered);
+
+    ASSERT_TRUE(!*is_dtor_triggered);
+  };
+
+  void* handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr);
+
+  handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+
+  std::thread t(f, handle, &is_dtor_triggered);
+  t.join();
+
+  ASSERT_TRUE(is_dtor_triggered);
+  dlclose(handle);
+
+  handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr);
+}
+
+TEST(dlfcn, dlclose_before_thread_local_dtor) {
+  bool is_dtor_triggered = false;
+
+  auto f = [](bool* is_dtor_triggered) {
+    void* handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+    ASSERT_TRUE(handle == nullptr);
+
+    handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW);
+    ASSERT_TRUE(handle != nullptr) << dlerror();
+
+    typedef void (*fn_t)(bool*);
+    fn_t fn = reinterpret_cast<fn_t>(dlsym(handle, "init_thread_local_variable"));
+    ASSERT_TRUE(fn != nullptr) << dlerror();
+
+    fn(is_dtor_triggered);
+
+    dlclose(handle);
+
+    ASSERT_TRUE(!*is_dtor_triggered);
+
+    // Since we have thread_atexit dtors associated with handle - the library should
+    // still be availabe.
+    handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+    ASSERT_TRUE(handle != nullptr) << dlerror();
+    dlclose(handle);
+  };
+
+  void* handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+  dlclose(handle);
+
+  handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr);
+
+  std::thread t(f, &is_dtor_triggered);
+  t.join();
+#if defined(__BIONIC__)
+  // ld-android.so unloads unreferenced libraries on pthread_exit()
+  ASSERT_TRUE(is_dtor_triggered);
+  handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle == nullptr);
+#else
+  // GLIBC does not unload libraries with ref_count = 0 on pthread_exit
+  ASSERT_TRUE(is_dtor_triggered);
+  handle = dlopen("libtest_thread_local_dtor.so", RTLD_NOW | RTLD_NOLOAD);
+  ASSERT_TRUE(handle != nullptr) << dlerror();
+#endif
+}
+
 TEST(dlfcn, RTLD_macros) {
 #if !defined(RTLD_LOCAL)
 #error no RTLD_LOCAL
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 33dbfd9..6b20094 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -90,7 +90,6 @@
 }  // namespace testing
 
 using testing::internal::GTestColor;
-using testing::internal::COLOR_DEFAULT;
 using testing::internal::COLOR_RED;
 using testing::internal::COLOR_GREEN;
 using testing::internal::COLOR_YELLOW;
@@ -274,8 +273,7 @@
 }
 
 static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
-  std::vector<const char*> args;
-  for (int i = 0; i < argc; ++i) args.push_back(argv[i]);
+  std::vector<const char*> args(argv, argv + argc);
   args.push_back("--gtest_list_tests");
   args.push_back(nullptr);
 
@@ -543,7 +541,7 @@
                                 const std::vector<TestCase>& testcase_list,
                                 time_t epoch_iteration_start_time,
                                 int64_t elapsed_time_ns) {
-  FILE* fp = fopen(xml_output_filename.c_str(), "w");
+  FILE* fp = fopen(xml_output_filename.c_str(), "we");
   if (fp == NULL) {
     fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
     exit(1);
@@ -1185,10 +1183,7 @@
   g_argc = argc;
   g_argv = argv;
   g_envp = envp;
-  std::vector<char*> arg_list;
-  for (int i = 0; i < argc; ++i) {
-    arg_list.push_back(argv[i]);
-  }
+  std::vector<char*> arg_list(argv, argv + argc);
 
   IsolationTestOptions options;
   if (PickOptions(arg_list, options) == false) {
diff --git a/tests/headers/posix/Android.bp b/tests/headers/posix/Android.bp
index 682627f..8f3a2f2 100644
--- a/tests/headers/posix/Android.bp
+++ b/tests/headers/posix/Android.bp
@@ -18,11 +18,11 @@
     name: "libbionic_tests_headers_posix",
     srcs: ["*.c"],
     cflags: [
-      "-Wno-absolute-value", // broken clang diagnostic that doesn't understand <tgmath.h>
-      "-Wno-deprecated",
-      "-Werror",
-      "-D_POSIX_C_SOURCE=200809L",
-      "-D_XOPEN_SOURCE=700",
+        "-Wno-absolute-value", // broken clang diagnostic that doesn't understand <tgmath.h>
+        "-Wno-deprecated",
+        "-Werror",
+        "-D_POSIX_C_SOURCE=200809L",
+        "-D_XOPEN_SOURCE=700",
     ],
     host_supported: true,
     target: {
diff --git a/tests/headers/posix/pthread_h.c b/tests/headers/posix/pthread_h.c
index 4fa5b9d..4be822c 100644
--- a/tests/headers/posix/pthread_h.c
+++ b/tests/headers/posix/pthread_h.c
@@ -57,9 +57,9 @@
 
   MACRO(PTHREAD_ONCE_INIT);
 
-#if !defined(__BIONIC__) // No robust mutexes on Android.
   MACRO(PTHREAD_PRIO_INHERIT);
   MACRO(PTHREAD_PRIO_NONE);
+#if !defined(__BIONIC__)
   MACRO(PTHREAD_PRIO_PROTECT);
 #endif
 
@@ -158,8 +158,8 @@
   FUNCTION(pthread_mutexattr_destroy, int (*f)(pthread_mutexattr_t*));
 #if !defined(__BIONIC__) // No robust mutexes on Android.
   FUNCTION(pthread_mutexattr_getprioceiling, int (*f)(const pthread_mutexattr_t*, int*));
-  FUNCTION(pthread_mutexattr_getprotocol, int (*f)(const pthread_mutexattr_t*, int*));
 #endif
+  FUNCTION(pthread_mutexattr_getprotocol, int (*f)(const pthread_mutexattr_t*, int*));
   FUNCTION(pthread_mutexattr_getpshared, int (*f)(const pthread_mutexattr_t*, int*));
 #if !defined(__BIONIC__) // No robust mutexes on Android.
   FUNCTION(pthread_mutexattr_getrobust, int (*f)(const pthread_mutexattr_t*, int*));
@@ -168,8 +168,8 @@
   FUNCTION(pthread_mutexattr_init, int (*f)(pthread_mutexattr_t*));
 #if !defined(__BIONIC__) // No robust mutexes on Android.
   FUNCTION(pthread_mutexattr_setprioceiling, int (*f)(pthread_mutexattr_t*, int));
-  FUNCTION(pthread_mutexattr_setprotocol, int (*f)(pthread_mutexattr_t*, int));
 #endif
+  FUNCTION(pthread_mutexattr_setprotocol, int (*f)(pthread_mutexattr_t*, int));
   FUNCTION(pthread_mutexattr_setpshared, int (*f)(pthread_mutexattr_t*, int));
 #if !defined(__BIONIC__) // No robust mutexes on Android.
   FUNCTION(pthread_mutexattr_setrobust, int (*f)(pthread_mutexattr_t*, int));
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index e45eb6e..3afda67 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -80,7 +80,7 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlext_test_library.cpp"],
     ldflags: ["-Wl,-z,norelro"],
-    shared_libs = ["libtest_simple"],
+    shared_libs: ["libtest_simple"],
 }
 
 // -----------------------------------------------------------------------------
@@ -123,7 +123,6 @@
     relative_install_path: "bionic-loader-test-libs/public_namespace_libs",
 }
 
-
 // -----------------------------------------------------------------------------
 // Library used by dlext indirect unload on the namespace boundary tests
 //
@@ -259,6 +258,58 @@
 }
 
 // -----------------------------------------------------------------------------
+// Build test helper libraries for linker namespaces for allow all shared libs
+//
+// This set of libraries is used to verify linker namespaces for allow all
+// shared libs.
+//
+// Test cases
+// 1. Check that namespace a exposes libnstest_ns_a_public1 to
+//    namespace b while keeping libnstest_ns_a_public1_internal as an
+//    internal lib.
+// 2. Check that namespace b exposes all libraries to namespace a.
+//
+// Dependency tree (visibility)
+// libnstest_ns_b_public2.so  (ns:b)
+// +-> libnstest_ns_a_public1.so  (ns:a)
+//     +-> libnstest_ns_a_public2_internal.so  (ns:a)
+//     +-> libnstest_ns_b_public3.so  (ns:b)
+//
+// -----------------------------------------------------------------------------
+cc_test_library {
+    name: "libnstest_ns_a_public1",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["libnstest_ns_a_public1.cpp"],
+    relative_install_path: "bionic-loader-test-libs/ns_a",
+    shared_libs: [
+        "libnstest_ns_a_public1_internal",
+        "libnstest_ns_b_public3",
+    ],
+}
+
+cc_test_library {
+    name: "libnstest_ns_a_public1_internal",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["libnstest_ns_a_public1_internal.cpp"],
+    relative_install_path: "bionic-loader-test-libs/ns_a",
+}
+
+cc_test_library {
+    name: "libnstest_ns_b_public2",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["libnstest_ns_b_public2.cpp"],
+    relative_install_path: "bionic-loader-test-libs/ns_b",
+    shared_libs: ["libnstest_ns_a_public1"],
+}
+
+cc_test_library {
+    name: "libnstest_ns_b_public3",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["libnstest_ns_b_public3.cpp"],
+    relative_install_path: "bionic-loader-test-libs/ns_b",
+}
+
+// -----------------------------------------------------------------------------
 // Build DT_RUNPATH test helper libraries
 // -----------------------------------------------------------------------------
 // include $(LOCAL_PATH)/Android.build.dt_runpath.mk
@@ -355,7 +406,6 @@
 // +-> libtest_relo_check_dt_needed_order_2.so
 // -----------------------------------------------------------------------------
 
-
 cc_test_library {
     name: "libtest_relo_check_dt_needed_order",
     defaults: ["bionic_testlib_defaults"],
@@ -405,7 +455,7 @@
     name: "libtest_ifunc_variable",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["dlopen_testlib_ifunc_variable.cpp"],
-    shared_libs: [ "libtest_ifunc_variable_impl" ],
+    shared_libs: ["libtest_ifunc_variable_impl"],
 
     arch: {
         mips: {
@@ -508,7 +558,6 @@
     },
 }
 
-
 // -----------------------------------------------------------------------------
 // Library with weak function
 // -----------------------------------------------------------------------------
@@ -636,6 +685,15 @@
 }
 
 // -----------------------------------------------------------------------------
+// Library with non-trivial thread_local variable to test dlclose()
+// -----------------------------------------------------------------------------
+cc_test_library {
+    name: "libtest_thread_local_dtor",
+    defaults: ["bionic_testlib_defaults"],
+    srcs: ["thread_local_dtor.cpp"],
+}
+
+// -----------------------------------------------------------------------------
 // Tool to use to align the shared libraries in a zip file.
 // -----------------------------------------------------------------------------
 cc_binary_host {
diff --git a/tests/libs/libnstest_ns_a_public1.cpp b/tests/libs/libnstest_ns_a_public1.cpp
new file mode 100644
index 0000000..c095e60
--- /dev/null
+++ b/tests/libs/libnstest_ns_a_public1.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+static const char ns_a_public1_string[] = "libnstest_ns_a_public1.so";
+
+extern "C" const char* get_ns_a_public1_string() {
+  return ns_a_public1_string;
+}
+
+
+extern "C" const char *get_ns_a_public1_internal_string();
+
+extern "C" const char *delegate_get_ns_a_public1_internal_string() {
+  return get_ns_a_public1_internal_string();
+}
+
+
+extern "C" const char *get_ns_b_public3_string();
+
+extern "C" const char *delegate_get_ns_b_public3_string() {
+  return get_ns_b_public3_string();
+}
diff --git a/tests/libs/libnstest_ns_a_public1_internal.cpp b/tests/libs/libnstest_ns_a_public1_internal.cpp
new file mode 100644
index 0000000..6529936
--- /dev/null
+++ b/tests/libs/libnstest_ns_a_public1_internal.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+static const char ns_a_public1_internal_string[] = "libnstest_ns_a_public1_internal.so";
+
+extern "C" const char* get_ns_a_public1_internal_string() {
+  return ns_a_public1_internal_string;
+}
diff --git a/tests/libs/libnstest_ns_b_public2.cpp b/tests/libs/libnstest_ns_b_public2.cpp
new file mode 100644
index 0000000..6251a8d
--- /dev/null
+++ b/tests/libs/libnstest_ns_b_public2.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+static const char ns_b_public2_string[] = "libnstest_ns_b_public2.so";
+
+extern "C" const char* get_ns_b_public2_string() {
+  return ns_b_public2_string;
+}
+
+
+extern "C" const char* get_ns_a_public1_string();
+
+extern "C" const char* delegate_get_ns_a_public1_string() {
+  return get_ns_a_public1_string();
+}
diff --git a/tests/libs/libnstest_ns_b_public3.cpp b/tests/libs/libnstest_ns_b_public3.cpp
new file mode 100644
index 0000000..b332445
--- /dev/null
+++ b/tests/libs/libnstest_ns_b_public3.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+static const char ns_b_public3_string[] = "libnstest_ns_b_public3.so";
+
+extern "C" const char* get_ns_b_public3_string() {
+  return ns_b_public3_string;
+}
diff --git a/libc/bionic/sigsuspend.cpp b/tests/libs/thread_local_dtor.cpp
similarity index 80%
rename from libc/bionic/sigsuspend.cpp
rename to tests/libs/thread_local_dtor.cpp
index fb846b8..cefff7a 100644
--- a/libc/bionic/sigsuspend.cpp
+++ b/tests/libs/thread_local_dtor.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,13 +26,20 @@
  * SUCH DAMAGE.
  */
 
-#include <signal.h>
+namespace {
 
-#include "private/kernel_sigset_t.h"
+class TestClass {
+ public:
+  TestClass(bool* flag) : flag_(flag) {}
+  ~TestClass() {
+    *flag_ = true;
+  }
+ private:
+  bool* flag_;
+};
 
-extern "C" int __rt_sigsuspend(const kernel_sigset_t*, size_t);
+};  // namespace
 
-int sigsuspend(const sigset_t* bionic_set) {
-  kernel_sigset_t set(bionic_set);
-  return __rt_sigsuspend(&set, sizeof(set));
+extern "C" void init_thread_local_variable(bool* flag) {
+  thread_local TestClass test(flag);
 }
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 183312d..5e55415 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -33,7 +33,9 @@
 #include <atomic>
 #include <vector>
 
+#include <android-base/parseint.h>
 #include <android-base/scopeguard.h>
+#include <android-base/strings.h>
 
 #include "private/bionic_constants.h"
 #include "private/bionic_macros.h"
@@ -354,9 +356,9 @@
 }
 
 static void* SignalHandlerFn(void* arg) {
-  sigset_t wait_set;
-  sigfillset(&wait_set);
-  return reinterpret_cast<void*>(sigwait(&wait_set, reinterpret_cast<int*>(arg)));
+  sigset64_t wait_set;
+  sigfillset64(&wait_set);
+  return reinterpret_cast<void*>(sigwait64(&wait_set, reinterpret_cast<int*>(arg)));
 }
 
 TEST(pthread, pthread_sigmask) {
@@ -400,6 +402,47 @@
   ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &original_set, NULL));
 }
 
+TEST(pthread, pthread_sigmask64_SIGTRMIN) {
+  // Check that SIGRTMIN isn't blocked.
+  sigset64_t original_set;
+  sigemptyset64(&original_set);
+  ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, NULL, &original_set));
+  ASSERT_FALSE(sigismember64(&original_set, SIGRTMIN));
+
+  // Block SIGRTMIN.
+  sigset64_t set;
+  sigemptyset64(&set);
+  sigaddset64(&set, SIGRTMIN);
+  ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &set, NULL));
+
+  // Check that SIGRTMIN is blocked.
+  sigset64_t final_set;
+  sigemptyset64(&final_set);
+  ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, NULL, &final_set));
+  ASSERT_TRUE(sigismember64(&final_set, SIGRTMIN));
+  // ...and that sigprocmask64 agrees with pthread_sigmask64.
+  sigemptyset64(&final_set);
+  ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, NULL, &final_set));
+  ASSERT_TRUE(sigismember64(&final_set, SIGRTMIN));
+
+  // Spawn a thread that calls sigwait64 and tells us what it received.
+  pthread_t signal_thread;
+  int received_signal = -1;
+  ASSERT_EQ(0, pthread_create(&signal_thread, NULL, SignalHandlerFn, &received_signal));
+
+  // Send that thread SIGRTMIN.
+  pthread_kill(signal_thread, SIGRTMIN);
+
+  // See what it got.
+  void* join_result;
+  ASSERT_EQ(0, pthread_join(signal_thread, &join_result));
+  ASSERT_EQ(SIGRTMIN, received_signal);
+  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(join_result));
+
+  // Restore the original signal mask.
+  ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &original_set, NULL));
+}
+
 static void test_pthread_setname_np__pthread_getname_np(pthread_t t) {
   ASSERT_EQ(0, pthread_setname_np(t, "short"));
   char name[32];
@@ -1376,18 +1419,23 @@
   EXPECT_EQ(stack_size, stack_size2);
 
 #if defined(__BIONIC__)
-  // What does /proc/self/maps' [stack] line say?
+  // Find stack in /proc/self/maps using a pointer to the stack.
+  //
+  // We do not use "[stack]" label because in native-bridge environment it is not
+  // guaranteed to point to the right stack. A native bridge implementation may
+  // keep separate stack for the guest code.
   void* maps_stack_hi = NULL;
   std::vector<map_record> maps;
   ASSERT_TRUE(Maps::parse_maps(&maps));
+  uintptr_t stack_address = reinterpret_cast<uintptr_t>(&maps_stack_hi);
   for (const auto& map : maps) {
-    if (map.pathname == "[stack]") {
+    if (map.addr_start <= stack_address && map.addr_end > stack_address){
       maps_stack_hi = reinterpret_cast<void*>(map.addr_end);
       break;
     }
   }
 
-  // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
+  // The high address of the /proc/self/maps stack region should equal stack_base + stack_size.
   // Remember that the stack grows down (and is mapped in on demand), so the low address of the
   // region isn't very interesting.
   EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);
@@ -1631,11 +1679,27 @@
   ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
 }
 
+TEST(pthread, pthread_mutexattr_protocol) {
+  pthread_mutexattr_t attr;
+  ASSERT_EQ(0, pthread_mutexattr_init(&attr));
+
+  int protocol;
+  ASSERT_EQ(0, pthread_mutexattr_getprotocol(&attr, &protocol));
+  ASSERT_EQ(PTHREAD_PRIO_NONE, protocol);
+  for (size_t repeat = 0; repeat < 2; ++repeat) {
+    for (int set_protocol : {PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT}) {
+      ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, set_protocol));
+      ASSERT_EQ(0, pthread_mutexattr_getprotocol(&attr, &protocol));
+      ASSERT_EQ(protocol, set_protocol);
+    }
+  }
+}
+
 struct PthreadMutex {
   pthread_mutex_t lock;
 
-  explicit PthreadMutex(int mutex_type) {
-    init(mutex_type);
+  explicit PthreadMutex(int mutex_type, int protocol = PTHREAD_PRIO_NONE) {
+    init(mutex_type, protocol);
   }
 
   ~PthreadMutex() {
@@ -1643,23 +1707,25 @@
   }
 
  private:
-  void init(int mutex_type) {
+  void init(int mutex_type, int protocol) {
     pthread_mutexattr_t attr;
     ASSERT_EQ(0, pthread_mutexattr_init(&attr));
     ASSERT_EQ(0, pthread_mutexattr_settype(&attr, mutex_type));
+    ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, protocol));
     ASSERT_EQ(0, pthread_mutex_init(&lock, &attr));
     ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
   }
 
   void destroy() {
     ASSERT_EQ(0, pthread_mutex_destroy(&lock));
+    ASSERT_EQ(EBUSY, pthread_mutex_destroy(&lock));
   }
 
   DISALLOW_COPY_AND_ASSIGN(PthreadMutex);
 };
 
-TEST(pthread, pthread_mutex_lock_NORMAL) {
-  PthreadMutex m(PTHREAD_MUTEX_NORMAL);
+static void TestPthreadMutexLockNormal(int protocol) {
+  PthreadMutex m(PTHREAD_MUTEX_NORMAL, protocol);
 
   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
@@ -1668,20 +1734,24 @@
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
 }
 
-TEST(pthread, pthread_mutex_lock_ERRORCHECK) {
-  PthreadMutex m(PTHREAD_MUTEX_ERRORCHECK);
+static void TestPthreadMutexLockErrorCheck(int protocol) {
+  PthreadMutex m(PTHREAD_MUTEX_ERRORCHECK, protocol);
 
   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
   ASSERT_EQ(EDEADLK, pthread_mutex_lock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_trylock(&m.lock));
-  ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock));
+  if (protocol == PTHREAD_PRIO_NONE) {
+    ASSERT_EQ(EBUSY, pthread_mutex_trylock(&m.lock));
+  } else {
+    ASSERT_EQ(EDEADLK, pthread_mutex_trylock(&m.lock));
+  }
   ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
   ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock));
 }
 
-TEST(pthread, pthread_mutex_lock_RECURSIVE) {
-  PthreadMutex m(PTHREAD_MUTEX_RECURSIVE);
+static void TestPthreadMutexLockRecursive(int protocol) {
+  PthreadMutex m(PTHREAD_MUTEX_RECURSIVE, protocol);
 
   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
   ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
@@ -1694,6 +1764,55 @@
   ASSERT_EQ(EPERM, pthread_mutex_unlock(&m.lock));
 }
 
+TEST(pthread, pthread_mutex_lock_NORMAL) {
+  TestPthreadMutexLockNormal(PTHREAD_PRIO_NONE);
+}
+
+TEST(pthread, pthread_mutex_lock_ERRORCHECK) {
+  TestPthreadMutexLockErrorCheck(PTHREAD_PRIO_NONE);
+}
+
+TEST(pthread, pthread_mutex_lock_RECURSIVE) {
+  TestPthreadMutexLockRecursive(PTHREAD_PRIO_NONE);
+}
+
+TEST(pthread, pthread_mutex_lock_pi) {
+  TestPthreadMutexLockNormal(PTHREAD_PRIO_INHERIT);
+  TestPthreadMutexLockErrorCheck(PTHREAD_PRIO_INHERIT);
+  TestPthreadMutexLockRecursive(PTHREAD_PRIO_INHERIT);
+}
+
+TEST(pthread, pthread_mutex_pi_count_limit) {
+#if defined(__BIONIC__) && !defined(__LP64__)
+  // Bionic only supports 65536 pi mutexes in 32-bit programs.
+  pthread_mutexattr_t attr;
+  ASSERT_EQ(0, pthread_mutexattr_init(&attr));
+  ASSERT_EQ(0, pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT));
+  std::vector<pthread_mutex_t> mutexes(65536);
+  // Test if we can use 65536 pi mutexes at the same time.
+  // Run 2 times to check if freed pi mutexes can be recycled.
+  for (int repeat = 0; repeat < 2; ++repeat) {
+    for (auto& m : mutexes) {
+      ASSERT_EQ(0, pthread_mutex_init(&m, &attr));
+    }
+    pthread_mutex_t m;
+    ASSERT_EQ(ENOMEM, pthread_mutex_init(&m, &attr));
+    for (auto& m : mutexes) {
+      ASSERT_EQ(0, pthread_mutex_lock(&m));
+    }
+    for (auto& m : mutexes) {
+      ASSERT_EQ(0, pthread_mutex_unlock(&m));
+    }
+    for (auto& m : mutexes) {
+      ASSERT_EQ(0, pthread_mutex_destroy(&m));
+    }
+  }
+  ASSERT_EQ(0, pthread_mutexattr_destroy(&attr));
+#else
+  GTEST_LOG_(INFO) << "This test does nothing as pi mutex count isn't limited.\n";
+#endif
+}
+
 TEST(pthread, pthread_mutex_init_same_as_static_initializers) {
   pthread_mutex_t lock_normal = PTHREAD_MUTEX_INITIALIZER;
   PthreadMutex m1(PTHREAD_MUTEX_NORMAL);
@@ -1710,6 +1829,7 @@
   ASSERT_EQ(0, memcmp(&lock_recursive, &m3.lock, sizeof(pthread_mutex_t)));
   ASSERT_EQ(0, pthread_mutex_destroy(&lock_recursive));
 }
+
 class MutexWakeupHelper {
  private:
   PthreadMutex m;
@@ -1773,6 +1893,99 @@
   helper.test();
 }
 
+static int GetThreadPriority(pid_t tid) {
+  // sched_getparam() returns the static priority of a thread, which can't reflect a thread's
+  // priority after priority inheritance. So read /proc/<pid>/stat to get the dynamic priority.
+  std::string filename = android::base::StringPrintf("/proc/%d/stat", tid);
+  std::string content;
+  int result = INT_MAX;
+  if (!android::base::ReadFileToString(filename, &content)) {
+    return result;
+  }
+  std::vector<std::string> strs = android::base::Split(content, " ");
+  if (strs.size() < 18) {
+    return result;
+  }
+  if (!android::base::ParseInt(strs[17], &result)) {
+    return INT_MAX;
+  }
+  return result;
+}
+
+class PIMutexWakeupHelper {
+private:
+  PthreadMutex m;
+  int protocol;
+  enum Progress {
+    LOCK_INITIALIZED,
+    LOCK_CHILD_READY,
+    LOCK_WAITING,
+    LOCK_RELEASED,
+  };
+  std::atomic<Progress> progress;
+  std::atomic<pid_t> main_tid;
+  std::atomic<pid_t> child_tid;
+  PthreadMutex start_thread_m;
+
+  static void thread_fn(PIMutexWakeupHelper* helper) {
+    helper->child_tid = gettid();
+    ASSERT_EQ(LOCK_INITIALIZED, helper->progress);
+    ASSERT_EQ(0, setpriority(PRIO_PROCESS, gettid(), 1));
+    ASSERT_EQ(21, GetThreadPriority(gettid()));
+    ASSERT_EQ(0, pthread_mutex_lock(&helper->m.lock));
+    helper->progress = LOCK_CHILD_READY;
+    ASSERT_EQ(0, pthread_mutex_lock(&helper->start_thread_m.lock));
+
+    ASSERT_EQ(0, pthread_mutex_unlock(&helper->start_thread_m.lock));
+    WaitUntilThreadSleep(helper->main_tid);
+    ASSERT_EQ(LOCK_WAITING, helper->progress);
+
+    if (helper->protocol == PTHREAD_PRIO_INHERIT) {
+      ASSERT_EQ(20, GetThreadPriority(gettid()));
+    } else {
+      ASSERT_EQ(21, GetThreadPriority(gettid()));
+    }
+    helper->progress = LOCK_RELEASED;
+    ASSERT_EQ(0, pthread_mutex_unlock(&helper->m.lock));
+  }
+
+public:
+  explicit PIMutexWakeupHelper(int mutex_type, int protocol)
+      : m(mutex_type, protocol), protocol(protocol), start_thread_m(PTHREAD_MUTEX_NORMAL) {
+  }
+
+  void test() {
+    ASSERT_EQ(0, pthread_mutex_lock(&start_thread_m.lock));
+    main_tid = gettid();
+    ASSERT_EQ(20, GetThreadPriority(main_tid));
+    progress = LOCK_INITIALIZED;
+    child_tid = 0;
+
+    pthread_t thread;
+    ASSERT_EQ(0, pthread_create(&thread, NULL,
+              reinterpret_cast<void* (*)(void*)>(PIMutexWakeupHelper::thread_fn), this));
+
+    WaitUntilThreadSleep(child_tid);
+    ASSERT_EQ(LOCK_CHILD_READY, progress);
+    ASSERT_EQ(0, pthread_mutex_unlock(&start_thread_m.lock));
+    progress = LOCK_WAITING;
+    ASSERT_EQ(0, pthread_mutex_lock(&m.lock));
+
+    ASSERT_EQ(LOCK_RELEASED, progress);
+    ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
+    ASSERT_EQ(0, pthread_join(thread, nullptr));
+  }
+};
+
+TEST(pthread, pthread_mutex_pi_wakeup) {
+  for (int type : {PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK}) {
+    for (int protocol : {PTHREAD_PRIO_INHERIT}) {
+      PIMutexWakeupHelper helper(type, protocol);
+      helper.test();
+    }
+  }
+}
+
 TEST(pthread, pthread_mutex_owner_tid_limit) {
 #if defined(__BIONIC__) && !defined(__LP64__)
   FILE* fp = fopen("/proc/sys/kernel/pid_max", "r");
@@ -1816,6 +2029,30 @@
   ASSERT_EQ(0, pthread_mutex_destroy(&m));
 }
 
+TEST(pthread, pthread_mutex_timedlock_pi) {
+  PthreadMutex m(PTHREAD_MUTEX_NORMAL, PTHREAD_PRIO_INHERIT);
+  timespec ts;
+  clock_gettime(CLOCK_REALTIME, &ts);
+  ts.tv_sec += 1;
+  ASSERT_EQ(0, pthread_mutex_timedlock(&m.lock, &ts));
+
+  auto ThreadFn = [](void* arg) -> void* {
+    PthreadMutex& m = *static_cast<PthreadMutex*>(arg);
+    timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+    ts.tv_sec += 1;
+    intptr_t result = pthread_mutex_timedlock(&m.lock, &ts);
+    return reinterpret_cast<void*>(result);
+  };
+
+  pthread_t thread;
+  ASSERT_EQ(0, pthread_create(&thread, NULL, ThreadFn, &m));
+  void* result;
+  ASSERT_EQ(0, pthread_join(thread, &result));
+  ASSERT_EQ(ETIMEDOUT, reinterpret_cast<intptr_t>(result));
+  ASSERT_EQ(0, pthread_mutex_unlock(&m.lock));
+}
+
 class StrictAlignmentAllocator {
  public:
   void* allocate(size_t size, size_t alignment) {
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index bb01601..4f5e60c 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -19,6 +19,8 @@
 #include <setjmp.h>
 #include <stdlib.h>
 
+#include "ScopedSignalHandler.h"
+
 TEST(setjmp, setjmp_smoke) {
   int value;
   jmp_buf jb;
@@ -63,61 +65,59 @@
   }
 }
 
-// Two distinct signal sets, pipu
+// Two distinct signal sets.
 struct SigSets {
   SigSets() : one(MakeSigSet(0)), two(MakeSigSet(1)) {
   }
 
-  static sigset_t MakeSigSet(int offset) {
-    sigset_t ss;
-    sigemptyset(&ss);
-    sigaddset(&ss, SIGUSR1 + offset);
-#if defined(__LP64__)
-    // For arm and x86, sigset_t was too small for the RT signals.
-    // For mips, sigset_t was large enough but jmp_buf wasn't.
-    sigaddset(&ss, SIGRTMIN + offset);
-#endif
+  static sigset64_t MakeSigSet(int offset) {
+    sigset64_t ss;
+    sigemptyset64(&ss);
+    sigaddset64(&ss, SIGUSR1 + offset);
+    sigaddset64(&ss, SIGRTMIN + offset);
     return ss;
   }
 
-  sigset_t one;
-  sigset_t two;
-  sigset_t original;
+  sigset64_t one;
+  sigset64_t two;
 };
 
-void AssertSigmaskEquals(const sigset_t& expected) {
-  sigset_t actual;
-  sigprocmask(0 /* ignored */, NULL, &actual);
-  size_t end = sizeof(sigset_t) * 8;
+void AssertSigmaskEquals(const sigset64_t& expected) {
+  sigset64_t actual;
+  sigprocmask64(SIG_SETMASK, NULL, &actual);
+  size_t end = sizeof(expected) * 8;
   for (size_t i = 1; i <= end; ++i) {
-    EXPECT_EQ(sigismember(&expected, i), sigismember(&actual, i)) << i;
+    EXPECT_EQ(sigismember64(&expected, i), sigismember64(&actual, i)) << i;
   }
 }
 
 TEST(setjmp, _setjmp_signal_mask) {
+  SignalMaskRestorer smr;
+
   // _setjmp/_longjmp do not save/restore the signal mask.
   SigSets ss;
-  sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+  sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
   jmp_buf jb;
   if (_setjmp(jb) == 0) {
-    sigprocmask(SIG_SETMASK, &ss.two, NULL);
+    sigprocmask64(SIG_SETMASK, &ss.two, NULL);
     _longjmp(jb, 1);
     FAIL(); // Unreachable.
   } else {
     AssertSigmaskEquals(ss.two);
   }
-  sigprocmask(SIG_SETMASK, &ss.original, NULL);
 }
 
 TEST(setjmp, setjmp_signal_mask) {
+  SignalMaskRestorer smr;
+
   // setjmp/longjmp do save/restore the signal mask on bionic, but not on glibc.
   // This is a BSD versus System V historical accident. POSIX leaves the
   // behavior unspecified, so any code that cares needs to use sigsetjmp.
   SigSets ss;
-  sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+  sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
   jmp_buf jb;
   if (setjmp(jb) == 0) {
-    sigprocmask(SIG_SETMASK, &ss.two, NULL);
+    sigprocmask64(SIG_SETMASK, &ss.two, NULL);
     longjmp(jb, 1);
     FAIL(); // Unreachable.
   } else {
@@ -129,37 +129,38 @@
     AssertSigmaskEquals(ss.two);
 #endif
   }
-  sigprocmask(SIG_SETMASK, &ss.original, NULL);
 }
 
 TEST(setjmp, sigsetjmp_0_signal_mask) {
+  SignalMaskRestorer smr;
+
   // sigsetjmp(0)/siglongjmp do not save/restore the signal mask.
   SigSets ss;
-  sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+  sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
   sigjmp_buf sjb;
   if (sigsetjmp(sjb, 0) == 0) {
-    sigprocmask(SIG_SETMASK, &ss.two, NULL);
+    sigprocmask64(SIG_SETMASK, &ss.two, NULL);
     siglongjmp(sjb, 1);
     FAIL(); // Unreachable.
   } else {
     AssertSigmaskEquals(ss.two);
   }
-  sigprocmask(SIG_SETMASK, &ss.original, NULL);
 }
 
 TEST(setjmp, sigsetjmp_1_signal_mask) {
+  SignalMaskRestorer smr;
+
   // sigsetjmp(1)/siglongjmp does save/restore the signal mask.
   SigSets ss;
-  sigprocmask(SIG_SETMASK, &ss.one, &ss.original);
+  sigprocmask64(SIG_SETMASK, &ss.one, nullptr);
   sigjmp_buf sjb;
   if (sigsetjmp(sjb, 1) == 0) {
-    sigprocmask(SIG_SETMASK, &ss.two, NULL);
+    sigprocmask64(SIG_SETMASK, &ss.two, NULL);
     siglongjmp(sjb, 1);
     FAIL(); // Unreachable.
   } else {
     AssertSigmaskEquals(ss.one);
   }
-  sigprocmask(SIG_SETMASK, &ss.original, NULL);
 }
 
 #if defined(__aarch64__)
@@ -218,7 +219,7 @@
 #elif defined(__aarch64__)
 #define __JB_SIGFLAG 0
 #elif defined(__i386__)
-#define __JB_SIGFLAG 7
+#define __JB_SIGFLAG 8
 #elif defined(__x86_64)
 #define __JB_SIGFLAG 8
 #elif defined(__mips__) && defined(__LP64__)
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 207c156..87a918f 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -20,57 +20,45 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <thread>
+
 #include <gtest/gtest.h>
 
 #include "ScopedSignalHandler.h"
 
-static size_t SIGNAL_MIN() {
+static int SIGNAL_MIN() {
   return 1; // Signals start at 1 (SIGHUP), not 0.
 }
 
-static size_t SIGNAL_MAX() {
-  size_t result = SIGRTMAX;
-
-#if defined(__BIONIC__) && !defined(__mips__) && !defined(__LP64__)
-  // 32-bit bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64.
-  // This means you can't refer to any of the real-time signals.
-  // See http://b/3038348 and http://b/5828899.
-  result = 32;
-#else
-  // Otherwise, C libraries should be perfectly capable of using their largest signal.
-  if (sizeof(sigset_t) * 8 < static_cast<size_t>(SIGRTMAX)) {
-    abort();
-  }
-#endif
-
-  return result;
+template <typename SigSetT>
+static int SIGNAL_MAX(SigSetT* set) {
+  return sizeof(*set) * 8;
 }
 
-template <typename Fn>
-static void TestSigSet1(Fn fn) {
-  // NULL sigset_t*.
-  sigset_t* set_ptr = NULL;
+template <typename SigSetT>
+static void TestSigSet1(int (fn)(SigSetT*)) {
+  // NULL sigset_t*/sigset64_t*.
+  SigSetT* set_ptr = NULL;
   errno = 0;
   ASSERT_EQ(-1, fn(set_ptr));
   ASSERT_EQ(EINVAL, errno);
 
   // Non-NULL.
-  sigset_t set;
+  SigSetT set = {};
   errno = 0;
   ASSERT_EQ(0, fn(&set));
   ASSERT_EQ(0, errno);
 }
 
-template <typename Fn>
-static void TestSigSet2(Fn fn) {
-  // NULL sigset_t*.
-  sigset_t* set_ptr = NULL;
+template <typename SigSetT>
+static void TestSigSet2(int (fn)(SigSetT*, int)) {
+  // NULL sigset_t*/sigset64_t*.
+  SigSetT* set_ptr = NULL;
   errno = 0;
   ASSERT_EQ(-1, fn(set_ptr, SIGSEGV));
   ASSERT_EQ(EINVAL, errno);
 
-  sigset_t set;
-  sigemptyset(&set);
+  SigSetT set = {};
 
   // Bad signal number: too small.
   errno = 0;
@@ -79,37 +67,67 @@
 
   // Bad signal number: too high.
   errno = 0;
-  ASSERT_EQ(-1, fn(&set, SIGNAL_MAX() + 1));
+  ASSERT_EQ(-1, fn(&set, SIGNAL_MAX(&set) + 1));
   ASSERT_EQ(EINVAL, errno);
 
   // Good signal numbers, low and high ends of range.
   errno = 0;
   ASSERT_EQ(0, fn(&set, SIGNAL_MIN()));
   ASSERT_EQ(0, errno);
-  ASSERT_EQ(0, fn(&set, SIGNAL_MAX()));
+  ASSERT_EQ(0, fn(&set, SIGNAL_MAX(&set)));
   ASSERT_EQ(0, errno);
 }
 
-TEST(signal, sigismember_invalid) {
-  TestSigSet2(sigismember);
-}
-
 TEST(signal, sigaddset_invalid) {
   TestSigSet2(sigaddset);
 }
 
+TEST(signal, sigaddset64_invalid) {
+#if defined(__BIONIC__)
+  TestSigSet2(sigaddset64);
+#endif
+}
+
 TEST(signal, sigdelset_invalid) {
   TestSigSet2(sigdelset);
 }
 
+TEST(signal, sigdelset64_invalid) {
+#if defined(__BIONIC__)
+  TestSigSet2(sigdelset64);
+#endif
+}
+
 TEST(signal, sigemptyset_invalid) {
   TestSigSet1(sigemptyset);
 }
 
+TEST(signal, sigemptyset64_invalid) {
+#if defined(__BIONIC__)
+  TestSigSet1(sigemptyset64);
+#endif
+}
+
 TEST(signal, sigfillset_invalid) {
   TestSigSet1(sigfillset);
 }
 
+TEST(signal, sigfillset64_invalid) {
+#if defined(__BIONIC__)
+  TestSigSet1(sigfillset64);
+#endif
+}
+
+TEST(signal, sigismember_invalid) {
+  TestSigSet2(sigismember);
+}
+
+TEST(signal, sigismember64_invalid) {
+#if defined(__BIONIC__)
+  TestSigSet2(sigismember64);
+#endif
+}
+
 TEST(signal, raise_invalid) {
   errno = 0;
   ASSERT_EQ(-1, raise(-1));
@@ -129,12 +147,8 @@
   raise(SIGALRM);
 }
 
-static void HandleSIGALRM(int signal_number) {
-  ASSERT_EQ(SIGALRM, signal_number);
-}
-
-TEST(signal, sigwait) {
-  ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM);
+TEST(signal, sigwait_SIGALRM) {
+  ScopedSignalHandler ssh(SIGALRM, [](int sig) { ASSERT_EQ(SIGALRM, sig); });
 
   sigset_t wait_set;
   sigemptyset(&wait_set);
@@ -149,38 +163,57 @@
   ASSERT_EQ(SIGALRM, received_signal);
 }
 
-static int g_sigsuspend_test_helper_call_count = 0;
+TEST(signal, sigwait64_SIGRTMIN) {
+  ScopedSignalHandler ssh(SIGRTMIN, [](int sig) { ASSERT_EQ(SIGRTMIN, sig); });
 
-static void SigSuspendTestHelper(int) {
-  ++g_sigsuspend_test_helper_call_count;
+  sigset64_t wait_set;
+  sigemptyset64(&wait_set);
+  sigaddset64(&wait_set, SIGRTMIN);
+
+  pid_t pid = getpid();
+  std::thread thread([&pid]() {
+    usleep(5000);
+    kill(pid, 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) {
+  SignalMaskRestorer smr;
+
   // Block SIGALRM.
   sigset_t just_SIGALRM;
   sigemptyset(&just_SIGALRM);
   sigaddset(&just_SIGALRM, SIGALRM);
-  sigset_t original_set;
-  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
-  ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper);
+  ScopedSignalHandler ssh(SIGALRM, [](int) { ++g_sigsuspend_signal_handler_call_count; });
 
   // There should be no pending signals.
   sigset_t pending;
   sigemptyset(&pending);
   ASSERT_EQ(0, sigpending(&pending));
-  for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) {
+  for (int i = SIGNAL_MIN(); i <= SIGNAL_MAX(&pending); ++i) {
     EXPECT_FALSE(sigismember(&pending, i)) << i;
   }
 
   // Raise SIGALRM and check our signal handler wasn't called.
   raise(SIGALRM);
-  ASSERT_EQ(0, g_sigsuspend_test_helper_call_count);
+  ASSERT_EQ(0, g_sigsuspend_signal_handler_call_count);
 
   // We should now have a pending SIGALRM but nothing else.
   sigemptyset(&pending);
   ASSERT_EQ(0, sigpending(&pending));
-  for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) {
+  for (int i = SIGNAL_MIN(); i <= SIGNAL_MAX(&pending); ++i) {
     EXPECT_EQ((i == SIGALRM), sigismember(&pending, i));
   }
 
@@ -191,61 +224,108 @@
   ASSERT_EQ(-1, sigsuspend(&not_SIGALRM));
   ASSERT_EQ(EINTR, errno);
   // ...and check that we now receive our pending SIGALRM.
-  ASSERT_EQ(1, g_sigsuspend_test_helper_call_count);
-
-  // Restore the original set.
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
+  ASSERT_EQ(1, g_sigsuspend_signal_handler_call_count);
 }
 
-static void EmptySignalHandler(int) {}
-static void EmptySignalAction(int, siginfo_t*, void*) {}
+static int g_sigsuspend64_signal_handler_call_count = 0;
 
-TEST(signal, sigaction) {
+TEST(signal, sigsuspend64_sigpending64) {
+  SignalMaskRestorer smr;
+
+  // Block SIGRTMIN.
+  sigset64_t just_SIGRTMIN;
+  sigemptyset64(&just_SIGRTMIN);
+  sigaddset64(&just_SIGRTMIN, SIGRTMIN);
+  ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &just_SIGRTMIN, nullptr));
+
+  ScopedSignalHandler ssh(SIGRTMIN, [](int) { ++g_sigsuspend64_signal_handler_call_count; });
+
+  // There should be no pending signals.
+  sigset64_t pending;
+  sigemptyset64(&pending);
+  ASSERT_EQ(0, sigpending64(&pending));
+  for (int i = SIGNAL_MIN(); i <= SIGNAL_MAX(&pending); ++i) {
+    EXPECT_FALSE(sigismember64(&pending, i)) << i;
+  }
+
+  // Raise SIGRTMIN and check our signal handler wasn't called.
+  raise(SIGRTMIN);
+  ASSERT_EQ(0, g_sigsuspend64_signal_handler_call_count);
+
+  // We should now have a pending SIGRTMIN but nothing else.
+  sigemptyset64(&pending);
+  ASSERT_EQ(0, sigpending64(&pending));
+  for (int i = SIGNAL_MIN(); i <= SIGNAL_MAX(&pending); ++i) {
+    EXPECT_EQ((i == SIGRTMIN), sigismember64(&pending, i));
+  }
+
+  // Use sigsuspend64 to block everything except SIGRTMIN...
+  sigset64_t not_SIGRTMIN;
+  sigfillset64(&not_SIGRTMIN);
+  sigdelset64(&not_SIGRTMIN, SIGRTMIN);
+  ASSERT_EQ(-1, sigsuspend64(&not_SIGRTMIN));
+  ASSERT_EQ(EINTR, errno);
+  // ...and check that we now receive our pending SIGRTMIN.
+  ASSERT_EQ(1, g_sigsuspend64_signal_handler_call_count);
+}
+
+template <typename SigActionT, typename SigSetT>
+static void TestSigAction(int (sigaction_fn)(int, const SigActionT*, SigActionT*),
+                          int (sigaddset_fn)(SigSetT*, int),
+                          int sig) {
   // Both bionic and glibc set SA_RESTORER when talking to the kernel on arm,
   // arm64, x86, and x86-64. The version of glibc we're using also doesn't
   // define SA_RESTORER, but luckily it's the same value everywhere, and mips
   // doesn't use the bit for anything.
   static const unsigned sa_restorer = 0x4000000;
 
-  // See what's currently set for SIGALRM.
-  struct sigaction original_sa;
-  memset(&original_sa, 0, sizeof(original_sa));
-  ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa));
+  // See what's currently set for this signal.
+  SigActionT original_sa = {};
+  ASSERT_EQ(0, sigaction_fn(sig, NULL, &original_sa));
   ASSERT_TRUE(original_sa.sa_handler == NULL);
   ASSERT_TRUE(original_sa.sa_sigaction == NULL);
   ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer);
 
   // Set a traditional sa_handler signal handler.
-  struct sigaction sa;
-  memset(&sa, 0, sizeof(sa));
-  sigaddset(&sa.sa_mask, SIGALRM);
+  auto no_op_signal_handler = [](int) {};
+  SigActionT sa = {};
+  sigaddset_fn(&sa.sa_mask, sig);
   sa.sa_flags = SA_ONSTACK;
-  sa.sa_handler = EmptySignalHandler;
-  ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
+  sa.sa_handler = no_op_signal_handler;
+  ASSERT_EQ(0, sigaction_fn(sig, &sa, NULL));
 
   // Check that we can read it back.
-  memset(&sa, 0, sizeof(sa));
-  ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
-  ASSERT_TRUE(sa.sa_handler == EmptySignalHandler);
+  sa = {};
+  ASSERT_EQ(0, sigaction_fn(sig, NULL, &sa));
+  ASSERT_TRUE(sa.sa_handler == no_op_signal_handler);
   ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
   ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer);
 
   // Set a new-style sa_sigaction signal handler.
-  memset(&sa, 0, sizeof(sa));
-  sigaddset(&sa.sa_mask, SIGALRM);
+  auto no_op_sigaction = [](int, siginfo_t*, void*) {};
+  sa = {};
+  sigaddset_fn(&sa.sa_mask, sig);
   sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
-  sa.sa_sigaction = EmptySignalAction;
-  ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
+  sa.sa_sigaction = no_op_sigaction;
+  ASSERT_EQ(0, sigaction_fn(sig, &sa, NULL));
 
   // Check that we can read it back.
-  memset(&sa, 0, sizeof(sa));
-  ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
-  ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction);
+  sa = {};
+  ASSERT_EQ(0, sigaction_fn(sig, NULL, &sa));
+  ASSERT_TRUE(sa.sa_sigaction == no_op_sigaction);
   ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
   ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer);
 
   // Put everything back how it was.
-  ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL));
+  ASSERT_EQ(0, sigaction_fn(sig, &original_sa, NULL));
+}
+
+TEST(signal, sigaction) {
+  TestSigAction(sigaction, sigaddset, SIGALRM);
+}
+
+TEST(signal, sigaction64_SIGRTMIN) {
+  TestSigAction(sigaction64, sigaddset64, SIGRTMIN);
 }
 
 TEST(signal, sys_signame) {
@@ -301,12 +381,13 @@
 }
 
 TEST(signal, sigwaitinfo) {
+  SignalMaskRestorer smr;
+
   // Block SIGALRM.
   sigset_t just_SIGALRM;
   sigemptyset(&just_SIGALRM);
   sigaddset(&just_SIGALRM, SIGALRM);
-  sigset_t original_set;
-  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, nullptr));
 
   // Raise SIGALRM.
   sigval_t sigval;
@@ -320,38 +401,75 @@
   ASSERT_EQ(0, errno);
   ASSERT_EQ(SIGALRM, info.si_signo);
   ASSERT_EQ(1, info.si_value.sival_int);
+}
 
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
+TEST(signal, sigwaitinfo64_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;
+  sigval.sival_int = 1;
+  ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
+
+  // Get pending SIGRTMIN.
+  siginfo_t info;
+  errno = 0;
+  ASSERT_EQ(SIGRTMIN, sigwaitinfo64(&just_SIGRTMIN, &info));
+  ASSERT_EQ(0, errno);
+  ASSERT_EQ(SIGRTMIN, info.si_signo);
+  ASSERT_EQ(1, info.si_value.sival_int);
 }
 
 TEST(signal, sigtimedwait) {
+  SignalMaskRestorer smr;
+
   // Block SIGALRM.
   sigset_t just_SIGALRM;
   sigemptyset(&just_SIGALRM);
   sigaddset(&just_SIGALRM, SIGALRM);
-  sigset_t original_set;
-  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
+  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.
   siginfo_t info;
-  struct timespec timeout;
-  timeout.tv_sec = 2;
-  timeout.tv_nsec = 0;
+  timespec timeout = { .tv_sec = 2, .tv_nsec = 0 };
   errno = 0;
   ASSERT_EQ(SIGALRM, sigtimedwait(&just_SIGALRM, &info, &timeout));
   ASSERT_EQ(0, errno);
+}
 
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
+TEST(signal, sigtimedwait64_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 SIGALRM.
+  sigval_t sigval = { .sival_int = 1 };
+  ASSERT_EQ(0, sigqueue(getpid(), SIGRTMIN, sigval));
+
+  // Get pending SIGALRM.
+  siginfo_t info;
+  timespec timeout = { .tv_sec = 2, .tv_nsec = 0 };
+  errno = 0;
+  ASSERT_EQ(SIGRTMIN, sigtimedwait64(&just_SIGRTMIN, &info, &timeout));
+  ASSERT_EQ(0, errno);
 }
 
 static int64_t NanoTime() {
-  struct timespec t;
-  t.tv_sec = t.tv_nsec = 0;
+  timespec t;
   clock_gettime(CLOCK_MONOTONIC, &t);
   return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
 }
@@ -367,9 +485,7 @@
   // Wait timeout.
   int64_t start_time = NanoTime();
   siginfo_t info;
-  struct timespec timeout;
-  timeout.tv_sec = 0;
-  timeout.tv_nsec = 1000000;
+  timespec timeout = { .tv_sec = 0, .tv_nsec = 1000000 };
   errno = 0;
   ASSERT_EQ(-1, sigtimedwait(&just_SIGALRM, &info, &timeout));
   ASSERT_EQ(EAGAIN, errno);
@@ -387,8 +503,7 @@
     "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
   static siginfo received;
 
-  struct sigaction handler;
-  memset(&handler, 0, sizeof(handler));
+  struct sigaction handler = {};
   handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
   handler.sa_flags = SA_SIGINFO;
 
@@ -411,18 +526,20 @@
                                             << sent.si_code << ", received " << received.si_code
                                             << error_msg;
 }
+#endif
 
-#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
 TEST(signal, sigset_size) {
   // The setjmp implementations for ARM, AArch64, x86, and x86_64 assume that sigset_t can fit in a
   // long. This is true because ARM and x86 have broken rt signal support, and AArch64 and x86_64
   // both have a SIGRTMAX defined as 64.
+#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
+#if defined(__BIONIC__)
   static_assert(sizeof(sigset_t) <= sizeof(long), "sigset_t doesn't fit in a long");
+#endif
+  static_assert(sizeof(sigset64_t)*8 >= 64, "sigset64_t too small for real-time signals");
+#endif
 }
 
-#endif
-#endif
-
 TEST(signal, sigignore_EINVAL) {
   errno = 0;
   ASSERT_EQ(-1, sigignore(99999));
@@ -464,33 +581,45 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
-TEST(signal, sighold_sigpause_sigrelse) {
-  static int sigalrm_handler_call_count;
-  auto sigalrm_handler = [](int) { sigalrm_handler_call_count++; };
-  ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler};
-  ScopedSignalMask mask;
+static void TestSigholdSigpauseSigrelse(int sig) {
+  static int signal_handler_call_count = 0;
+  ScopedSignalHandler ssh{sig, [](int) { signal_handler_call_count++; }};
+  SignalMaskRestorer mask_restorer;
   sigset_t set;
 
-  // sighold(SIGALRM) should add SIGALRM to the signal mask ...
-  ASSERT_EQ(0, sighold(SIGALRM));
+  // sighold(SIGALRM/SIGRTMIN) should add SIGALRM/SIGRTMIN to the signal mask ...
+  ASSERT_EQ(0, sighold(sig));
   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
-  EXPECT_TRUE(sigismember(&set, SIGALRM));
+  EXPECT_TRUE(sigismember(&set, sig));
 
-  // ... preventing our SIGALRM handler from running ...
-  raise(SIGALRM);
-  ASSERT_EQ(0, sigalrm_handler_call_count);
-  // ... until sigpause(SIGALRM) temporarily unblocks it.
-  ASSERT_EQ(-1, sigpause(SIGALRM));
+  // ... preventing our SIGALRM/SIGRTMIN handler from running ...
+  raise(sig);
+  ASSERT_EQ(0, signal_handler_call_count);
+  // ... until sigpause(SIGALRM/SIGRTMIN) temporarily unblocks it.
+  ASSERT_EQ(-1, sigpause(sig));
   ASSERT_EQ(EINTR, errno);
-  ASSERT_EQ(1, sigalrm_handler_call_count);
+  ASSERT_EQ(1, signal_handler_call_count);
 
-  // But sigpause(SIGALRM) shouldn't permanently unblock SIGALRM.
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
-  EXPECT_TRUE(sigismember(&set, SIGALRM));
+  if (sig >= SIGRTMIN && sizeof(void*) == 8) {
+    // But sigpause(SIGALRM/SIGRTMIN) shouldn't permanently unblock SIGALRM/SIGRTMIN.
+    ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
+    EXPECT_TRUE(sigismember(&set, sig));
 
-  ASSERT_EQ(0, sigrelse(SIGALRM));
-  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
-  EXPECT_FALSE(sigismember(&set, SIGALRM));
+    // Whereas sigrelse(SIGALRM/SIGRTMIN) should.
+    ASSERT_EQ(0, sigrelse(sig));
+    ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set));
+    EXPECT_FALSE(sigismember(&set, sig));
+  } else {
+    // sigismember won't work for SIGRTMIN on LP32.
+  }
+}
+
+TEST(signal, sighold_sigpause_sigrelse) {
+  TestSigholdSigpauseSigrelse(SIGALRM);
+}
+
+TEST(signal, sighold_sigpause_sigrelse_RT) {
+  TestSigholdSigpauseSigrelse(SIGRTMIN);
 }
 
 TEST(signal, sigset_EINVAL) {
@@ -499,23 +628,48 @@
   ASSERT_EQ(EINVAL, errno);
 }
 
-TEST(signal, sigset) {
-  auto sigalrm_handler = [](int) { };
-  ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler};
-  ScopedSignalMask mask;
+TEST(signal, sigset_RT) {
+  static int signal_handler_call_count = 0;
+  auto signal_handler = [](int) { signal_handler_call_count++; };
+  ScopedSignalHandler ssh{SIGRTMIN, signal_handler};
+  SignalMaskRestorer mask_restorer;
 
-  // block SIGALRM so the next sigset(SIGARLM) call will return SIG_HOLD
-  sigset_t sigalrm_set;
-  sigemptyset(&sigalrm_set);
-  sigaddset(&sigalrm_set, SIGALRM);
-  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &sigalrm_set, nullptr));
-
+  ASSERT_EQ(signal_handler, sigset(SIGRTMIN, SIG_HOLD));
+#if defined(__LP64__)
   sigset_t set;
-  ASSERT_EQ(SIG_HOLD, sigset(SIGALRM, sigalrm_handler));
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
+  ASSERT_TRUE(sigismember(&set, SIGRTMIN));
+#endif
+
+  ASSERT_EQ(SIG_HOLD, sigset(SIGRTMIN, signal_handler));
+  ASSERT_EQ(signal_handler, sigset(SIGRTMIN, signal_handler));
+  ASSERT_EQ(0, signal_handler_call_count);
+  raise(SIGRTMIN);
+  ASSERT_EQ(1, signal_handler_call_count);
+}
+
+TEST(signal, sigset) {
+  static int signal_handler_call_count = 0;
+  auto signal_handler = [](int) { signal_handler_call_count++; };
+  ScopedSignalHandler ssh{SIGALRM, signal_handler};
+  SignalMaskRestorer mask_restorer;
+
+  ASSERT_EQ(0, signal_handler_call_count);
+  raise(SIGALRM);
+  ASSERT_EQ(1, signal_handler_call_count);
+
+  // Block SIGALRM so the next sigset(SIGARLM) call will return SIG_HOLD.
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, SIGALRM);
+  ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &set, nullptr));
+
+  sigemptyset(&set);
+  ASSERT_EQ(SIG_HOLD, sigset(SIGALRM, signal_handler));
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
   EXPECT_FALSE(sigismember(&set, SIGALRM));
 
-  ASSERT_EQ(sigalrm_handler, sigset(SIGALRM, SIG_IGN));
+  ASSERT_EQ(signal_handler, sigset(SIGALRM, SIG_IGN));
   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, nullptr, &set));
   EXPECT_FALSE(sigismember(&set, SIGALRM));
 
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index d2e4ea1..84df16d 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -96,6 +96,25 @@
   ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
 }
 
+TEST(spawn, posix_spawnattr_setsigmask64_posix_spawnattr_getsigmask64) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  sigset64_t sigs;
+  ASSERT_EQ(0, posix_spawnattr_getsigmask64(&sa, &sigs));
+  ASSERT_FALSE(sigismember64(&sigs, SIGRTMIN));
+
+  sigset64_t just_SIGRTMIN;
+  sigemptyset64(&just_SIGRTMIN);
+  sigaddset64(&just_SIGRTMIN, SIGRTMIN);
+  ASSERT_EQ(0, posix_spawnattr_setsigmask64(&sa, &just_SIGRTMIN));
+
+  ASSERT_EQ(0, posix_spawnattr_getsigmask64(&sa, &sigs));
+  ASSERT_TRUE(sigismember64(&sigs, SIGRTMIN));
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
 TEST(spawn, posix_spawnattr_setsigdefault_posix_spawnattr_getsigdefault) {
   posix_spawnattr_t sa;
   ASSERT_EQ(0, posix_spawnattr_init(&sa));
@@ -115,6 +134,25 @@
   ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
 }
 
+TEST(spawn, posix_spawnattr_setsigdefault64_posix_spawnattr_getsigdefault64) {
+  posix_spawnattr_t sa;
+  ASSERT_EQ(0, posix_spawnattr_init(&sa));
+
+  sigset64_t sigs;
+  ASSERT_EQ(0, posix_spawnattr_getsigdefault64(&sa, &sigs));
+  ASSERT_FALSE(sigismember64(&sigs, SIGRTMIN));
+
+  sigset64_t just_SIGRTMIN;
+  sigemptyset64(&just_SIGRTMIN);
+  sigaddset64(&just_SIGRTMIN, SIGRTMIN);
+  ASSERT_EQ(0, posix_spawnattr_setsigdefault64(&sa, &just_SIGRTMIN));
+
+  ASSERT_EQ(0, posix_spawnattr_getsigdefault64(&sa, &sigs));
+  ASSERT_TRUE(sigismember64(&sigs, SIGRTMIN));
+
+  ASSERT_EQ(0, posix_spawnattr_destroy(&sa));
+}
+
 TEST(spawn, posix_spawnattr_setsschedparam_posix_spawnattr_getsschedparam) {
   posix_spawnattr_t sa;
   ASSERT_EQ(0, posix_spawnattr_init(&sa));
@@ -376,6 +414,7 @@
   sigset_t just_SIGALRM;
   sigemptyset(&just_SIGALRM);
   sigaddset(&just_SIGALRM, SIGALRM);
+
   ASSERT_EQ(0, posix_spawnattr_setsigdefault(&sa, &just_SIGALRM));
   ASSERT_EQ(0, posix_spawnattr_setflags(&sa, POSIX_SPAWN_SETSIGDEF));
 
@@ -393,15 +432,18 @@
   // child without first defaulting any caught signals (http://b/68707996).
   static pid_t parent = getpid();
 
+  setpgid(0, 0);
+
   pid_t pid = fork();
   ASSERT_NE(-1, pid);
 
   if (pid == 0) {
+    signal(SIGRTMIN, SIG_IGN);
     for (size_t i = 0; i < 1024; ++i) {
-      kill(0, SIGWINCH);
+      kill(0, SIGRTMIN);
       usleep(10);
     }
-    return;
+    _exit(99);
   }
 
   // We test both with and without attributes, because they used to be
@@ -417,11 +459,15 @@
 
   posix_spawnattr_t* attrs[] = { nullptr, &attr1, &attr2 };
 
-  ScopedSignalHandler ssh(SIGWINCH, [](int) { ASSERT_EQ(getpid(), parent); });
+  // We use a real-time signal because that's a tricky case for LP32
+  // because our sigset_t was too small.
+  ScopedSignalHandler ssh(SIGRTMIN, [](int) { ASSERT_EQ(getpid(), parent); });
 
   ExecTestHelper eth;
   eth.SetArgs({"true", nullptr});
   for (size_t i = 0; i < 128; ++i) {
     posix_spawn(nullptr, "true", nullptr, attrs[i % 3], eth.GetArgs(), nullptr);
   }
+
+  AssertChildExited(pid, 99);
 }
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index d0d9130..c1a51a8 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -1016,6 +1016,138 @@
   CheckScanf(swscanf, L"+,-/.", L"%[+--/]", 1, "+,-/");
 }
 
+template <typename T1, typename T2>
+static void CheckScanfM(int sscanf_fn(const T1*, const T1*, ...),
+                        const T1* input, const T1* fmt,
+                        int expected_count, const T2* expected_string) {
+  T2* result = nullptr;
+  ASSERT_EQ(expected_count, sscanf_fn(input, fmt, &result)) << fmt;
+  if (expected_string == nullptr) {
+    ASSERT_EQ(nullptr, result);
+  } else {
+    ASSERT_STREQ(expected_string, result) << fmt;
+  }
+  free(result);
+}
+
+TEST(STDIO_TEST, sscanf_mc) {
+  char* p1 = nullptr;
+  char* p2 = nullptr;
+  ASSERT_EQ(2, sscanf("hello", "%mc%mc", &p1, &p2));
+  ASSERT_EQ('h', *p1);
+  ASSERT_EQ('e', *p2);
+  free(p1);
+  free(p2);
+
+  p1 = nullptr;
+  ASSERT_EQ(1, sscanf("hello", "%4mc", &p1));
+  ASSERT_EQ('h', p1[0]);
+  ASSERT_EQ('e', p1[1]);
+  ASSERT_EQ('l', p1[2]);
+  ASSERT_EQ('l', p1[3]);
+  free(p1);
+
+  p1 = nullptr;
+  ASSERT_EQ(1, sscanf("hello world", "%30mc", &p1));
+  ASSERT_EQ('h', p1[0]);
+  ASSERT_EQ('e', p1[1]);
+  ASSERT_EQ('l', p1[2]);
+  ASSERT_EQ('l', p1[3]);
+  ASSERT_EQ('o', p1[4]);
+  free(p1);
+}
+
+
+TEST(STDIO_TEST, sscanf_mlc) {
+  // This is so useless that clang doesn't even believe it exists...
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+
+  wchar_t* p1 = nullptr;
+  wchar_t* p2 = nullptr;
+  ASSERT_EQ(2, sscanf("hello", "%mlc%mlc", &p1, &p2));
+  ASSERT_EQ(L'h', *p1);
+  ASSERT_EQ(L'e', *p2);
+  free(p1);
+  free(p2);
+
+  p1 = nullptr;
+  ASSERT_EQ(1, sscanf("hello", "%4mlc", &p1));
+  ASSERT_EQ(L'h', p1[0]);
+  ASSERT_EQ(L'e', p1[1]);
+  ASSERT_EQ(L'l', p1[2]);
+  ASSERT_EQ(L'l', p1[3]);
+  free(p1);
+
+  p1 = nullptr;
+  ASSERT_EQ(1, sscanf("hello world", "%30mlc", &p1));
+  ASSERT_EQ(L'h', p1[0]);
+  ASSERT_EQ(L'e', p1[1]);
+  ASSERT_EQ(L'l', p1[2]);
+  ASSERT_EQ(L'l', p1[3]);
+  ASSERT_EQ(L'o', p1[4]);
+  free(p1);
+#pragma clang diagnostic pop
+}
+
+
+TEST(STDIO_TEST, sscanf_ms) {
+  CheckScanfM(sscanf, "hello", "%ms", 1, "hello");
+  CheckScanfM(sscanf, "hello", "%4ms", 1, "hell");
+  CheckScanfM(sscanf, "hello world", "%30ms", 1, "hello");
+}
+
+TEST(STDIO_TEST, sscanf_mls) {
+  CheckScanfM(sscanf, "hello", "%mls", 1, L"hello");
+  CheckScanfM(sscanf, "hello", "%4mls", 1, L"hell");
+  CheckScanfM(sscanf, "hello world", "%30mls", 1, L"hello");
+}
+
+TEST(STDIO_TEST, sscanf_m_ccl) {
+  CheckScanfM(sscanf, "hello", "%m[a-z]", 1, "hello");
+  CheckScanfM(sscanf, "hello", "%4m[a-z]", 1, "hell");
+  CheckScanfM(sscanf, "hello world", "%30m[a-z]", 1, "hello");
+}
+
+TEST(STDIO_TEST, sscanf_ml_ccl) {
+  CheckScanfM(sscanf, "hello", "%ml[a-z]", 1, L"hello");
+  CheckScanfM(sscanf, "hello", "%4ml[a-z]", 1, L"hell");
+  CheckScanfM(sscanf, "hello world", "%30ml[a-z]", 1, L"hello");
+}
+
+TEST(STDIO_TEST, sscanf_ls) {
+  wchar_t w[32] = {};
+  ASSERT_EQ(1, sscanf("hello world", "%ls", w));
+  ASSERT_EQ(L"hello", std::wstring(w));
+}
+
+TEST(STDIO_TEST, sscanf_ls_suppress) {
+  ASSERT_EQ(0, sscanf("hello world", "%*ls %*ls"));
+}
+
+TEST(STDIO_TEST, sscanf_ls_n) {
+  setlocale(LC_ALL, "C.UTF-8");
+  wchar_t w[32] = {};
+  int pos = 0;
+  ASSERT_EQ(1, sscanf("\xc4\x80", "%ls%n", w, &pos));
+  ASSERT_EQ(static_cast<wchar_t>(256), w[0]);
+  ASSERT_EQ(2, pos);
+}
+
+TEST(STDIO_TEST, sscanf_ls_realloc) {
+  // This is so useless that clang doesn't even believe it exists...
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+  wchar_t* p1 = nullptr;
+  wchar_t* p2 = nullptr;
+  ASSERT_EQ(2, sscanf("1234567890123456789012345678901234567890 world", "%mls %mls", &p1, &p2));
+  ASSERT_EQ(L"1234567890123456789012345678901234567890", std::wstring(p1));
+  ASSERT_EQ(L"world", std::wstring(p2));
+#pragma clang diagnostic pop
+}
+
 // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202240
 TEST(STDIO_TEST, scanf_wscanf_EOF) {
   EXPECT_EQ(0, sscanf("b", "ab"));
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 93877f3..caa7a85 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -679,22 +679,51 @@
   if (std::numeric_limits<T>::is_signed) {
     // Minimum (such as -128).
     std::string min{std::to_string(std::numeric_limits<T>::min())};
+    end_p = nullptr;
+    errno = 0;
     ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
+    ASSERT_EQ(0, errno);
+    ASSERT_EQ('\0', *end_p);
     // Too negative (such as -129).
     min.back() = (min.back() + 1);
+    end_p = nullptr;
     errno = 0;
     ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
     ASSERT_EQ(ERANGE, errno);
+    ASSERT_EQ('\0', *end_p);
   }
 
   // Maximum (such as 127).
   std::string max{std::to_string(std::numeric_limits<T>::max())};
+  end_p = nullptr;
+  errno = 0;
   ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
+  ASSERT_EQ(0, errno);
+  ASSERT_EQ('\0', *end_p);
   // Too positive (such as 128).
   max.back() = (max.back() + 1);
+  end_p = nullptr;
   errno = 0;
   ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
   ASSERT_EQ(ERANGE, errno);
+  ASSERT_EQ('\0', *end_p);
+
+  // In case of overflow, strto* leaves us pointing past the end of the number,
+  // not at the digit that overflowed.
+  end_p = nullptr;
+  errno = 0;
+  ASSERT_EQ(std::numeric_limits<T>::max(),
+            fn("99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
+  ASSERT_EQ(ERANGE, errno);
+  ASSERT_STREQ("abc", end_p);
+  if (std::numeric_limits<T>::is_signed) {
+      end_p = nullptr;
+      errno = 0;
+      ASSERT_EQ(std::numeric_limits<T>::min(),
+                fn("-99999999999999999999999999999999999999999999999999999abc", &end_p, 0));
+      ASSERT_EQ(ERANGE, errno);
+      ASSERT_STREQ("abc", end_p);
+  }
 }
 
 TEST(stdlib, strtol_smoke) {
diff --git a/tests/sys_epoll_test.cpp b/tests/sys_epoll_test.cpp
index d1b411a..7233ccc 100644
--- a/tests/sys_epoll_test.cpp
+++ b/tests/sys_epoll_test.cpp
@@ -35,6 +35,11 @@
   // epoll_pwait without a sigset (which is equivalent to epoll_wait).
   ASSERT_EQ(0, epoll_pwait(epoll_fd, events, 1, 1, NULL));
 
+#if defined(__BIONIC__)
+  // epoll_pwait64 without a sigset (which is equivalent to epoll_wait).
+  ASSERT_EQ(0, epoll_pwait64(epoll_fd, events, 1, 1, NULL));
+#endif
+
   // epoll_pwait with a sigset.
   sigset_t ss;
   sigemptyset(&ss);
diff --git a/tests/sys_signalfd_test.cpp b/tests/sys_signalfd_test.cpp
new file mode 100644
index 0000000..67a72e0
--- /dev/null
+++ b/tests/sys_signalfd_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/signalfd.h>
+#include <unistd.h>
+
+#include <thread>
+
+#include "ScopedSignalHandler.h"
+
+static void TestSignalFd(int fd, int signal) {
+  ASSERT_NE(-1, fd) << strerror(errno);
+
+  ASSERT_EQ(0, raise(signal));
+
+  signalfd_siginfo sfd_si;
+  ASSERT_EQ(static_cast<ssize_t>(sizeof(sfd_si)), read(fd, &sfd_si, sizeof(sfd_si)));
+
+  ASSERT_EQ(signal, static_cast<int>(sfd_si.ssi_signo));
+
+  close(fd);
+}
+
+TEST(sys_signalfd, signalfd) {
+  SignalMaskRestorer smr;
+
+  sigset_t mask = {};
+  sigaddset(&mask, SIGALRM);
+  ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &mask, nullptr));
+
+  TestSignalFd(signalfd(-1, &mask, SFD_CLOEXEC), SIGALRM);
+}
+
+TEST(sys_signalfd, signalfd64) {
+#if defined(__BIONIC__)
+  SignalMaskRestorer smr;
+
+  sigset64_t mask = {};
+  sigaddset64(&mask, SIGRTMIN);
+  ASSERT_EQ(0, sigprocmask64(SIG_SETMASK, &mask, nullptr));
+
+  TestSignalFd(signalfd64(-1, &mask, SFD_CLOEXEC), SIGRTMIN);
+#endif
+}
diff --git a/tests/utils.h b/tests/utils.h
index a5783af..3f4218e 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -180,10 +180,10 @@
     return const_cast<char**>(env_.data());
   }
 
-  void SetArgs(const std::vector<const char*> args) {
+  void SetArgs(const std::vector<const char*>& args) {
     args_ = args;
   }
-  void SetEnv(const std::vector<const char*> env) {
+  void SetEnv(const std::vector<const char*>& env) {
     env_ = env;
   }
 
diff --git a/tools/versioner/src/Android.bp b/tools/versioner/src/Android.bp
index 9151646..4b237a9 100644
--- a/tools/versioner/src/Android.bp
+++ b/tools/versioner/src/Android.bp
@@ -35,6 +35,8 @@
 
         "-D__STDC_CONSTANT_MACROS",
         "-D__STDC_LIMIT_MACROS",
+
+        "-D_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS",
     ],
 
     target: {
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index 19c2f0d..d9cff17 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -102,21 +102,18 @@
       return true;
     }
 
-    DeclarationType declaration_type;
     std::string declaration_name = getDeclName(named_decl);
     bool is_extern = named_decl->getFormalLinkage() == ExternalLinkage;
     bool is_definition = false;
     bool no_guard = false;
 
     if (auto function_decl = dyn_cast<FunctionDecl>(decl)) {
-      declaration_type = DeclarationType::function;
       is_definition = function_decl->isThisDeclarationADefinition();
     } else if (auto var_decl = dyn_cast<VarDecl>(decl)) {
       if (!var_decl->isFileVarDecl()) {
         return true;
       }
 
-      declaration_type = DeclarationType::variable;
       switch (var_decl->isThisDeclarationADefinition()) {
         case VarDecl::DeclarationOnly:
           is_definition = false;
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index efb39bd..af0c067 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -496,7 +496,6 @@
 
 int main(int argc, char** argv) {
   std::string cwd = getWorkingDir() + "/";
-  bool default_args = true;
   std::string platform_dir;
   std::set<Arch> selected_architectures;
   std::set<int> selected_levels;
@@ -507,7 +506,6 @@
 
   int c;
   while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
-    default_args = false;
     switch (c) {
       case 'a': {
         char* end;